from roxiadebug import *
# -*- encoding: UTF-8 -*-

## Index

NAME, GROUP, PRIORITY, HOME, MOBILE, OFFICE, SPEED, EMAIL, MELODY, SNAPSHOT, CDATE, MDATE = range(12)
record = 'name', 'group', 'prority', 'home', 'mobile', 'office', 'speed', 'email', 'melody', 'snapshot', 'cdate', 'mdate'

class NamedListMetaClass(type):
	def __init__(cls, cls_name, bases, attrs):
		# cls -> cls_name을 갖는 class
		members = attrs['members']
		member_list = members.split()
		setattr(cls, '__slots__', ())
		def property_factory(index):
			def property_get(self):
				return self[index]
			def property_set(self, v):
				self[index] = v
			return property_get, property_set
		for i, member in enumerate(member_list):
			setattr(cls, member, property(*property_factory(i)))
		super(NamedListMetaClass, cls).__init__(cls_name, bases, attrs)
	def __call__(self, *args):
		# self: class
		instance = super(NamedListMetaClass, self).__call__(args)
		return instance

class PhoneItem(list):
	__metaclass__ = NamedListMetaClass
	members = 'name group prority home mobile office speed email melody snapshot cdate mdate'
	def __init__(self, args):
		if not args:
			list.__init__(self, [''] * len(self.members.split()))
		elif len(args) == 1:
			list.__init__(self, *args)
		else:
			list.__init__(self, args)
	def is_valid(self):
		return self[0] or self[1] or self[2] or self[3] or self[4]


