#!/usr/bin/python
# -*- coding: utf-8 -*-

import appuifw
import anydbm
import e32
import time
import os

trans=[{
		'%d.%m.%Y':'%d.%m.%Y',
		'%s: %.2f EUR':'%s: %.2f EUR',
		'-- Neu --':'-- Neu --',
		'Speichern':'Exportieren',
		'Löschen':'Löschen',
		'Optionen':'Optionen',
		'Alles löschen':'Alles löschen',
		'Wirklich löschen?':'Wirklich löschen?',
		'Wirklich alles löschen?':'Wirklich alles löschen?',
		'Gespeichert unter %s':'Gespeichert unter %s',
		'Was':'Was',
		'Wieviel':'Wieviel',
		'Kategorie':'Kategorie',
		'Wann':'Wann',
		'%s existiert nicht!':'%s existiert nicht!',
		'Sprache':'Sprache',
		'Deutsch':'Deutsch',
		'English':'English',
		'Verzeichnis':'Ordner',
},{
		'%d.%m.%Y':'%m %d, %Y',
		'%s: %.2f EUR':'%s: %.2f EUR',
		'-- Neu --':'-- New --',
		'Speichern':'Save',
		'Löschen':'Delete',
		'Optionen':'Options',
		'Alles löschen':'Delete All',
		'Wirklich löschen?':'Are you sure?',
		'Wirklich alles löschen?':'Are you sure?',
		'Gespeichert unter %s':'Saved as %s',
		'Was':'What',
		'Wieviel':'Amount',
		'Kategorie':'Category',
		'Wann':'Date',
		'%s existiert nicht!':'%s does not exist!',
		'Sprache':'Language',
		'Deutsch':'Deutsch',
		'English':'English',
		'Verzeichnis':'Folder',
}]
lang= 0
def _(string):
	return unicode(trans[lang][string],'utf-8')

class Expense:			
	def __init__(self,what, amount, category, when):
		self.what= what
		self.amount= amount
		self.category= category
		self.when= when
		
	def __repr__(self):
		return 'Expense(u"%s", %s, u"%s", %s)'%(
				self.what,
				repr(self.amount),
				self.category,
				repr(self.when))
	
	def getQIF(self):
		date= time.localtime(self.when)
		day=date[2]
		month=date[1]
		year=date[0]
		cat='\n'
		if self.category:
			cat='\nL'+self.category+'\n'
		
		result=u"""!Type:Bank
D%02d/%02d/%d
T-%#.2f
M%s%s^
"""%(month,day,year,self.amount,self.what,cat)
		return result
	
class Data:
	def __init__(self):
		self.dbpath=os.getcwd()+'db.txt'
		if not os.path.exists(self.dbpath):
			self.db={}
		else:
			self.db = self.load(open(self.dbpath, "r").read())

		if not u'data' in self.db:
			self.clean()
		else:
			self.data= self.db[u'data']

		if not u'options' in self.db:
			self.reset_options()
		else:
			self.options= self.db[u'options']
			self.flush_options()
			
	def flush_data(self):
		self.data.sort(lambda a,b: -cmp(a.when,b.when))
		self.db[u'data'] = self.data
	
	def flush_options(self):
		global lang
		lang= self.options['language']
		self.db[u'options'] = self.options
	
	def load(self,string):
		return(eval(string))
		
	def close(self):
		open(self.dbpath,'w').write(repr(self.db))
		
	def as_list(self):
		if not self.data:
			return []
		return [(unicode(time.strftime(_('%d.%m.%Y'),time.localtime(exp.when))),
			   _('%s: %.2f EUR')%(exp.what,exp.amount)) for exp in self.data]
	
	def get(self,index):
		return self.data[index]
		
	def remove(self,element):
		self.data.remove(element)
		self.flush_data()
		
	def save(self,exp):
		if not exp in self.data:
			self.data.append(exp)
		self.flush_data()
		
	def clean(self):
		self.data=[]
		self.flush_data()
		
	def getQIF(self):
		result=[u'!Account\nNBar\n^\n']
		for exp in self.data:
			result.append(exp.getQIF())
		return ''.join(result)

	def reset_options(self):
		self.options={'language':0, 'folder': u'c:/Data/Others/'}
		self.flush_options()

	def get_option(self, key):
		return self.options[key]
		
	def set_option(self, key, value):
		self.options[key]= value
		self.flush_options()

