import runtime
from richtext import RichText
from richtext import TAG_TEXT
from automata import Automata, Automata_ko, T9Automata, NumericAutomata, AddWordAutomata, LOWERCASE, IPAddrAutomata
from widget import CallbackWidget

class EditBase(CallbackWidget):
	AutomataChanged = 'automataChanged'

	background_color = 255, 255, 255, 255
	margin = 3

	def __init__(self, pos, size, bgcolor=None):
		CallbackWidget.__init__(self)

		# for test
		self.rounding = runtime.evas.rectangle(pos=(pos[0]-1, pos[1]-1), size=(size[0]+1, size[1]+1))
		self.rounding.color = 183, 183, 183, 255 #gray
		self.children.append(self.rounding)
		#import uiconfig
		#self.rounding = runtime.evas.image(uiconfig.entry_rounding_box,pos)
		#self.rounding.color = uiconfig.color_dark_gray
		#self.children.append(self.rounding)
		# for test ==

		self.background = runtime.evas.rectangle()
		self.background.pos = pos
		self.background.size = size
		if bgcolor == None:
			self.background.color = self.background_color
		else:
			self.background.color = bgcolor
		self.children.append(self.background)

		#textarea_pos = (pos[0] + self.margin, pos[1] + self.margin)
		textarea_pos = (pos[0] + self.margin, pos[1] + size[1]/2 - 8) # 8 is depend on font size
		#textarea_size = (size[0] - self.margin*2, size[1] - self.margin*2 - 4)
		textarea_size = (size[0] - self.margin*2 - 4, size[1] - self.margin*2 - 4) # first 4 is for right side area, second 4 is for bottom side area

		self.clip = runtime.evas.rectangle()
		self.clip.pos = textarea_pos
		self.clip.size = textarea_size
		self.clip.color = self.background_color
		self.children.append(self.clip)

		self._automata = NumericAutomata(self)
		self.email_mode = False
		
		# shchun: Korean version doesn't need euro alphabet.
		#		in order to prevent euc-kr encodings...
		#self.ascii_mode_case0 = False
		self.ascii_mode_case0 = True
		self.ascii_mode_case1 = False
		self.ascii_mode_case2 = False
		self.ascii_mode_case3 = False
		self.richtext = None
		
	def set_background_color(self, color):
		self.background.color = color
		self.clip.color = color

	def free(self):
		self.automata_changed_cb = None
		self.message_length_changed_cb = None

		self._automata.free()
		CallbackWidget.free(self)

	def show(self):
		CallbackWidget.show(self)
		self.cursor_show()

	def full(self):
		return self.richtext.full()

	def set_automata(self, name, case_mode=LOWERCASE):	#ÀÔ·Â ¹æ½ÄÀ» º¯È­½ÃÅ´
		self._automata.reset()
		self._automata.free()

		if name == 'multitap':			self._automata = Automata(self)
		elif name == 't9':				self._automata = T9Automata(self)
		elif name == '123':				self._automata = NumericAutomata(self)
		elif name == 'multitap_addword':	self._automata = AddWordAutomata(self)
		elif name == 'hangul':			self._automata = Automata_ko(self)
		# shchun : add ipaddr
		elif name == 'ip':				self._automata = IPAddrAutomata(self)
		else:
			# KA: [20080426] soft3 - symbol
			#pass
			self._automata = Automata(self)
			# KA: [20080426] soft3 - symbol ==
			#print 'Unknown automata name [%s]' % name
			#assert False

		self._automata.set_case_mode(case_mode)
		self._automata.ori_set_case_mode(case_mode)
		self.run_callback(self.AutomataChanged)

	def handle_key(self, key):
		ret = self._automata.handle_key(key)
		if ret: runtime.evas.render_now()
		return ret

	def func_key_handler(self, ctrl_keys):
		for k,c in ctrl_keys:
			if k == '\b':
				self.backspace(c)
				continue
			if k == 'Space':
				self.insert_unicode_text(unicode(' '))
				continue
			elif k == 'Left':
				self.cursor_backward()
				continue
			elif k == 'Right':
				self.cursor_forward()
				continue
			elif k == 'Up':
				self.cursor_up()
				continue
			elif k == 'Down':
				self.cursor_down()
				continue

	def backspace(self, count=1):
		self.richtext.backspace(count=count)
		self.cursor_show()

	def cursor_backward(self):
		self.richtext.cursor_backward()

	def cursor_forward(self):
		self.richtext.cursor_forward()

	def cursor_up(self):
		self.richtext.cursor_up()

	def cursor_down(self):
		self.richtext.cursor_down()

	def cursor_start(self):
		self.richtext.cursor_start()

	def cursor_end(self):
		self.richtext.cursor_end()

	def cursor_start(self):
		self.richtext.cursor_start()

	def cursor_end(self):
		self.richtext.cursor_end()

	def cursor_end_pos(self):
		return self.richtext.cursor_end_pos()

	def set_text(self, text):
		self._automata.reset()
		self.richtext.set_text(text)

	def insert_unicode_text(self, text, ul=False):
		self.richtext.insert_unicode_text(text, ul)

	def get_text(self):
		return self.richtext.get_text()

	def get_data(self):
		return self.richtext.get_data()

	def set_max(self, max):
		return self.richtext.set_max(max)

	def get_max(self):
		if self.richtext._max < 0:
			return 0
		return self.richtext._max

	def length(self):
		return self.richtext.length()

	def message_length(self):
		return self.richtext.message_length()

	def message_length_KT(self):
		return self.richtext.message_length_KT()

	# dirty hack for multitap automata
	def cursor_adj_ch(self):
		return self.richtext.cursor_adj_ch()

	def set_ul_shape(self, mode='line'):
		self.richtext.set_ul_shape(mode)

	def t9_helper_ul_reset(self):
		for o in self.richtext.objs:
			if o.tag() == TAG_TEXT:
				o.enable_ul(False)

	def t9_add_word(self, word):
		#assert self._automata.name() == 't9'
		self._automata.t9_add_word(word)

	def cursor_show(self):	
		if not self.hidden:
			self.richtext.cursor_show()

	def cursor_hide(self):
		self.richtext.cursor_hide()

	def start_editing(self):
		pass

	def end_editing(self):
		pass

	def is_start_of_sentance(self):
		return self.richtext.is_start_of_sentance()

	def need_scroll(self):
		return self._scroll

	def width(self):
		return self.background.geometry_get()[2]

	def height(self):
		return self.background.geometry_get()[3]

	def textarea_width(self):
		return self.clip.size[0]

	def textarea_height(self):
		return self.clip.size[1]