class PhoneDB:
	def __init__(self):
		#try:
		#	self.load_db()
		#except:
		pass

	def new_item(self, item=None):
		if item: PhoneItem(item)
		return PhoneItem()

	def is_empty(self):
		return len(self.db) == 0

	def is_empty_for_call(self):
		for item in self.db:
			if item[HOME] or item[MOBILE]:
				return False
		return True

	def has_name(self, name):
		for item in self.db:
			if item[0] == name:
				return True
		return False
		'''
		name = name.lower()
		for item in self.db:
			if item[0].lower() == name:
				return True
		return False
		'''

	def has_number(self, number):
		if not number:
			return False

		for item in self.db:
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				return True
		return False

	def load_db(self):
		self.db = []
		for line in file('phonenumber.txt'):
			try:
				item = line[:-1].split('\t')
				#assert len(item) == len(record)
				self.db.append(PhoneItem(item))
			except:
				pass
		self.sort()

	# KA: [20080429] for group DB serarh
	def load_group_db(self, group_index):
		group_db = []
		for item in self.db:
			if item[GROUP] == str(group_index):
				group_db.append(item)
		self.db = []
		self.db = group_db
		self.sort()

	def load_group_db_new(self, group_index):
		group_db = []
		index = []
		i = 0
		for item in self.db:
			if item[GROUP] == str(group_index):
				group_db.append(item)
				index.append(i)
			i +=1
		self.group_db = group_db
		self.group_db_index = index

	def get_names_by_group_new(self):
		return [item[0] for item in self.group_db]

	def get_names_by_group(self):
		return [item[NAME] for item in self.db]
	# KA: [20080429] for group DB serarh
	
	def find(self, number):
		if not number:
			return -1
		for i, item in enumerate(self.db):
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				return i
		return -1

	def get_name(self, number):
		if not number:
			return ''
		if number == 'P':
			return _('Private number')
		elif number == 'O':
			return _('Not available')
		for item in self.db:
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				return item[0] or number
		# not found
		return number	

	def get_name_by_number(self, number):
		if not number:
			return ''
		for item in self.db:
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				return item[0] or number
		return ''

	def get_name_by_email(self, email, isreturn=True):
		if not email:
			return ''
		for item in self.db:
			if email == item[EMAIL]:
				return item[0] or email
		# not found
		if isreturn:
			return email
		else:
			return ''

	def get_name_by_fax(self, fax):
		if not fax:
			return ''
		for item in self.db:
			if fax == item[OFFICE]:
				return item[0] or fax
		# not found
		return fax


	# KA: [20080321] phonebook priority
	def get_priority_number(self, item):
		#NAME, GROUP, PRIORITY, HOME, MOBILE, OFFICE, EMAIL, SPEED, MELODY, SNAPSHOT = range(10)
		if not item[PRIORITY]:
			return 0, ''
		elif item[PRIORITY] == '0':
			return int(item[PRIORITY]), item[HOME]
		elif item[PRIORITY] == '1':
			return int(item[PRIORITY]), item[MOBILE]
		else:
			return int(item[PRIORITY]), item[OFFICE]
	# KA: [20080321] phonebook priority

	# KA: [20080428] groupdb count members
	def get_group_number_of_members(self, index):
		count = 0
		for item in self.db:
			if  index == int(item[GROUP]):
				count += 1
		return count
	# KA: [20080428] groupdb count members ==

	def set_group(self, oldIndex, newIndex=0):
		newDB = []
		for item in self.db:
			if int(item[GROUP]) == oldIndex:
				item[GROUP] = str(newIndex)
			newDB.append(item)

		self.db = newDB
		self.sort()
        ### Need to add SQL statement here
		self.save()

	# 영상 광고를 위해 임시로 만든 함수 / 아래 get_snapshot()함수와 뭉치는게 가능하면 뭉칠 것.
	def get_snapshot2(self, number):
		if not number:
			return ''
		for item in self.db:
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				snapshot = item[SNAPSHOT]
				if snapshot == '/usr/local/lgvp/photos/snapshot/no_photo.png':
					snapshot = 'images/no_photo.png'
	
				import os
				if not os.access(snapshot, os.R_OK):
					snapshot = 'images/no_photo.png'
				return snapshot

		
	def get_snapshot(self, number):
		if not number:
			return ''
		for item in self.db:
			if number in (item[HOME], item[MOBILE], item[OFFICE]):
				snapshot = item[SNAPSHOT]
				#return snapshot
	
				import os
				if not os.access(snapshot, os.R_OK):
					snapshot = 'photos/snapshot/no_photo.png'
				return snapshot
		# 새로운 값으로 저장
		#index = self.find(number)			
		#self.remove(index)
		#item = groupdb.new_item()
		#self.insert_item(item)

	# KA: [20080506] long key 처리 -speed dialing
	def get_speed_dial(self, speed):
		for item in self.db:
			if not item[SPEED]:
				continue
			if int(speed) == int(item[SPEED]):
				tmp, number = self.get_priority_number(item)
				return number
		return False
	# KA: [20080506] long key 처리 -speed dialing ==

	def set_snapshot(self, snapshot, index=-1):
		import status
		if index < 0:
			index = status.editing_phone_number_index
			if index < 0:
				#print 'WARNING::: set snapshot: phone index is negative'
				return
		item = self.db[index]
		self.update_snapshot(item, snapshot)
        ### Need to add SQL statement here
		self.save()

	def update_snapshot(self, item, snapshot):
		import utils, os, config
		old_snapshot = item[SNAPSHOT]
		if old_snapshot:
			utils.remove(old_snapshot)
		if not snapshot:
			item[SNAPSHOT] = ''
			return

		image_type = utils.image_type(snapshot)
		tmp_w, tmp_h = utils.get_img_size(snapshot)
		if tmp_w * tmp_h > 640 * 480:
			snapshot = '/usr/local/lgvp/images/image_big.png'
		snapshot = utils.changefile_gif(snapshot)
		sname = os.path.split(snapshot)[-1]
		new_snapshot_name = config.image_snapshot_dir + image_type + '_' + sname
		if os.path.exists(new_snapshot_name):
			i = 1
			while 1:
				new_snapshot_name = config.image_snapshot_dir + image_type + '_' + str(i) + sname
				if not os.path.exists(new_snapshot_name):
					break
				i += 1
		item[SNAPSHOT] = new_snapshot_name
		utils.image_resize(snapshot, new_snapshot_name)
		if not os.path.exists(new_snapshot_name):
			utils.file_copy(snapshot, new_snapshot_name)

	def set_melody(self, melody, index=-1):
		import status
		if index < 0:
			index = status.editing_phone_number_index
			if index < 0:
				#print 'WARNING::: set melody: phone index is negative'
				return
		item = self.db[index]
		item[MELODY] = melody
        ### Need to add SQL statement here
		self.save()

	def get_item(self, i):
		#assert 0 <= i < len(self.db)
		return self.db[i]

	def find_items_by_char(self, name, index_tables):
		index = []
		name = name.lower()
		for i, index in enumerate(index_tables):
			item = self.db[index]
			if name <= item[0].lower():
				if item[0].lower().startswith(name):
					index.append(i)

		return index


	def find_by_char(self, name, index_tables):
		name = name.lower()
		for i, index in enumerate(index_tables):
			item = self.db[index]
			if name <= item[0].lower():
				if item[0].lower().startswith(name):
					return i
				return -1
		return -1

	def find_by_name_near(self, name, index_tables=None):
		name = name.lower()
		if index_tables == None:
			for i, item in enumerate(self.db):
				if name <= item[0].lower():
					return i
		else:
			for i, index in enumerate(index_tables):
				item = self.db[index]
				if name <= item[0].lower():
					return i
		return -1

	# KA: [20080425] searh near name and number
	def find_by_all_near(self, key, index_tables=None):
		result =[]
		kor = unicode(key,'utf-8')	
		if key.isdigit():
			#self.get_name_by_number(key)
			for item in self.db:
				print 'ka....item[HOME]=%s item[MOBILE]=%s item[OFFICE]=%s'%(item[HOME], item[MOBILE], item[OFFICE])
				if key in item[HOME] or key in item[MOBILE]  or key in item[OFFICE]:
					print 'ka........its matched'
					result.append(item[NAME])
		else:
			key = key.lower()
			for item in self.db:
				if key in item[0].lower():
					result.append(item[NAME])
		print 'ka......result =', result
		return result
		
	# KA: [20080425] serarh near name and number ==	
	def find_by_name_near_for_call(self, name):
		name = name.lower()
		for i, item in enumerate(self.get_list_for_call()[1]):
			if name <= item[0].lower():
				return i
		return -1 # not valid

	def find_by_name_near_for_email(self, name):
		name = name.lower()
		for i, item in enumerate(self.get_list_for_email()[1]):
			if name <= item[0].lower():
				return i
		return -1# not valid

	def find_by_name_near_for_fax(self, name):
		name = name.lower()
		for i, item in enumerate(self.get_list_for_fax()[1]):
			if name <= item[0].lower():
				return i
		return -1 # not valid

	def get_item_by_number(self, number):
		index = self.find(number)
		if index < 0:
			return None
		return self.get_item(index)

	def find_by_item(self, item):
		return self.db.index(item)

	def count(self):
		return len(self.db)

	def insert_item(self, item):
		#print 'ka.............insert item=', item
		try:
			assert len(item) == 12
		except:
			try:
				import traceback
				traceback.print_exc()
			except:
				pass
			return
		self.db.append(item)
		#if item[SNAPSHOT]:
		#	snapshot = item[SNAPSHOT]
		#	item[SNAPSHOT] = ''
		#	self.update_snapshot(item, snapshot)
		self.sort()
        ### Need to add SQL statement here
		self.save()

	def sort(self):
		def sort_func(x, y):
			xname = x[0] or x[1] or x[2] or x[3]
			yname = y[0] or y[1] or y[2] or y[3]
			xname = xname.lower()
			yname = yname.lower()
			return cmp(xname, yname)
		self.db.sort(sort_func)

	def groupdb_sort(self):
		def sort_func(x, y):
			xname = x[0] or x[1] or x[2] or x[3]
			yname = y[0] or y[1] or y[2] or y[3]
			xname = xname.lower()
			yname = yname.lower()
			return cmp(xname, yname)
		self.group_db.sort(sort_func)
	
	def sort_cdate(self):
		def sort_func(x, y):
			xname = int(x[10])
			yname = int(y[10])
			return cmp(xname, yname)
		self.db.sort(sort_func)		

	def remove(self, index):
		#assert 0 <= index < len(self.db)
		item = self.db[index]
		#if item[SNAPSHOT]:
		#	self.update_snapshot(item, '')
		del self.db[index]
        ### Need to add SQL statement here
		self.save()

	# KA: [20080329] NEW phonebook
	def get_phonelist_by_text(self, keys=''): # key value should not be null
		#convert string to hex
		def toHex(s):
		             lst = []
		             for ch in s:
		                           hv = hex(ord(ch)).replace('0x', '')
		                           if len(hv) == 1:
		                                        hv = '0'+hv
		                           lst.append(hv)
		             return reduce(lambda x,y:x+y, lst)
		#convert hex repr to string


		def search(key, key_jamo, search_db, IsFirst=True):
			result=[]
			real_phonebook_index_list=[]

			key_total = key
			name_list = search_db

			for i in range(len(name_list)):
				#print 'ka....name = ', unicode(name_list[i],'utf-8').encode('euc-kr')
				# DB name을 읽고 ---( to unicode because Korean)
				#print 'ka...........name=', name_list[i]
				name = unicode(name_list[i],'utf-8')
				name_len = len(name)

				# name 자모 분리
				name_jamo=[]
				name_total=[]
				
				for j in range(name_len): #날라리  name / name_len = 3
					# KA: [20080518]
					if name[j].isdigit():
						#print 'ka.........................1'
						ch = (name[j], u'|', u'|') #한글처럼 강제로 형식을 맞게
						name_jamo.append(ch)
					else:
						#print 'ka.........................2'
						ch = (name[j], u'|', u'|') #한글처럼 강제로 형식을 맞게
						name_jamo.append(ch)

					name_total += ch

				#키값이 자음 검색인지 체크(key 전체가 자음이여만 자음검색 루틴으로)
				def JAMOCheck():
					keyLen = len(key_jamo)
					for i in range(keyLen):
						# 자음 검색
						if key_jamo[i][1] != u'|' or key_jamo[i][2] != u'|':
							return False
					return True

				if JAMOCheck():
					# name list에서도 자음만 축출
					new_name_jamo = []
					name_total=[]
					for k in range(name_len):
						ch = (name_jamo[k][0], u'|', u'|') 
						new_name_jamo.append(ch)
						name_total += ch					
					name_jamo = new_name_jamo

				#print 'ka............key_total=', key_total
				#print 'ka............name_total=', name_total
				
				# 2. total 문자 검색				
				key_total= ''.join(key_total)
				name_total= ''.join(name_total)

				key_total = key_total.strip()
				name_total = name_total.strip()
				
				#print 'ka.........key_total = ', toHex(key_total)
				#print 'ka.........name_total=', toHex(name_total)
				
				if name_total.find(key_total) >= 0:
					#print '-------success'
					item=name.encode('utf-8')
					result.append(item)
					#real_phonebook_index_list.append(i)
					#jun -------------------------------- 0723 (QA 2-43)
					if IsFirst==True:
						real_phonebook_index_list.append(i)
					else:
						try:
							real_phonebook_index_list.append(status.real_phonedb_index[i])
						except:
							#print '&&&& Phonebook db Error!!!'
							real_phonebook_index_list.append(i)									
					#jun -------------------------------- 0723 (QA 2-43)
				else:
					pass
					#print '--------fail'				
					
			return result, real_phonebook_index_list

		def search_number(key):
			result = []
			real_phonebook_index_list = []
			if key.isdigit():
				for i, item in enumerate(self.db):	
					if key in item[HOME] or key in item[MOBILE]  or key in item[OFFICE]:
						result.append(item[NAME])
						real_phonebook_index_list.append(i)
	
			return result, real_phonebook_index_list
	