class ListView:
	def __init__(self, app):
		self.app=app
		
	def update(self):
		elements=self.app.data.as_list()
		elements.insert(0,(_('-- Neu --'),u''))
		self.list.set_list(elements)
	
	def activate(self):
		self.list= appuifw.Listbox([(u'',u'')], self.handle_select)
		self.update()
		appuifw.app.menu = [
			(_('Speichern'),self.handle_save),
			(_('Löschen'),self.handle_delete),
			(_('Optionen'),self.handle_options),
			(_('Alles löschen'),self.handle_delete_all),
		]
		appuifw.app.body = self.list
		
	def handle_select(self):
		view_edit= EditView(self.app)
		if self.list.current()==0:
			view_edit.show(Expense(u'',0.0,u'',time.time()))
		else:
			exp= self.app.data.get(self.list.current()-1)
			view_edit.show(exp)

	def handle_delete(self):
		if not self.list.current()==0:
			if appuifw.query(_('Wirklich löschen?'),'query'):
				exp= self.app.data.get(self.list.current()-1)
				self.app.data.remove(exp)
				self.update()
				
	def handle_delete_all(self):
		if appuifw.query(_('Wirklich alles löschen?'),'query'):
			self.app.data.clean()
			self.update()
				
	def handle_save(self):
		pathname=self.app.data.get_option('folder')
		now=time.localtime()
		filename='%d'%(now[0])+'%02d'%(now[1])+'%02d'%(now[2])+'.qif'
		file= open(pathname+filename,'w')
		file.write(self.app.data.getQIF().encode('utf-8'))
		file.close()
		appuifw.note(_('Gespeichert unter %s')%unicode(pathname+filename))
		
	def handle_options(self):
		view_options= OptionsView(self.app)
		view_options.show()
	
class EditView:
	def __init__(self, app):
		self.app= app
		
	def save(self,elem):
		self.exp.what= elem[0][2]
		self.exp.amount= elem[1][2]
		self.exp.category= elem[2][2]
		self.exp.when= elem[3][2]			
		self.app.data.save(self.exp)
		return True
		
	def show(self, exp):
		self.exp= exp
		data= [
			(_('Was'),'text',exp.what),
			(_('Wieviel'),'float',exp.amount),
			(_('Kategorie'),'text',exp.category),
			(_('Wann'),'date',exp.when),
		]
		flags = appuifw.FFormEditModeOnly
		form = appuifw.Form(data, flags)
		form.save_hook= self.save
		form.execute()
		self.app.view_list.activate()
		
class OptionsView:
	def __init__(self, app):
		self.app= app
	def save(self, elem):
		if not os.path.exists(elem[1][2]):
			appuifw.note(_('%s existiert nicht!')%(elem[1][2]),'error')
			return False
		self.app.data.set_option('language',int(elem[0][2][1]))
		self.app.data.set_option('folder',elem[1][2])
		return True
	def show(self):
		data= [
			(_('Sprache'),'combo',([_('Deutsch'),_('English')],self.app.data.get_option('language'))),
			(_('Verzeichnis'),'text',self.app.data.get_option('folder')),
		]
		flags = appuifw.FFormEditModeOnly
		form = appuifw.Form(data, flags)
		form.save_hook= self.save
		form.execute()
		self.app.view_list.activate()		
		
class CollectExpenses:
	def cb_exit(self):
		appuifw.app.exit_key_handler = self.orig_exit
		self.data.close()
		self.lock.signal()

	def __init__(self):
		self.data = Data()
		self.orig_exit = appuifw.app.exit_key_handler 
		appuifw.app.exit_key_handler=self.cb_exit
		self.view_list= ListView(self)
		self.view_list.activate()
		self.lock = e32.Ao_lock()
		self.lock.wait()
		appuifw.app.set_exit()

ce= CollectExpenses()