class RichTextEdit(EditBase):
	margin = 5

	def __init__(self, pos, size):
		EditBase.__init__(self, pos, size)

		self.richtext = RichText(pos=self.clip.pos, size=self.clip.size, edit=True)
		self.richtext.clip = self.clip
		self.children.append(self.richtext)

		self._vscroll_offset = 0
		self._vscroll_tag = None
		self._scroll = False

	def show(self):
		EditBase.show(self)
		self.check_scroll_mode()
		self.check_vscroll_offset()

	def insert_unicode_text(self, text, ul=False):
		EditBase.insert_unicode_text(self, text, ul)
		self.check_scroll_mode()
		self.check_vscroll_offset()

	def insert_image(self, filename, data = None):
		self._automata.reset()
		self.richtext.insert_image(filename, data)
		self.check_vscroll_offset()

	def insert_audio(self, filename, data = None):
		self._automata.reset()
		self.richtext.insert_audio(filename, data)
		self.check_vscroll_offset()

	def backspace(self, count=1):
		EditBase.backspace(self, count)
		self.check_vscroll_offset()

	def cursor_backward(self):
		EditBase.cursor_backward(self)
		self.check_vscroll_offset()

	def cursor_forward(self):
		EditBase.cursor_forward(self)
		self.check_vscroll_offset()

	def cursor_up(self):
		EditBase.cursor_up(self)
		self.check_vscroll_offset()

	def cursor_down(self):
		EditBase.cursor_down(self)
		self.check_vscroll_offset()

	def cursor_start(self):
		EditBase.cursor_start(self)
		self.check_vscroll_offset()

	def cursor_end(self):
		EditBase.cursor_end(self)
		self.check_vscroll_offset()

	def set_text(self, text):
		EditBase.set_text(self, text)
		self.check_vscroll_offset()

	def check_vscroll_offset(self):
		if self.hidden:
			return

		if self.richtext._format_delayed:
			return

		iy = self.richtext.y
		cx, cy1, ch = self.richtext.cursor_pos_height()
		cy2 = cy1 + ch
		y1 = self.clip.geometry[1]
		y2 = y1 + self.clip.geometry[3]

		need_move = False
		if cy1 < y1:
			self._vscroll_offset += (cy1-y1)
			need_move = True
		elif cy2 > y2:
			self._vscroll_offset += (cy2-y2)
			need_move = True

		if need_move:
			self.richtext.move(self.richtext.x, y1 - self._vscroll_offset)
			runtime.evas.render()

		self.richtext.cursor.queue_update()

	def check_scroll_mode(self):
		if self.richtext.get_height() > self.textarea_height():
			self._scroll = True
		else:
			self._scroll = False

	def start_editing(self):
		self.richtext._format_delayed = True

	def end_editing(self):
		self.richtext._format_delayed = False
		self.richtext.formatting()
		self.check_scroll_mode()
		self.check_vscroll_offset()