###############################
		if not keys: #CHECKME : to remove this procedure!!!
			return range(phonedb.count()), phonedb.get_names()

		# 검색할 list를 줄여나간다.  최초에는 원래 phonebook DB
		result_db = self.get_names()

		# key 값을 1글자단위로 길이 측정 #'\xeb\xaa\xa8\xed\x86\xa0\xec\xb9\xb4\xeb\xa0\x88' 모토카레
		# 1. 입력받은 key값을 한글 형태로 나눈다. 
		uni_key = unicode(keys,'utf-8')
		key_jamo=[]
		key_total=[]		
		import status		
		for i in range(len(uni_key)):
			key = uni_key[i]
			if key.isdigit():
				ch = (key, u'|', u'|') #한글처럼 강제로 형식을 맞게
				key_jamo.append(ch)
				key_total += ch
			else:
				ch = (key, u'|', u'|') #한글처럼 강제로 형식을 맞게
				key_jamo.append(ch)
				key_total += ch
		
		result_db, status.real_phonedb_index = search(key_total, key_jamo, result_db, True)
		if not result_db:
			result_db, status.real_phonedb_index = search_number(keys)

		if not result_db:
			return None
		else:
			return result_db		
	# KA: [20080329] NEW phonebook ==

	def get_list_for_call(self):
		index_list = []
		name_list = []
		for i, item in enumerate(self.db):
			if item[NUMBER] or item[MOBILE]:
				name_list.append(item[NAME] or item[HOME] or item[MOBILE])
				index_list.append(i)
		return index_list, name_list

	def get_list_for_fax(self):
		index_list = []
		name_list = []
		for i, item in enumerate(self.db):
			if item[WORK]:
				name_list.append(item[NAME] or item[WORK])
				index_list.append(i)
		return index_list, name_list

	def get_list_for_email(self):
		index_list = []
		name_list = []
		for i, item in enumerate(self.db):
			if item[EMAIL]:
				name_list.append(item[NAME] or item[EMAIL])
				index_list.append(i)
		return index_list, name_list

	def get_sym_name(self, index):
		item = self.db[index]
		return item[NAME] or item[HOME] or item[MOBILE] or item[OFFICE]

	def get_names(self):
		return [item[NAME] or item[HOME] or item[MOBILE] or item[OFFICE] or item[EMAIL] for item in self.db]

	def save(self):
		fp = open('phonenumber.txt','w')
		for item in self.db:
			fp.write('\t'.join(item) + '\n')

	def reset(self):
#		for item in self.db:
#			if item[SNAPSHOT]:
#				self.update_snapshot(item, '')
		self.db = []
        ### Need to add SQL statement here
		self.save()

	def get_vip_list(self):
		vip_list = []
		index_list = []
		for i, item in enumerate(self.db):
			if item[VIP]:
				vip_list.append(item[0] or item[1] or item[2] or item[3])
				index_list.append(i)
		return index_list, vip_list

	def get_not_vip_list(self):
		not_vip_list = []
		index_list = []
		for i, item in enumerate(self.db):
			if not item[VIP]:
				not_vip_list.append(item[0] or item[1] or item[2] or item[3])
				index_list.append(i)
		return index_list, not_vip_list


	def delete_vip_list(self):
		for item in self.db:
			item[VIP] = ''
        ### Need to add SQL statement here
		self.save()

	def __del__(self):
		pass
		#print 'phonedb destroy'


phonedb = PhoneDB()
try:
	phonedb.load_db()
except:
	pass

if __name__ == '__main__':	
	phonedb.save()

