Newer
Older
Import / projects / LGN-IP3870 / t / new / model.py
# -*- coding: utf-8 -*-

import baseui, ui, config, uiconfig, os
from basemodel import Stage, EntryStage, NotifyStage, GaugeStage, ListStage, SearchStage
import runtime
from setting import setting
import time, ntptime, status, utils
from roxiadebug import *
from mmiDebug import *
from runtime import mmiDebug as MD
from mms_net_stage import MMS_Downloading_Stage

import profile

from mmiSoundPath import SP_State, Device, SP_Context
from dectHandler import DectCallManager




dspg = runtime.dspg
ani_timer = None

menu_bg_style = 0

class MenuStage(Stage):
	name = 'MenuStage'
	
	def __init__(self):
		self.ui = ui.MenuUI()
		self.testkey = 0
		self.test1key = []

	def chk_test_key(self, key):
		# testkey : VideoSize - VideoProvacy - VideoSize
		if key == config.VideoSize:
			if self.testkey == 0:
				self.testkey = 1
			elif self.testkey == 2:
				self.testkey = 0
				import tstmod
				stage = tstmod.TestStage()
				runtime.manager.stack_stage(stage)
		elif key == config.VideoPrivacy:
			if self.testkey == 1:
				self.testkey = 2
			else:
				self.testkey = 0
		elif key in "0123456789*#":
			self.test1key.append(key)
			#if self.test1key == ['*','8','#','8','1','5']:
			if self.test1key == ['*','0','#','9','#','0','*']:
				self.test1key = []
				import tstmod
				stage = tstmod.To_debug_stage()
				runtime.manager.stack_stage(stage)
			elif self.test1key == ['*','1','2','3','5','8','*','1','2','3','4','7','8','9', '5', '6', '*']:
				self.test1key = []
				from menu import CheckPasswordStage
				stage = CheckPasswordStage(mode=2)
				runtime.manager.stack_stage(stage)
			# hcryoo:TBR
			elif self.test1key == ['*','#', '*', '#', '*', '#']: 
				self.test1key = []
				from menu import CheckPasswordStage
				stage = CheckPasswordStage(mode=7)
				runtime.manager.stack_stage(stage)
			elif self.test1key == ['*','1','4','7','3','5','9','*','1','2','3', '5', '8', '*']:
				self.test1key = []
				from menu import CheckPasswordStage
				stage = CheckPasswordStage(mode=1)
				runtime.manager.stack_stage(stage)
#MMW	// for wifi RF test
			elif self.test1key == ['*','#','#','*','#','#','*','#','#']:
				self.test1key = []
				import tstmod
				stage = tstmod.Wifi_RF_test_stage()
				runtime.manager.stack_stage(stage)
#end of MMW

	def handle_key(self, key):			
		global menu_bg_style
		if key == 'OK':
			if config.key_debug:
				print self.ui.focus, 'OK'
			if self.ui.focus == 0 and status.now_sending_email == True:
				runtime.manager.stack_stage(NotifyStage(_('Sending IP email')+'...',  uiconfig.baloon_email_icon))
				return False
			else:
				import menu
				if self.ui.focus == 2: #MMS
					msg = _('Sorry, we are preparing this service.')
					stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					
					#from eaHandler import EaHandler
					#runtime.eaHandler.startMMSC()
					
				elif self.ui.focus == 0:
					if (status.get_regstatus_mmi() == 0) and (config.myann_test_flag == False):
						msg = _('Please use after register to server')
						stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
						runtime.manager.stack_stage(stage)
						return True

					cur_profile=profile.profile.get_profile()
					if (cur_profile == 1 and not runtime.peek_lanlink()) or \
								(cur_profile == 2 and not runtime.peek_wifilink()):	
						msg = _('Check network connection.')
						stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
						runtime.manager.stack_stage(stage)
						return True						

					if runtime.myannapp:
						import myannapp
						if not runtime.myannapp.is_running():
							runtime.manager.stack_stage(myannapp.MyAnnStage(config.MY_SERVICE_HOME_URL))
							from eaHandler import EaHandler
							runtime.eaHandler.activateApplication_browser(destination=EaHandler.BROWSER)		
				else:
					'''
					dectInfos = runtime.dectCallManager.getDectInformationList()	
					serial = dectInfos[4]
					print 'dectInfo = ', serial, ' == ', len(serial)
					import struct
					serialNumber = []
					for char in range(len(serial)):
						serialChar = '%02x' % struct.unpack('B', serial[char])[0]
						serialNumber.append(serialChar)
					serialNumber = ''.join(serialNumber)
					print 'serialNumber = ', serialNumber					
					'''
					stage = menu.get_stage(self.ui.focus)
					roxia_trace('==>>>>> F1 key, focus=', self.ui.focus)
					menu_bg_style = self.ui.focus + 1
					runtime.manager.stack_stage(stage)
		elif key in (config.CLEAR, config.Red):
			if config.key_debug:
				print 'Back'
			runtime.manager.back_stage()
			menu_bg_style = 0 # default background image
			roxia_trace('==<<<<< F2 key')
		elif key in '12345678':
			import menu
			if key  == '3':	#MMS
				msg = _('Sorry, we are preparing this service.')
				stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
				runtime.manager.stack_stage(stage)
				#from eaHandler import EaHandler
				#runtime.eaHandler.startMMSC()	
			elif key == '1': # KT Service
				if (status.get_regstatus_mmi() == 0) and (config.myann_test_flag == False):
					msg = _('Please use after register to server')
					stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					return True

				cur_profile=profile.profile.get_profile()
				if (cur_profile == 1 and not runtime.peek_lanlink()) or \
							(cur_profile == 2 and not runtime.peek_wifilink()):	
					msg = _('Check network connection.')
					stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					return True
					
				if runtime.myannapp:
					import myannapp
					if not runtime.myannapp.is_running():
						runtime.manager.stack_stage(myannapp.MyAnnStage(config.MY_SERVICE_HOME_URL))
						from eaHandler import EaHandler
						runtime.eaHandler.activateApplication_browser(destination=EaHandler.BROWSER)
			else:
				selected_menu = int(key) - 1
				self.ui.focus = selected_menu
				stage = menu.get_stage(self.ui.focus)
				menu_bg_style = self.ui.focus + 1
				runtime.manager.stack_stage(stage)
		elif key in (config.Menu1, config.Menu4):
			return True
		else:
			self.chk_test_key(key)
			return self.ui.handle_key(key)
		return True

	def destroy(self):
		global menu_bg_style
		menu_bg_style = 0
		Stage.destroy(self)
		
# KA: [20080514] call menu
'''
def AudioCallVolumeStage():
	from phonesetting import AudioVolumeStage
	return AudioVolumeStage
'''

class HandsFreeNotifyStage(Stage):
	name = 'HandsFreeNotify'

# eicho modify 06.08.16
	def __init__(self, special_cid=False):
		icon = uiconfig.connected_icon
		message = _('To enable hands free mode on hook the receiver!')
		self.ui = baseui.NotifyUI(message, icon)
		self.ui.set_right(_('BACK'))
		os.system('fb0top 1')
# eicho add 06.08.16
		self.is_dirvideo_pstn = special_cid
		
	def handle_key(self, key):
		if key == config.OnHook:
# eicho add 06.08.16
			if self.is_dirvideo_pstn :	# a direct video call from IP
						# it is not real path. just for playing message after some key event.
				status.modem_audio_state_for_special_cid = status.SPK
				#dspg.set_state(dspg.ST_V_SPK_OFFHK)
			else:
# end.
				status.set_modem_audio_state(status.SPK)
				dspg.change_to_spk()
				
			# MMI p4: OnHook 을 했을 경우 dial 을 한다.
			# VoiceConnected 상태일 경우 무조건 back
			if status.phone_status == status.VoiceConnected:
				if config.dual_audio_volume:
					stage = runtime.manager.find_stage('audio volume')
					if stage:
						import phonesetting
						runtime.manager.back_stage('audio volume')
						runtime.manager.change_stage(phonesetting.AudioVolumeStage)
					else:
						runtime.manager.back_stage()
				else:
					runtime.manager.back_stage()
			else:
				stage = runtime.manager.find_stage('dial list detail') or runtime.manager.find_stage('dial list')
				if stage:
					index = stage.ui.get_focus()
					if index in (0, 1):
						stage.activate(index)
					else:
						runtime.manager.back_stage()
				else:
					runtime.manager.back_stage()

			return True
		elif key == config.Red:
			runtime.manager.back_stage()
			return True
		elif key == config.Menu2:
			# MMI p4: back을 했을 경우 dial 을 한다.
			# VoiceConnected 상태일 경우 무조건 back
			if status.phone_status == status.VoiceConnected:
				runtime.manager.back_stage()
			else:
				stage = runtime.manager.find_stage('dial list detail') or runtime.manager.find_stage('dial list')
				if stage:
					index = stage.ui.get_focus()
					if index in (0, 1):
						stage.activate(index)
					else:
						runtime.manager.back_stage()
				else:
					runtime.manager.back_stage()
			return True
		elif key == config.Green:
			return True
		return False


class ConnectedStage(Stage):
	name = 'connected'

	def __init__(self):
		roxia_event('ConnectedStage.__init__()')
		number = ''
		name = ''

		if status.caller_number:
			number = status.caller_number
		else:
			number = status.dial_number
		if config.stage_debug:
			print 'connected stage: dial', status.dial_number, 'caller:', status.caller_number
		if status.service_name:
			name = status.service_name
		else:
			if setting.phone_extension:
				if not status.dialed_by_user and number.startswith(setting.phone_extension):
					number = number[len(setting.phone_extension)+1:]

			from phonedb import phonedb
			name = phonedb.get_name(number)
			
		# 전화를 받은 경우에만 text width 조절
		if status.caller_number:
			name = utils.resize_text(name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]

		# eicho 06.02.14 it should be after status.caller_number.
		if status.dial_number != '  ' and status.dial_number != '':	# why this character is changed?
			#print 'dial_number is /', status.dial_number + '/'
			if name.isdigit():
				# Tde Prefix in PSTN
				if profile.ip_mode == 0 and setting.set_supplement_tde_prefix == 1:
					name = config.FAC_TELEFONICA_PREFIX_CODE + name
		if not name:
			name = _('Unknown')
			
		self.ui = ui.ConnectedUI(name)
		self.update_time_tag = 0

		self.connect_start_time = ntptime.ntime()
		status.call_time = self.connect_start_time

		status.received_call_time = utils.make_call_time()

		status.phone_status = status.VoiceConnected

		status.AnalogOption = True

		self.ui.show_cursor(True)

		dspg.change_to_conv()

	def update_number(self):
		roxia_event('ConnectedStage.update_number()')
		if runtime.manager.check_call_barring(status.dial_number):
			stage = CallBarringStage(status.dial_number)
			status.dial_number = ''
			runtime.manager.change_stage(stage, True)
			runtime.evas.render_now()
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
			dspg.dtmf_abort()
			time.sleep(1)
			if status.modem_audio_state == status.HS:
				dspg.set_state(dspg.ST_HS_OFFHK)
			if status.phone_status in (status.VoiceConnected,status.PPPConnected):
				pass
			status.phone_status = status.Disconnected ## sigh,,,,
			return False

		if status.caller_number:
			number = status.caller_number
		else:
			number = status.dial_number
		if config.stage_debug:
			print 'connected stage: dial', status.dial_number, 'caller:', status.caller_number
		if status.service_name:
			name = status.service_name
		else:
			if setting.phone_extension:
				if not status.dialed_by_user and number.startswith(setting.phone_extension):
					number = number[len(setting.phone_extension)+1:]
			#ka...CLIP name 2006.11.067
			if status.caller_CLIP_name:
				name = status.caller_CLIP_name
			else:
				from phonedb import phonedb
				name = phonedb.get_name(number)
		# 전화를 받은 경우에만 text width 조절
		if status.caller_number:
			name = utils.resize_text(name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]

		# eicho 06.02.14 it should be after status.caller_number.
		if status.dial_number != '  ' and status.dial_number != '':  # why this character is changed?
			if name.isdigit():
				# Tde Prefix in PSTN
				if profile.ip_mode == 0 and setting.set_supplement_tde_prefix == 1:
					name = config.FAC_TELEFONICA_PREFIX_CODE + name
		if not name:
			name = _('Unknown')
		self.ui.change_caller_number(name)
		return True

	def handle_key(self,  key):
		roxia_event('ConnectedStage.handle_key(), key=', key)

#TODO: outgoing call anmation
#pstn/ip 상태에 따라 ani처리를 다르게 해주어야 함.
#timer, remove timer, event 처리등 한꺼번에 수정되어야 함.

		if key == 'Up':
			roxia_event('ConnectedStage.handle_key(), press *Up*')
			# audio volume
			stage = AudioCallVolumeStage()
			runtime.manager.stack_stage(stage)
			if config.key_debug:
				print 'temporary volume up'
			# volume up

		elif key == 'Down':
			roxia_event('ConnectedStage.handle_key(), press *Down*')
			stage = AudioCallVolumeStage()
			runtime.manager.stack_stage(stage)
			if config.key_debug:
				print 'temporary volume down'

		elif key in '0123456789#*':
			roxia_event('ConnectedStage.handle_key(), press *number*')
			if status.dial_number:
				status.set_dial_number(status.dial_number + key)
				if not self.update_number():
					return
				runtime.evas.render_now()
			dspg.send_dtmf(key, True)
			if config.key_debug:
				print 'num input in connected stage: current dial number=', status.dial_number

		elif key == config.Menu1:
			roxia_event('ConnectedStage.handle_key(), press *Menu1*, Option')
			# eicho modify 06.10.16
			if status.dialed_TdESupplementary == True:
				# TdE supplementary service로 전화를 걸어 connected 가 된 경우,
				# LEFT MENU없으므로, 기능도 삭제.
				return True
			# eicho end.
			
			import options
			stage = options.OptionsAnalogStage
			runtime.manager.stack_stage(stage)

		elif key == config.Menu2:
			roxia_event('ConnectedStage.handle_key(), press *Menu2*')
			if status.audio_mute:
				roxia_event('ConnectedStage.handle_key(), audio_mute TRUE')
				status.toggle_audio_mute()
				self.ui.show() # update icon/label
				return
			if status.waiting:
				roxia_event('ConnectedStage.handle_key(), waiting TRUE')
				status.toggle_waiting()
				self.ui.show() # update icon/label
				return
			# Menu2 에 의한 End 기능 제거
			return True

		elif key == config.Red:
			roxia_event('ConnectedStage.handle_key(), press *Red*')
			#assert status.modem_audio_state != status.IDLE
			return False

		elif key == config.OnHook:
			roxia_event('ConnectedStage.handle_key(), press *OnHook*')
			#assert status.modem_audio_state != status.IDLE
			return False

		elif key == config.OffHook:
			roxia_event('ConnectedStage.handle_key(), press *OffHook*')
			#assert status.modem_audio_state != status.IDLE
			return False

		elif key == config.Green:
			roxia_event('ConnectedStage.handle_key(), press *Green*')
			#assert status.modem_audio_state != status.IDLE
			return False

		elif key == config.Video:
			roxia_event('ConnectedStage.handle_key(), press *Video*')
			if status.waiting:
				status.toggle_waiting()
				self.ui.show() # update icon/label
			if status.audio_mute:
				status.toggle_audio_mute()
				self.ui.show() # update icon/label
			if utils.check_videocall() and status.dial_number:
				if runtime.manager.check_call_barring(status.dial_number, videocall=True):
					stage = NotifyStage(_('Number blocked.')+'\n'+_('Video call impossible.'), uiconfig.baloon_terminated_icon, None, 3000)
					runtime.manager.stack_stage(stage)
					return True

				elif runtime.manager.check_limited_number(status.dial_number):
					stage = NotifyStage(_('Service not available'), uiconfig.baloon_terminated_icon, None, 3000)
					runtime.manager.stack_stage(stage)
					return True
				else:
					status.pstn_indirect_video = True
					stage = VideoCallRequestStage
					runtime.manager.stack_stage(stage)
			else:
				stage = VideoCallImpossibleStage
				runtime.manager.stack_stage(stage)
		else:
			return False
		return True

	def end_call_by_red(self):
		if status.modem_audio_state == status.SPK:
			runtime.manager.stop_call(IdleStage)
			status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
			return True
		else:
			return False
	def end_call_by_onhook(self):
		if status.modem_audio_state == status.HS:
			runtime.manager.stop_call(IdleStage)
			status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
			return True
		else:
			return False

	def update_time(self):
		return True

	def show(self):
		self.update_time_tag = utils.Timer(700, self.update_time)
		Stage.show(self)
		self.update_number()

	def hide(self):
		self.update_time_tag = 0
		Stage.hide(self)

	def destroy(self):
		# CHECK MERGE 08.30
		status.pstn_indirect_video = False
		self.update_time_tag = 0
		status.AnalogOption = False
		if not config.dual_audio_volume:
			setting.set_volume(setting.audio_volume)
		status.sending_dtmf = ''
		dspg.dtmf_abort()
		Stage.destroy(self)


from basemodel import Stage
class InUseByDectStage(Stage):
	name = 'InUseByDect'
	
	def __init__(self):
		import ui
		self.ui = ui.InUseByDectUI(False)

		runtime.mmiDebug.mmiTodo('그냥 tone stop을 하면 dect에 tone이 나가는 오류가 발생한다. --> 임시로 수정함.')
		currentDevices = runtime.SP_context.getCurrentDevice()
		for currentDevice in currentDevices:
			if currentDevice in [SP_State.DEVICE_HS, SP_State.DEVICE_SPK]:
				runtime.SP_context.startTonePlay(currentDevice, config.PLAY_BUSY_TONE)	
		
	def handle_key(self, key):
		if key == config.Red:
			MD.mmiTrace('InUseByDectStage : Red')

			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("InUseByDectStage : Red : Stop tone play and Stage clear.")
					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					status.dialed_by_user = False
					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

					if runtime.eaHandler.isAppInUse():
						runtime.manager.back_stage()						
						runtime.eaHandler.changeShow()
					else:
						runtime.manager.change_stage(IdleStage, True)
				else:
					status.dialed_by_user = False		
			else:
				runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
				runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

				if runtime.eaHandler.isAppInUse():
					runtime.manager.back_stage()						
					runtime.eaHandler.changeShow()
				else:
					runtime.manager.change_stage(IdleStage, True)
			return True

		elif key == config.OnHook:
			MD.mmiTrace('InUseByDectStage : OnHook')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("InUseByDectStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("InUseByDectStage : OnHook : Stage closed.")
					status.dialed_by_user = False
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

					if runtime.eaHandler.isAppInUse():
						runtime.manager.back_stage()						
						runtime.eaHandler.changeShow()
					else:
						runtime.manager.change_stage(IdleStage, True)
			return True

		elif key == config.OffHook:
			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)

					runtime.SP_context.handset.setTone(config.PLAY_BUSY_TONE)				
					runtime.SP_context.startTonePlay()								
			return True
			
		elif key == config.Green:
			MD.mmiTrace('InUseByDectStage : Green')

			dectStatus = runtime.dectCallManager.getDectStatus()
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
			if spkOffHook.next():
				if spkOffHook.next():
					runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
					runtime.SP_context.startTonePlay()								
				else:
					if spkOffHook.next():
						'''
						status.dial_number = ''
						status.dialed_by_user = False

						runtime.SP_context.stopTonePlay()

						runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
						runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

						if runtime.eaHandler.isAppInUse():
							runtime.manager.back_stage()						
							runtime.eaHandler.changeShow()
						else:
							runtime.manager.change_stage(IdleStage, True)
						'''
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
						runtime.SP_context.startTonePlay()			
			return True
			
		return True


class MissedIncomingCallStage(Stage):
	# Page 32
	name = 'missed_incomingcall'
	def __init__(self, vm_flag=False):
		self.vm_flag = vm_flag
		import calldb, time
		detail = calldb.get_detail('missed', 0)

		from phonedb import phonedb
		caller_name = phonedb.get_name(detail.number)
		#self.caller_name = utils.resize_text(caller_name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]
		
		if detail.video_time:
			# calling_time
			year, mon, day, hour, min, sec = time.localtime(detail.video_time)[:6]
			date = "%02d/%02d" % (mon, day)
		else:
			# calling_time
			year, mon, day, hour, min, sec = time.localtime(detail.time)[:6]
			date = "%02d/%02d" % (mon, day)
		if hour > 12:
			#call_time = "%02d:%02dPM" % ((hour-12), min)
			call_time = "%s%02d:%02d" % (_('PM'), (hour-12), min)
		elif hour == 12:
			#call_time = "%02d:%02dPM" % (hour, min)
			call_time = "%s%02d:%02d" % (_('PM'), hour, min)
		elif hour == 0:
			#call_time = "%02d:%02dAM" % ((hour+12), min)
			call_time = "%s%02d:%02d" % (_('AM'), (hour+12), min)
		else:
			#call_time = "%02d:%02dAM" % (hour, min)
			call_time = "%s%02d:%02d" % (_('AM'), hour, min)
		time = date + ' ' + call_time

		self.ui = ui.MissedIncomingCallUI(caller_name, time)
		#KA:[2008.11.11] QA9-18
		#status.received_name = None #ka...name 2006.10.24
		#status.caller_CLIP_name = ''
		#status.caller_number = ''
		#status.clear_current_call_status()


	def handle_key(self, key):
		if self.vm_flag:
			if key == config.Menu1 or key == 'OK':
				status.missed_call_count = 0
				import callhistory
				runtime.manager.change_stage(callhistory.CallHistoryStage('missed', True))				
			elif key in (config.Menu4, config.CLEAR, config.Red):
				status.missed_call_count = 0
				runtime.eaHandler.endCall()
			elif key in (config.OffHook, config.Green, config.Video) or key in '0123456789*#+':
				status.missed_call_count = 0				
				runtime.eaHandler.deactivateApplication(gotoIdle=True)
				return False
				#stage = NotifyStage(_('Please finish using feature(Life service, message, media player).'))
				#runtime.manager.stack_stage(stage)
			return True
		
		if key == config.Menu1 or key == 'OK':
			import callhistory
			runtime.manager.change_stage(callhistory.CallHistoryStage('missed'))
			status.missed_call_count = 0
			return True
		elif key in (config.Menu4, config.CLEAR, config.Red):
			status.missed_call_count = 0	
			runtime.manager.change_stage(IdleStage, True)					
			return True			
		elif key in '0123456789*#+':
			status.missed_call_count = 0
			runtime.mmedia.unload()			
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				spkOffHook.next()			
			runtime.manager.stack_stage(EnblockEditStage, True)
			runtime.manager.handle_key(True, key)			
			return True		
		elif key in (config.Green, config.Video, config.OffHook):
			status.missed_call_count = 0
			return False
		else:
			#status.missed_call_count = 0
			runtime.manager.change_stage(IdleStage, True)
			return True
			'''
		elif key == config.OffHook:
			status.missed_call_count = 0
			utils.print_hw_debug('OFF-HOOK')
			if status.save_callback_other:
				self.emergency_save_other()

			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
				elif SP_State.DEVICE_HSS1_TS1 in originalDevices:
					from dectHandler import DectCallManager
					dectStatus = runtime.dectCallManager.getDectStatus()
					if dectStatus == DectCallManager.IDLE:
						runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
					else:
						runtime.SP_context.handset.setTone(config.PLAY_BUSY_TONE)				
				else:
					runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
				runtime.SP_context.startTonePlay()		

				runtime.manager.handle_call_action(config.OffHook)
		elif key == config.OnHook:
			status.missed_call_count = 0
			return False
			'''
		return True

	#Roxia Begin cmlim 06.04.11
	def handle_msg_waiting(self):
		roxia_event('MissedIncomingCallStage.handle_msg_waiting()')
#		self.ui.set_msg_waiting(setting.msg_waiting)
	#Roxia End cmlim 06.04.11

	#Roxia Begin cmlim 06.04.13
	def handle_mwi_waiting(self):
		roxia_event('MissedIncomingCallStage.handle_mwi_waiting()')
#		self.ui.set_mwi_waiting(setting.msg_waiting)
	#Roxia End cmlim 06.04.13


class ServiceNotAvailableStage(Stage):
	name = 'ServiceNotAvailable'
	def __init__(self):
		utils.player.stop_message()
		from phonedb import phonedb
		message = _('Service not available.')+'\n'+_('Retry audio call')+phonedb.get_name(status.caller_number)+'.'
		message = utils.resize_text(message, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]
		icon=uiconfig.baloon_terminated_icon
		self.ui = ui.BaloonMessageUI(_('CALL'), _('EXIT'), '', icon, message)
		status.caller_number = ''
		status.clear_current_call_status()
		
	def handle_key(self, key):
		if key == config.Menu1:
			runtime.manager.start_call(status.caller_number)
			status.missed_call_count = 0
			return True
		elif key == config.Menu2:
			runtime.manager.change_stage(IdleStage, True)
			status.missed_call_count = 0
			return True
		elif key in (config.Green, config.Red):
			status.missed_call_count = 0
		return False


class CallTerminatedStage(Stage):
	name = 'CallTerminated'
	agenda_forbidden = True
	""" Page 4 """
	def __init__(self, name='', next_stage=None):
		status.videocall_byuser = False
		if not name:
			name = status.service_name
		status.critical_entered = True
		if not name:
			#ka...CLIP name 2006.11.06
			if status.caller_CLIP_name:
				name = status.caller_CLIP_name
			else:

				if status.caller_number:
					number = status.caller_number
				else:
					number = status.dial_number

				if number:
					if setting.phone_extension:
						if not status.dialed_by_user and number.startswith(setting.phone_extension):
							number = number[len(setting.phone_extension)+1:]

					from phonedb import phonedb
					name = phonedb.get_name(number)
				else:
					name = _('Unknown')
		if status.caller_number:
			name = utils.resize_text(name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]

		# eicho 06.02.14 it should be after status.caller_number.
		if status.dial_number != '  ' and status.dial_number != '':  # why this character is changed?
			if name.isdigit():
				if profile.ip_mode == 0 and setting.set_supplement_tde_prefix == 1:
					name = config.FAC_TELEFONICA_PREFIX_CODE + name
		# eicho add 06.10.16
		status.dialed_TdESupplementary = False
		
		self.ui = ui.TerminatedCallUI(name)

		def cb():
			self.timer = None
			if next_stage:
				runtime.manager.change_stage(next_stage)
			else:
				runtime.manager.back_stage()
		self.timer = utils.Timer(2000, cb)

	def destroy(self):
		self.timer = 0
		status.dialed_by_user = False
		Stage.destroy(self)


# eicho add for warning. 81 in NB 06.10.25
class NoResponseFromRemoteStage(NotifyStage):
	name = 'NoResponseFromRemote'
	def __init__(self):
		icon = uiconfig.video_call_connect_icon
		message = _('No response from Remote.')
		NotifyStage.__init__(self, message, icon, cb = None, duration=3000)

		
class VideoCallRequestStage(Stage):
	name = "VideoCallRequest"
	def __init__(self):
		import ppp, vdciapp
		runtime.manager.set_videocall_mode(status.VideoCallRequest)
		status.set_video_mode(status.VideoRequesting)
		self.to_connecting = False
		self.ui = ui.VideoCallRequestUI()
		self.timer = utils.Timer(config.timerT1,\
				self.wait_video_call_accept)
		def cb():
			runtime.evas.render_now()

			if profile.ip_mode == 0:
				dspg.send_dtmf( status.VideoRequestDtmf(), False )
			else:
				runtime.vdci_send_dtmf( status.VideoRequestDtmf() )
			# logging for snmp
			#runtime.log.log("Send DTMF '"+status.VideoRequestDtmf()+\
			#		"' for request video call" )
			return False
		runtime.evas.idle_add(cb)

	def wait_video_call_accept(self):
		self.timer = utils.Timer(config.timerT2,\
				self.wait_more_video_call_accept)
		return False

	def wait_more_video_call_accept(self):
		if profile.ip_mode == 0:
			dspg.send_dtmf( status.VideoRequestDtmf(), False )
		else:
			runtime.vdci_send_dtmf( status.VideoRequestDtmf() )

		# logging for snmp
		#runtime.log.log( "Send DTMF '" + status.VideoRequestDtmf() +\
		#		"' again for request video call" )
		self.timer = utils.Timer(config.timerT1,\
				self.wait_video_call_accept_fail)
		return False

	def wait_video_call_accept_fail(self):
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
# eicho add for warning. 81 in NB 06.10.25
		if profile.ip_mode == 0:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
				
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
			else:
				runtime.manager.back_stage()
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
		else:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
			else:
				runtime.manager.back_stage()
				runtime.manager.stack_stage(NoResponseFromRemoteStage)
		
		self.timer = None
		return False

	def handle_key(self, key):
		if key[0] == 'D' and status.CheckAnswerDtmf(key[1]):	# get accept signal
			# logging for snmp
			#runtime.log.log( "Recieved callee's answer DTMF '" +\
			#		key[1]  + "'")
			if runtime.manager:	# release voice call
				try:
					runtime.manager.stop_call_for_video_call()
				except:
					return False

			def cb_change_to_video_call_connected():
				self.to_connecting = True
				stage = VideoCallConnectingStage
				runtime.manager.change_stage(stage)
				return False
			runtime.evas.idle_add(cb_change_to_video_call_connected)
			return True
		return False

	def destroy(self):
		self.timer = 0
		if not self.to_connecting:
			runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		Stage.destroy(self)

# hcryoo : [20070419_1]
class TryVideoRequestLater(NotifyStage):
	name = 'TryVideoRequestLater'
	def __init__(self):
		icon = uiconfig.video_call_connect_icon
		message = _('Try 10 seconds later')
		NotifyStage.__init__(self, message, icon, None, 3000)

class VideoRequestDeclinedStage(NotifyStage):
	name = 'VideoRequestDeclined'
	def __init__(self):
		icon = uiconfig.baloon_terminated_icon
		NotifyStage.__init__(self, _('Video call request declined.'), icon, None, 3000)

class VideoRequestRejectedStage(NotifyStage):
	name = 'VideoRequestRejected'
	def __init__(self):
		icon = uiconfig.baloon_terminated_icon
		NotifyStage.__init__(self, _('Video call request declined.'), icon, None, 3000)

class VideoRequestCancelledStage(NotifyStage):
	name = 'VideoRequestCancelled'
	def __init__(self):
		icon = uiconfig.baloon_terminated_icon
		NotifyStage.__init__(self, _('Video call request cancelled.'), icon, None, 3000)

class VideoHeldRemotelyStage(Stage):
	name = 'VideoHeldRemotely'
	def __init__(self):
		roxia_event('VideoHeldRemotelyStage.__init__()')

		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		status.set_video_mode(status.VideoConnected)
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.phone_status = status.VoiceConnected
		self.exiting = False
		self.connected_name = status.display_caller_name(status.active_call_index)
		snapshot = None

		self.ui = ui.ConnectedUI(self.connected_name)

	def end_call(self,error=False):
		roxia_event('VideoHeldRemotelyStage.end_call(), error=', error)
		runtime.manager.stop_video_call(error)
		return False

	def end_call_by_red(self):
		roxia_event('VideoHeldRemotelyStage.end_call_by_red()')
		if status.modem_audio_state == status.SPK:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		else:
			return self.end_call_by_onhook()		
		return False

	def end_call_by_onhook(self):
		roxia_event('VideoHeldRemotelyStage.end_call_by_onhook()')
		if status.modem_audio_state == status.HS:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				status.set_modem_audio_state(status.IDLE)
				dspg.set_state(dspg.ST_IDLE)
			return True
		return False

	def activate_menu1(self):
		import options
		stage = options.OptionsVideoStage
		runtime.manager.stack_stage(stage)

	def activate_menu2(self):
		if status.audio_mute == 1:
			status.toggle_audio_mute()
			self.ui.set_right('')
			self.ui.draw_icons()

	def handle_key(self, key):
		roxia_event('VideoHeldRemotelyStage.handle_key(), key=', key)
		
		if key == config.Menu1:
			self.activate_menu1()
		elif key == config.Menu2:
			if config.key_debug:
				print 'Pressed Menu2'
			if status.audio_mute == 1:	
				status.toggle_audio_mute()
				self.ui.set_right('')
				self.ui.draw_icons()
			elif status.audio_mute == 0:
				roxia_event('status.audio_mute = 0')
				status.toggle_audio_mute()
				self.ui.set_right(_('ENABLE MIC'))
				self.ui.draw_icons()

		if key == 'Up':
			stage = AudioCallVolumeStage()
			runtime.manager.stack_stage(stage)

		elif key == 'Down':
			stage = AudioCallVolumeStage()
			runtime.manager.stack_stage(stage)

		elif key == config.Red:
			self.end_call_by_red()
			return True

		elif key == config.OnHook:
			return self.end_call_by_onhook()
			
		elif key == config.OffHook:
			status.set_modem_audio_state(status.HS)
			dspg.change_to_handset()
			self.ui.draw_icons()
		elif key == config.Green:
			return False
			
		return True

	def held_to_VideoCallconnected(self):
		runtime.manager.set_videocall_mode(status.VideoCallConnecting)
		self.exiting = False
		self.remoteID = status.dial_number
		#status.video_codec = status.AudioAndVideo
		status.save_current_call_status() # vpark-05.08.25
	
		#status.video_mode = status.VideoConnected
		status.video_mode = status.VideoIncoming
		# 06.07.06 Mr.Gun
		time.sleep(1)
		runtime.manager.change_stage(VideoCallConnectedStage,True)

	def show(self):
		Stage.show(self)

	def destroy(self):
		self.timer_avata = 0
		Stage.destroy(self)
		
class VideoCallRequestStageForCallTrading(Stage):
	name = "VideoCallRequestForCallTrading"
	def __init__(self):
		import ppp, vdciapp
		runtime.manager.set_videocall_mode(status.VideoCallRequest)
		status.set_video_mode(status.VideoRequesting)
		self.to_connecting = False
		self.ui = ui.VideoCallRequestUI()
		self.timer = utils.Timer(config.callTradingRequestTimerT1, self.wait_video_call_accept_fail)
		
		def cb():
			runtime.evas.render_now()

			if profile.ip_mode == 0:
				dspg.send_dtmf( status.VideoRequestDtmf(), False )
			else:
				runtime.vdci_send_mesg(code1=config.MESG_CALL_REINVITE)
			# logging for snmp
			#runtime.log.log('Send reinvite for request video call' )
			return False
		runtime.evas.idle_add(cb)

	def wait_video_call_accept_fail(self):
		roxia_event('CALL_TRADING : wait_video_call_accept_fail')
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP, code2=config.MESG_CANCEL)

		return False

	def video_call_declined(self):
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		# hcryoo : [20070527_2]
		status.set_video_mode(status.AudioConnected)
		# hcryoo : [20070527_2]==
		if profile.ip_mode == 0:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
				
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('connected')
			else:
				runtime.manager.back_stage()
		else:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('AudioCallConnected')
			else:
				runtime.manager.back_stage('AudioCallConnected')

		runtime.manager.stack_stage(VideoRequestDeclinedStage)
		
		self.timer = None

	# hcryoo : [20070509_2]
	def activate_cancel_key(self):
		# KA: [20070912] Temporary KT DEMO
		'''
		roxia_event('ACTIVATE CANCEL KEY')
		
		self.ui.set_right(_('CANCEL'))
		self.ui.show()
		'''
		pass
	# hcryoo : [20070509_2]==

	def video_call_cancelled(self):
		roxia_event('CALL_TRADING : video_call_cancelled')
		self.timer = None
		
		status.set_video_mode(status.AudioConnected)
		roxia_event('MODEL video_call_try_fail')
		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		
		if runtime.manager.stage.name == 'HandsFreeNotify':
			runtime.manager.back_stage('AudioCallConnected')
			runtime.manager.stack_stage(HandsFreeNotifyStage)
		else :
			runtime.manager.back_stage()
		import basemodel
		stage = VideoRequestCancelledStage
		runtime.manager.stack_stage(stage)

	def video_call_try_fail(self):
		roxia_event('CALL_TRADING : video_call_try_fail')
		self.timer = None
		
		status.set_video_mode(status.AudioConnected)
		roxia_event('MODEL video_call_try_fail')
		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		
		if runtime.manager.stage.name == 'HandsFreeNotify':
			runtime.manager.back_stage('AudioCallConnected')
			runtime.manager.stack_stage(HandsFreeNotifyStage)
		else :
			runtime.manager.back_stage()
		import basemodel
		stage = TryVideoRequestLater
		runtime.manager.stack_stage(stage)

	def end_call(self,error=False):
		if profile.ip_mode == 0:
			runtime.manager.set_videocall_mode(status.AudioDisconnected)
			status.video_mode = status.AudioDisconnected
			runtime.manager.stop_call(IdleStage)
			status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
		else:
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			status.set_modem_audio_state(status.IDLE)
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
			runtime.manager.stop_audio_call(False)

	def handle_key(self, key):
		if key == config.Red:
			roxia_trace('VideoCallRequestStageForCallTrading.handle_key(), press *Red*')

			self.end_call()
			time.sleep(2)
			return True
		# KA: [20070912] Temporary KT DEMO
		'''
		elif key == config.Menu2:
			roxia_trace('VideoCallRequestStageForCallTrading.handle_key(), press *MENU2*')
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP, code2=config.MESG_CANCEL)

			self.timer = None
			#self.timer1 = utils.Timer(config.timerT1, self.wait_video_call_accept_fail)
				
			return True
		'''
		return False

	def remove_timer_cancel(self):
		self.timer = 0

	def destroy(self):
		self.timer = None
		#self.timer1 = 0
		
		if not self.to_connecting:
			runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		Stage.destroy(self)
# hcryoo : [20070419_1]==

class VideoCallRequestedStage(Stage):
	name = "VideoCallRequested"
	def __init__(self):
		roxia_event('VideoCallRequestedStage.__init__()')
		import ppp, vdciapp
		self._videocall_connecting_tag = None
		self.to_connecting = False
		self.cancel_video = False

		runtime.manager.set_videocall_mode(status.VideoCallRequested)
		status.set_video_mode(status.VideoIncoming)

		self.ui = ui.VideoCallRequestedUI()
		self.timer = utils.Timer(config.timerT1,\
				self.video_call_request_ignore)

	def video_call_requested_overlaped(self):
		self.timer = utils.Timer(config.timerT1,\
				self.video_call_request_ignore)
		return False

	def video_call_request_ignore(self):
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		status.set_video_mode(status.AudioConnected) # vpark 11.19
		if profile.ip_mode == 0:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('connected')
			else:
				runtime.manager.back_stage()
		else:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('AudioCallConnected')
			else:
				runtime.manager.back_stage()
		self.timer = 0
		return False


# VideoCallRequestedStage handle_key
	def end_call(self,error=False):
		if profile.ip_mode == 0:
			runtime.manager.set_videocall_mode(status.AudioDisconnected)
			status.video_mode = status.AudioDisconnected
			runtime.manager.stop_call(IdleStage)
			status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
		else:
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			status.set_modem_audio_state(status.IDLE)
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
			runtime.manager.stop_audio_call(False)

	def handle_key(self, key):
		if key == config.Red:
			roxia_trace('VideoCallRequestedStage.handle_key(), press *Red*')
			if status.modem_audio_state == status.SPK:
				self.cancel_video = True
				self.end_call()
				time.sleep(2)
				return True
			else:
				return True

		elif key == config.OnHook:
			roxia_trace('VideoCallRequestedStage.handle_key(), press *OnHook*')
			self.cancel_video = True
			self.end_call()
			time.sleep(2)
			return True

		elif key == config.Video:
			if self._videocall_connecting_tag:
				return True

			if profile.ip_mode == 0:
				dspg.send_dtmf( status.VideoAnswerDtmf(), False )
			else:
				runtime.vdci_send_dtmf( status.VideoAnswerDtmf() )
			# logging for snmp
			#runtime.log.log( "Send DTMF '" +\
			#		status.VideoAnswerDtmf() + "' for accept video call")
			def cb():
				if dspg.sending_dtmf:
					return True
				self._videocall_connecting_tag = None
				if self.cancel_video == True:
					roxia_trace('VideoCallRequestedStage) accepted cancel video call')
					self.to_connecting = False
					return False

				self.to_connecting = True
				stage = VideoCallConnectingStage(True)
				runtime.manager.change_stage(stage)
				return False

			if status.FromDiffNetwork() or profile.ip_mode == 0:
				self._videocall_connecting_tag = utils.Timer(200,cb)	# from 100 to 200
		else:
			return False
		return True

	def destroy(self):
		self.timer = 0
		if not self.to_connecting:
			runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		Stage.destroy(self)


# hcryoo : [20070419_1]
class VideoCallRequestedStageForCallTrading(Stage):
	name = "VideoCallRequestedForCallTrading"
	def __init__(self):
		roxia_event('VideoCallRequestedStage.__init__()')
		import ppp, vdciapp
		self._videocall_connecting_tag = None
		self.to_connecting = False
		self.cancel_video = False

		runtime.manager.set_videocall_mode(status.VideoCallRequestedForCallTrading)
		status.set_video_mode(status.VideoIncoming)

		self.ui = ui.VideoCallRequestedUI()
		self.timer = utils.Timer(config.callTradingRequesetedTimerT1,\
				self.video_call_request_ignore)

	def video_call_requested_overlaped(self):
		self.timer = utils.Timer(config.timerT1,\
				self.video_call_request_ignore)
		return False

	def video_call_request_ignore(self):
		#runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_ACCEPT, mesg1='0', mesg2='0', mesg3='4')
		runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_ACCEPT, mesg3=config.MESG_INDIRECT_VIDEO_REJECT)
		self.timer = 0
		return False
		
	def video_call_declined(self):
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		status.set_video_mode(status.AudioConnected) # vpark 11.19
		if profile.ip_mode == 0:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('connected')
			else:
				runtime.manager.back_stage()
		else:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('AudioCallConnected')
			else:
				runtime.manager.back_stage('AudioCallConnected')

		runtime.manager.stack_stage(VideoRequestRejectedStage)

	def end_call(self,error=False):
		if profile.ip_mode == 0:
			runtime.manager.set_videocall_mode(status.AudioDisconnected)
			status.video_mode = status.AudioDisconnected
			runtime.manager.stop_call(IdleStage)
			status.set_modem_audio_state(status.IDLE)
			dspg.set_state(dspg.ST_IDLE)
		else:
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			status.set_modem_audio_state(status.IDLE)
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
			runtime.manager.stop_audio_call(False)

	def handle_key(self, key):
		if key == config.Red:
			roxia_trace('VideoCallRequestedStage.handle_key(), press *Red*')
			self.cancel_video = True
			self.end_call()
			time.sleep(2)
			return True
		elif key == config.OnHook:
			roxia_trace('VideoCallRequestedStage.handle_key(), press *OnHook*')
			self.cancel_video = True
			self.end_call()
			time.sleep(2)
			return True

		elif key == config.Video:
			if self._videocall_connecting_tag:
				return True

			if profile.ip_mode == 0:
				dspg.send_dtmf( status.VideoAnswerDtmf(), False )
			else:
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_ACCEPT, mesg3='0')
				
			# logging for snmp
			#runtime.log.log( "Send i|a for accept video call")
			'''
			def cb():
				if dspg.sending_dtmf:
					return True
				self._videocall_connecting_tag = None
				if self.cancel_video == True:
					roxia_trace('VideoCallRequestedStage) accepted cancel video call')
					self.to_connecting = False
					return False

				self.to_connecting = True
				stage = VideoCallConnectingStage(True)
				runtime.manager.change_stage(stage)
				return False

			if status.FromDiffNetwork() or profile.ip_mode == 0:
				self._videocall_connecting_tag = utils.Timer(200,cb)	# from 100 to 200
			'''
		elif key == config.Menu2:
			#runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_ACCEPT, mesg1='0', mesg2='0', mesg3='4')
			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_ACCEPT, mesg3=config.MESG_INDIRECT_VIDEO_REJECT)
			return True
		else:
			return False
		return True

	def invite_failed(self):
		self.dtmf_timer = 0
		self.timer = 0
		self.dtmf_tag = 0
		self.remove_cancel = 0

		status.set_video_mode(status.AudioConnected)
		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		if profile.ip_mode == 0:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('connected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('connected')
			else:
				runtime.manager.back_stage()
		else:
			if runtime.manager.stage.name == 'HandsFreeNotify':
				runtime.manager.back_stage('AudioCallConnected')
				runtime.manager.stack_stage(HandsFreeNotifyStage)
			elif runtime.manager.stage.name == 'VideoCallImpossible':
				runtime.manager.back_stage('AudioCallConnected')
			else:
				runtime.manager.back_stage()
		runtime.manager.stack_stage(VideoRequestCancelledStage)

	def destroy(self):
		self.timer = 0
		if not self.to_connecting:
			runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		Stage.destroy(self)

# hcryoo : [20070419_1]==

# eicho modify 06.04.12
# class VideoCallConnectingStage

class VideoCallConnectingStage(Stage):
	name = "VideoCallConnecting"
	def __init__(self,from_requested=False,snmp=False):
		utils.log_time('Start video call process',True)
		runtime.manager.set_videocall_mode(status.VideoCallConnecting)

		self.pstn_register_timer = None

		self.number = ''
		if status.caller_number:
			self.number = status.caller_number
		else:
			self.number = status.dial_number
		self.m_number = self.number

		if setting.phone_extension:
			if not status.dialed_by_user and self.number.startswith(setting.phone_extension):
				self.number = self.number[len(setting.phone_extension)+1:]

		from phonedb import phonedb
		self.call_name = phonedb.get_name(self.number)
		if not self.call_name:
			self.call_name = self.m_number

		self.call_name = utils.resize_text(self.call_name, uiconfig.progress_type2_text_width, uiconfig.progress_type2_font)[0]

		if not status.FromDiffNetwork() and status.special_cid:
			self.ui = ui.VideoCallConnectingUI(self.call_name, video_recv=True)
		else:
			self.ui = ui.VideoCallConnectingUI(self.call_name)

		self.progress_step = 0
		self.sended_invite = False
		self.invite_count = 0
		self.register_count = 0
		self.remoteID = None
		self.snmp = snmp
		self.exiting = False
		self.starting = False

		self.tag_invite_timer = 0
		self.tag_call_ppp = 0
		self.tag_run_vdciapp = 0
		self.tag_fail = 0
		self.tag_register = 0
		self.tag_request = 0
		self.tag_play_message = 0

		self.tag_progress = 0
		self.increse_counter = 0
		self.ui.set_max_duration(config.videocall_total_time)
		self.progress_value = 0
		self.curr_progress_status = status.VideoCallConnectingSTA
		status.videocall_connecting = status.VideoCallConnectingSTA
		self.update_progress()

		# eicho 06.04.11
		self.flag_indir_waitingcid= False
		# eicho 06.08.16
		status.modem_audio_state_for_special_cid = status.IDLE
		self.from_requested = from_requested

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		if status.FromDiffNetwork():
			if profile.ip_mode==0: # PSTN side
				if status.dial_number:
					self.start_ppp_call()
				else:	# PSTN side (IP to PSTN)
					if not status.special_cid: # indirect video call (IP to PSTN) first signal
						# eicho add tag - for handling key event.
						self.flag_indir_waitingcid = True
						dspg.dtmf_abort()
						status.modem_audio_state_for_special_cid = status.modem_audio_state
						dspg.set_state(dspg.ST_IDLE)
						status.modem_audio_state = status.IDLE
						self.special_timer = utils.Timer(config.indirect_special_cid_timeout, self.special_cid_timeout)
					else:
						self.flag_indir_waitingcid = False
						status.modem_audio_state = status.modem_audio_state_for_special_cid
						self.special_timer = utils.Timer(config.special_cid_ring_timeout, self.start_ppp_call_for_special_cid)
			else:			# IP side
				# add 06.06.12 as request by gun
				if not status.dial_number:
					time.sleep(config.TIME_WAIT_CALLEE_IP)
				# end.
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				status.release_channel()
				if status.dial_number:
					uriPolicy, number = utils.checkUrlPolicy(status.dial_number)
					runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
											code2=config.MESG_CALL_VIDEO, \
											mesg1=number, mesg9=uriPolicy)
				else:
					self.tag_play_message = utils.Timer(1000, self.connecting_play_message)

				self.ui.set_max_duration(config.indirect_total_timeout)
				self.special_timer = utils.Timer(config.indirect_total_timeout/3, self.update_progress_for_ip)

		elif status.special_cid: # direct video call (IP to PSTN)
			status.received_call_time = utils.make_call_time()
			utils.player.play(config.sms_ring, loop=False)
			self.special_timer = utils.Timer(config.special_cid_ring_timeout, self.start_ppp_call_for_special_cid)
		else: # PSTN indirect video call (PSTN to PSTN)
			self.start_ppp_call()

# eicho add 06.04.13
	def get_indirvideo_special_cid(self, from_requested=True):

		self.progress_step = 0
		self.sended_invite = False
		self.invite_count = 0
		self.register_count = 0
		self.remoteID = None
		self.exiting = False
		self.starting = False

		self.tag_invite_timer = 0
		self.tag_call_ppp = 0
		self.tag_run_vdciapp = 0
		self.tag_fail = 0
		self.tag_register = 0
		self.tag_request = 0
		self.tag_play_message = 0

		self.tag_progress = 0
		self.increse_counter = 0
		self.ui.set_max_duration(config.videocall_total_time)
		self.progress_value = 0
		self.curr_progress_status = status.VideoCallConnectingSTA
		status.videocall_connecting = status.VideoCallConnectingSTA
		self.update_progress()

		self.from_requested = from_requested

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		if status.FromDiffNetwork():
			if profile.ip_mode==0: # PSTN side
				if status.dial_number:
					self.start_ppp_call()
				else:	# PSTN side (IP to PSTN)
					if not status.special_cid: # indirect video call (IP to PSTN) first signal
						# eicho add tag - for handling key event.
						self.flag_indir_waitingcid = True
						dspg.dtmf_abort()
						status.modem_audio_state_for_special_cid = status.modem_audio_state
						dspg.set_state(dspg.ST_IDLE)
						status.modem_audio_state = status.IDLE
						self.special_timer = utils.Timer(config.indirect_special_cid_timeout, self.special_cid_timeout)
					else:
						self.flag_indir_waitingcid = False
						status.modem_audio_state = status.modem_audio_state_for_special_cid
						self.special_timer = utils.Timer(config.special_cid_ring_timeout, self.start_ppp_call_for_special_cid)
			else:			# IP side
				roxia_trace('VideoCallConnecting.. get_indirvideo_special_cid - 여기도? IP')
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				status.release_channel()
				if status.dial_number:
					uriPolicy, number = utils.checkUrlPolicy(status.dial_number)
					runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
											code2=config.MESG_CALL_VIDEO, \
											mesg1=number, mesg9=uriPolicy)
				else:
					self.tag_play_message = utils.Timer(1000, self.connecting_play_message)

				self.ui.set_max_duration(config.indirect_total_timeout)
				self.special_timer = utils.Timer(config.indirect_total_timeout/3, self.update_progress_for_ip)

# eicho end.

	def restore_dspg_state_by_modem_state(self,modem_state):
		if modem_state == status.HS:
			dspg.set_state(dspg.ST_HS_OFFHK)
		elif modem_state == status.SPK:
			dspg.set_state(dspg.ST_SPK_OFFHK)
		else:
			dspg.set_state(dspg.ST_IDLE)

	def special_cid_timeout(self):
		status.modem_audio_state = status.modem_audio_state_for_special_cid
		self.restore_dspg_state_by_modem_state(status.modem_audio_state)
		runtime.manager.stop_video_call(False)
		self.flag_indir_waitingcid = False

	def connecting_play_message(self):
		return utils.player.play_message(play_error='connecting')

	def start_ppp_call(self):
		if runtime.manager and self.from_requested:
			try:
				runtime.manager.stop_call_for_video_call()
			except:
				self.end_call(True)
				return True

		import ppp, vdciapp
		runtime.vdciapp = vdciapp.VDCIApp()
		runtime.ppp = ppp.PPP()
		self.starting = True
		if not self.snmp:	# for normal video call
			if self.from_requested: # from requested, wait T3 and then call ppp
				# callee
				self.tag_call_ppp = utils.Timer(config.timerT3, self.call_ppp)
				runtime.vdciapp.caller = False
				self.nas_number = config.sac2
				self.remoteID = status.dial_number
			else:	# from request, do not wait
				# caller
				self.tag_call_ppp = runtime.evas.idle_add(self.call_ppp)
				self.nas_number = status.ppp_call_number
				runtime.vdciapp.caller = True
				self.remoteID = status.dial_number
				if setting.phone_extension:
					self.remoteID = self.remoteID[len(setting.phone_extension)+1:]
				if self.remoteID.startswith(config.FAC_HIDE_ID_CODE):
					self.remoteID = self.remoteID[3:]
			self.tag_run_vdciapp = utils.Timer(config.timerRunVDCIApp,\
					self.run_vdciapp )
		else:	# for video call on snmp
			runtime.vdciapp.caller = False
			self.run_vdciapp()
			self.init_vdciapp()

	def start_ppp_call_for_special_cid(self):
		runtime.manager.kill_ringer()
		runtime.manager.stop_call_for_video_call()
		import ppp, vdciapp
		runtime.vdciapp = vdciapp.VDCIApp()
		runtime.ppp = ppp.PPP()
		self.starting = True
		runtime.vdciapp.caller = False
		self.nas_number = status.special_nas_number
		self.call_ppp()
		self.tag_run_vdciapp = utils.Timer(config.timerRunVDCIApp, self.run_vdciapp )

	def update_progress_for_ip(self):
		if self.tag_progress:
			self.tag_progress = 0
		max_value = config.indirect_total_timeout/3

		self.progress_value += max_value
		self.ui.set_value(self.progress_value)
		if self.progress_value == config.indirect_total_timeout:
			self.call_ppp_fail()
			return False

		runtime.evas.render_now()
		return True

	def update_progress(self):

		if self.tag_progress:
			self.tag_progress = 0
		max_value = config.pstn_videocall_time[self.progress_step]

		self.progress_value += max_value
		if self.progress_value >= config.videocall_total_time or \
				status.videocall_connecting == status.VideoCallConnectingJOIN:
			self.ui.set_value(config.videocall_total_time)
		else:
			self.ui.set_value(self.progress_value)
		self.increse_counter = 0
		runtime.evas.render_now()
		self.progress_step += 1

	def run_vdciapp(self):
		runtime.vdciapp.run_vdciapp()
		self.tag_run_vdciapp = 0
		return False
		
	def call_ppp(self):	# call ppp
		def disconnect_ppp():
			if status.videocall_mode == status.VideoCallConnected:
				if runtime.manager.stage.get_name() != 'VideoCallConnected':
					runtime.manager.back_stage('VideoCallConnected')
				runtime.manager.stage.end_call(True)
			elif status.videocall_mode == status.VideoCallConnecting:
				if runtime.manager.stage.get_name() != 'VideoCallConnecting':
					runtime.manager.back_stage('VideoCallConnecting')
				runtime.manager.stage.end_call(True)
		utils.log_time('Call PPP start')
		if not status.FromDiffNetwork() and status.special_cid:
			runtime.ppp.call_ppp(nas_number=self.nas_number, cb=self.init_vdciapp,
				fail_cb=disconnect_ppp,timeout_cb=self.call_ppp_fail,
				play_message=False)
		else:
			runtime.ppp.call_ppp(nas_number=self.nas_number, cb=self.init_vdciapp,
				fail_cb=disconnect_ppp,timeout_cb=self.call_ppp_fail,
				play_message=True)
		self.tag_fail = utils.Timer(config.timerPPPfail, self.call_ppp_fail)
		self.tag_call_ppp = 0
		return False

	def call_ppp_fail(self):	# function for PPP fail timer
		self.end_call(True)
		self.tag_fail = 0
		return False


	def handle_key(self, key):
		if key == config.Menu2:

			print '### END key during Receiving video call ###'
			print '### self.starting: ', self.starting
			print '### self.flag_indir_waitingcid: ', self.flag_indir_waitingcid
			
			if self.starting:	# PSTN only - starting PPP connecting... caller / calle OK
				self.end_call(False)
				return True
			else:
				if status.FromDiffNetwork() and self.flag_indir_waitingcid == True:
					if config.videocall_debug:
						print 'INDIR video call-  MENU event는 discard.'
					print '@@@@ No. 1'
					return True

				if status.modem_audio_state == status.SPK:
					if profile.ip_mode == 0:	# PSTN
						self.exiting = False
						print '@@@@ No. 2'
						self.end_call(False)
						# problem is still remained... ' SI port already open..  in modem monitor'

					else:
						# IP
						status.dtmf_overlap_mode = False # OK
						print '@@@@ No. 3'
						self.end_call()

				elif status.modem_audio_state == status.HS:
					if profile.ip_mode == 0:
						if status.videocall_mode < status.VideoCallConnecting:
							self.destroy_timers()
							dspg.set_state(dspg.ST_IDLE)
							if config.videocall_debug:
								print 'YOU PRESS MENU2 KEY before VideoCallConnecting... 1) '
							time.sleep(1)
							print '@@@@ No. 4'
							dspg.set_state(dspg.ST_HS_OFFHK)
						else:
							# OK
							print '@@@@ No. 5'
							self.end_call()


					else:
						status.dtmf_overlap_mode = False            # KEON-0412
						print '@@@@ No. 6'
						self.end_call(True)
						#runtime.manager.stop_call(EnblockEditStage)
						
				# eicho add 06.11.02 for w. 124		
				elif status.modem_audio_state == status.IDLE:
					print '@@@@ here ~~~ 7 @@@'
					if profile.ip_mode == 0:
						dspg.set_state(dspg.ST_HS_OFFHK)
						time.sleep(1)
						dspg.set_state(dspg.ST_IDLE)
					self.end_call(False)
					
				print '@@@@ here??? @@@'
				return True


		elif key == config.Red:
			if self.starting:	# PSTN only - starting PPP connecting... caller / calle OK
				#print 'RED KEY -during ppp '
				self.end_call(False)
			else:
				if status.FromDiffNetwork() and self.flag_indir_waitingcid == True:
					# INDIR video call인 경우 next signal을 기다리는 도중 ONHOOK event는 discard.
					#print '(eicho) DISCARD RED event during waiting next signal!!!!'
					return True
				'''
				if status.modem_audio_state == status.SPK:
					self.destroy_timers()	# caller OK

				elif status.modem_audio_state == status.HS:
					if profile.ip_mode !=0:	# IP-mode
						if status.dial_number:
							self.end_call(False) # caller OK
						else:
							self.destroy_timers()
							runtime.manager.stage.end_call() # IP callee OK
					else:	# PSTN
						self.end_call(False)
						return True
						
				# eicho add 06.11.02 for w. 124		
				elif status.modem_audio_state == status.IDLE:
					print '@@@@ here ~~~ 7 @@@'
					if profile.ip_mode == 0:
						#dspg.set_state(dspg.ST_HS_OFFHK)
						#time.sleep(1)
						dspg.set_state(dspg.ST_SPK_OFFHK)
					self.end_call(False)
				'''
				runtime.SP_context.goIdleState()

				if not status.dial_number:
					self.destroy_timers()
				self.end_call(False) 

		elif key == config.OnHook:
			roxia_event('VideoCallConnectingStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				currentDevices = hsOnHook.next()
				if not currentDevices:
					if not status.dial_number:
						self.destroy_timers()
					self.end_call(False) 
						
			'''
			print '@VideocallReceiving - ONHOOK'
			status.modem_audio_state_for_special_cid = status.SPK
			if self.starting:	# PSTN only - starting PPP connecting... caller / calle OK
				print 'MENU - from starting... in PSTN'
				status.set_modem_audio_state(status.IDLE)
				self.end_call(False)
				return True
			else:
				status.set_modem_audio_state(status.IDLE)
				if status.FromDiffNetwork() and self.flag_indir_waitingcid == True:
					self.end_call(False)
					return True

				self.destroy_timers()
			return False
			'''
		elif key == config.Green:
			roxia_event('VideoCallConnectingStage.handle_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						'''
						if not status.dial_number:
							self.destroy_timers()
						self.end_call(False) 
						'''
						pass
					else:
						spkOffHook.next()

			'''
			print '@VideocallReceiving - green!'
			if status.FromDiffNetwork() and self.flag_indir_waitingcid == True:
				if status.modem_audio_state == status.IDLE :
					# INDIR video call인 경우 next signal을 기다리는 도중 Green event는 discard.
					roxia_event('*Green on VideoConnecting...-> DISCARD*')
					#runtime.manager.stack_stage(HandsFreeNotifyStage)
					return True
			# eicho add 06.08.16
			elif not status.FromDiffNetwork() and status.special_cid:	#'Receiving videocall. Please wait'라고 출력되는 경우
				print 'status.modem_audio_state = ', status.modem_audio_state
				print 'status.modem_audio_state_for_special_cid=', status.modem_audio_state_for_special_cid
				if status.modem_audio_state_for_special_cid == status.HS:
					print '@VideocallReceiving (special cid)- GREEN'
					stage = HandsFreeNotifyStage(special_cid=True)
					#runtime.manager.stack_stage(HandsFreeNotifyStage)
					runtime.manager.stack_stage(stage)
				return True
				
			return False
			'''
		# eicho add 06.08.16 start
		elif key == config.OffHook:
			if not status.FromDiffNetwork() and status.special_cid:	#'Receiving videocall. Please wait'라고 출력되는 경우
				print '@VideocallReceiving (special cid)- INPUT OFFHOOK'
				status.modem_audio_state_for_special_cid = status.HS
				return True
			else :
				print '@VideocallReceiving - just OFFHOOK??'
				return False

		elif key == config.Video:
			print '@VideocallReceiving - Video green!'
			return False
		# 06.08.16 end.
		
		else:
			return False
		return True


	def destroy_timers(self):
		self.tag_call_ppp = 0
		self.tag_run_vdciapp = 0
		self.tag_fail = 0
		self.tag_register = 0
		self.tag_request = 0
		self.tag_progress = 0
		self.tag_start = 0
		self.tag_invite_timer = 0
		self.tag_play_message = 0
		self.special_timer = None
		self.flag_indir_waitingcid = False
		self.remove_register_timer()

	# eicho add 06.04.01
	def stop_connecting_msg_ip(self):
		try :
			if self.tag_play_message:
				print self.tag_play_message
		except:
			print 'VideoCallConnectingStage(IP) tag_play_message???'

		utils.player.stop_message()
	# eicho end


	def end_call(self,error=True):
		roxia_trace('VideoCallConnectingStage.end_call(), error=', error, 'exiting=', 'exiting=', self.exiting)
		self.destroy_timers()
		# eicho add 06.02.07
		if error != True:
			#eicho modify 06.04.01
			if profile.ip_mode == 0:	# PSTN mode
				roxia_trace('VideoCallConnectingStage(PSTN) calls  runtime.ppp.stop_connecting_msg()!!!')
				if runtime.ppp :
					runtime.ppp.stop_connecting_msg()
			else:
				roxia_trace('VideoCallConnectingStage(IP) calls  runtime.ppp.stop_connecting_msg()!!!')
				self.stop_connecting_msg_ip()
			# end. 06.04.01
		# eicho end.

# eicho add 06.08.16
		if not status.FromDiffNetwork() and status.special_cid:
			if status.modem_audio_state_for_special_cid == status.HS:
				#status.set_modem_audio_state(status.HS)
				#self.restore_dspg_state_by_modem_state(status.HS)
				dspg.set_state(dspg.ST_V_HS_OFFHK)
				print '@VideocallReceiving - change modem_audio_state to HS!'
			else:
				dspg.set_state(dspg.ST_V_SPK_OFFHK)
				print '@VideocallReceiving - change modem_audio_state to SPK!'
			print '@endcall() - status.modem_audio_state = ', status.modem_audio_state
# 06.08.16 end.
		if not self.exiting:
			self.exiting = True
			if runtime.vdciapp != None:
				if self.sended_invite and runtime.vdciapp.caller:
					pass
				if config.videocall_debug:
					print 'send hang up message to VDCI'
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				if profile.ip_mode == 0 and status.get_regstatus()== 1:
#Roxia Begin jhbang 06.03.16
						runtime.vdci_send_mesg(code1=config.MESG_REGISTERATION, \
						code2=config.MESG_UNREGISTER)
#Roxia End jhbang


			roxia_trace('call stop_video_call #1')
			runtime.manager.stop_video_call(error,self.snmp)
			'''
			# eicho 06.08.16 start
			if status.modem_audio_state_for_special_cid == status.HS:
				status.set_modem_audio_state(status.HS)
			else:
				status.set_modem_audio_state(status.IDLE)
			status.modem_audio_state_for_special_cid = status.IDLE
			'''

		return False
	def init_vdciapp(self):	# run vdciapp
		utils.log_time('Call PPP complete')
		if self.exiting:
			return False
		self.tag_fail = 0
		self.request_startup()
		return False

	def remove_register_timer(self):
		if self.pstn_register_timer:
			runtime.evas.timeout_remove(self.pstn_register_timer)
			self.pstn_register_timer = None

	def request_startup(self):
		status.videocall_dimension = setting.video_dimension
		self.remove_register_timer()
		self.pstn_register_timer = runtime.evas.timeout_add(config.timeoutRegister, self.end_call)

		# 1800과는 달리 2800에서는 snmp기능을 사용하지 않음.
		# 현 소스상의 snmp는 다운로드 process이며 이름만 동일함.
		runtime.vdci_startup(ip_profile=False) # pstn

	def request_invite(self):
		utils.log_time('Invite/WaitInvite Start')
		self.tag_fail = utils.Timer(config.timerT5, self.end_call)
		self.tag_register = None
		if runtime.vdciapp.caller:
			def cb():
				uriPolicy, number = utils.checkUrlPolicy(self.remoteID)
				runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
										code2=config.MESG_CALL_VIDEO, \
										mesg1=number, mesg9=uriPolicy)
				self.sended_invite = True
				return False
			self.tag_invite_timer = utils.Timer(config.timerDelayInvite, cb)
		self.tag_request = 0
		return False

	def stop_wait_invite_timer(self):
		self.fail = 0
		if self.tag_invite_timer:
			tag_invite_timer = 0

	def destroy(self):
		if self.tag_invite_timer:
			self.tag_invite_timer = 0
		self.destroy_timers()
		# eicho remove 06.02.07
		# utils.player.stop_message()
		status.videocall_connecting = status.VideoCallConnectingSTA

		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)
	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)

	def get_register_timer(self):
		roxia_trace('## model:get register timer: ', self.pstn_register_timer)
		return self.pstn_register_timer

class VideoTransfer(Stage):
	name = 'VideoTransfer'
	agenda_forbidden = True

	TRANSFER_TIMEOUT = 40*1000 # 40 second
	
	def __init__(self):
		MD.mmiTrace('B2H_Transfer.__init__()')

		self.onlyRingPath = False
		
	############ Transfer Utils ##################
	def setAudioRxMute(self):
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
						code2=config.MESG_SET_AUDIO_MUTE, \
						mesg1=1, mesg2=1)

	def setAudioRxUnmute(self):
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
						code2=config.MESG_SET_AUDIO_MUTE, \
						mesg1=0, mesg2=1)

	def setVideoMute(self):
		status.videocall_mute = 1 - status.videocall_mute
		runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
								code2=config.MESG_SET_VIDEO_MUTE, \
								mesg1=1)

	def setVideoUnmute(self):
		status.videocall_mute = 1 - status.videocall_mute
		runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
								code2=config.MESG_SET_VIDEO_MUTE, \
								mesg1=status.videocall_mute)

	def setVideoTxMute(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
					code2=config.MESG_SET_VIDEO_PATH, \
					mesg3=1, \
					mesg4=0)					

	############# B2H ####################
	def startB2h_VideoTransfer(self):
		self.modalMode = self.B2H_VIDEO_TRANSFER
		self.ui.soundPath.hide()
		# send message to dect
		runtime.dectCallManager.setDectStatus(DectCallManager.TRANSFER_RINGING)
		callerNumber = status.display_caller_number(status.active_call_index)
		callerName = status.display_caller_name(status.active_call_index)

		runtime.dectCallManager.start_B2H_Transfer(callerName, callerNumber)
		self.setAudioRxMute()
		self.setVideoMute()
		runtime.SP_context.SP_setMicDisable()
		runtime.dectCallManager.playTransferMoh()
		runtime.SP_context.startTonePlay(commonTone=config.PLAY_RINGBACK_TONE)	

		self.startTransferTimer()
		
	def startTransferTimer(self):
		def transferTimeout_callback():
			self.B2h_transferCancelledByBase()
			self.clearTransferTimer()
			self.hideSoftkeyAndMessageInB2H_Transfer()
			#self.ui.hideB2H_TransferMessage()
		self.transferTimer = utils.Timer(self.TRANSFER_TIMEOUT, transferTimeout_callback)
	
	def clearTransferTimer(self):
		self.modalMode = None
		self.transferTimer = None
		
	def transferCancelledByDectBusy(self):
		self.clearTransferTimer()
		self.ui.update_soundpath()	
		self.ui.soundPath.show()
	
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.stopTonePlay()

		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		self.setVideoUnmute()
		
		stage = NotifyStage(_('Dect in use.'), uiconfig.baloon_phonebook_icon)
		runtime.manager.change_stage(stage)

	def B2h_transferCancelledByBase(self):
		self.clearTransferTimer()

		self.ui.update_soundpath()	
		self.ui.soundPath.show()

		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.stopTonePlay()

		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		self.setVideoUnmute()

		devices = runtime.SP_context.getCurrentDevice()
		if runtime.SP_context.getCurrentStateName() in ['SP_HS_OffHook_SPK_OffHook','SP_HS_OffHook_SPK_OffHook_TS1_OffHook']:		
			runtime.SP_context.setPhysicalDevice()
			'''
			spkOnHook = runtime.SP_context.SPK_OnHook()
			if spkOnHook.next():
				spkOnHook.next()
			'''	

		from dectConfig import MessageCode
		runtime.dectCallManager.cancelCall(MessageCode.Normal.NORMAL_RELEASE)

	############# H2B ####################
	def transferCallbyDect(self, handsetNumber):
		MD.mmiTrace('transferCallbyDect()')

		self.modalMode = self.H2B_VIDEO_TRANSFER
		self.ui.soundPath.hide()
		self.ui.showH2B_TransferMessage(handsetNumber)
		self.startH2b_VideoTransfer()
		
	def startH2b_VideoTransfer(self):
		MD.mmiTrace('startH2b_VideoTransfer()')

		# receive message from dect
		runtime.SP_context.setBaseStatus(SP_Context.TRANSFER_RINGING)
		#self.callerNumber = status.display_caller_number(status.active_call_index)
		#self.callerName = status.display_caller_name(status.active_call_index)
		runtime.dectCallManager.closePcmChannel(1)
		runtime.dectCallManager.playTransferMoh()

		self.setAudioRxMute()
		self.setVideoMute()
		self.startTransferRinging()

	def transferDroppedByDect(self):
		MD.mmiTrace('transferDroppedByDect()')

		self.transferCancelledByDect()
		
	def transferCancelledByDect(self):
		MD.mmiTrace('transferCancelledByDect()')

		self.modalMode = None
		runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)

		runtime.dectCallManager.stopTransferMoh()
		self.stopTransferRinging()
		runtime.dectCallManager.openPcmChannel(1)
		self.setVideoUnmute()
		self.setAudioRxUnmute()
		
		self.hideSoftkeyAndMessageInB2H_Transfer()

		#self.ui.hideB2H_TransferMessage()

	def H2b_transferCancelledByBase(self):
		MD.mmiTrace('H2b_transferCancelledByBase()')

		runtime.dectCallManager.stopTransferMoh()
		self.stopTransferRinging()
		runtime.dectCallManager.openPcmChannel(1)
		runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)

		self.setAudioRxUnmute()
		self.setVideoUnmute()

		self.hideSoftkeyAndMessageInB2H_Transfer()

		from dectConfig import MessageCode
		runtime.dectCallManager.cancelCall(MessageCode.Normal.NORMAL_RELEASE)

	def startTransferRinging (self):
		MD.mmiTrace('startTransferRinging()')

		devices = runtime.SP_context.getCurrentDevice()
		
		if not SP_State.DEVICE_SPK in devices:	
			self.onlyRingPath = True
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						pass
					else:
						spkOffHook.next()	# SP_TS1_OffHook_SPK_OffHook
		runtime.SP_context.SP_playWav(SP_State.DEVICE_SPK, config.transferMOH2, True)
		
	def stopTransferRinging(self):
		MD.mmiTrace('stopTransferRinging()')

		runtime.SP_context.SP_stopWav()			

		if self.onlyRingPath:
			devices = runtime.SP_context.getCurrentDevice()

			self.onlyRingPath = False
			spkOnHook = runtime.SP_context.SPK_OnHook()
			if spkOnHook.next():
				if spkOnHook.next(): # SP_HS_OffHook_TS1_OffHook_SPK_OffHook
					pass
				else:
					spkOnHook.next()	# SP_SPK_OffHook
			
	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
			
		Stage.show(self)

	def destroy(self):
		self.transferTimer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

class VideoCallConnectedStage(Stage, VideoTransfer):
	name = "VideoCallConnected"

	B2H_VIDEO_TRANSFER = 1
	H2B_VIDEO_TRANSFER = 2
	
	def __init__(self, isAutoAnswerPossible=True):
		debugLogN("VideoCallConnectedStage.__init__() start")
	
		VideoTransfer.__init__(self)
		
		runtime.timer.hide()
		import videosetting#, setting
		videosetting.temp_fluency = 0
		self.softkey_timer = None

		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		status.set_video_mode(status.VideoConnected)
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.phone_status = status.VoiceConnected
		status.videocall_remote_mute = status.VideoMuteOff
		status.phone_status = status.VoiceConnected
		status.videocall_show_details = status.VideoDetailsShowMinimum

		os.system('fb0top 1')
		self.ui = ui.VideoCallConnectedUI()

		#self.connect_start_time = ntptime.ntime()
		#status.set_call_time()
		#status.video_call_time = self.connect_start_time
		self.exiting = False
		self.enable_resize = True
		self.tag_resize = None
		self.work_snapshot = False

		status.AnalogOption = True
		status.save_current_call_status()

		def cb():
			self.work_snapshot = True
			return False
		self.tag_snapshot = utils.Timer(config.timerSnapshot, cb)

		# Set data's for detail screen
		status.videocall_show_details = status.VideoDetailsShowMinimum

		self.tag_get_fps = None
		self.tag_get_fps_timer = None
		self.tag_hide_details = None
		self.softkey_timer = None
		self.volume_timer = None
		
		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		# hcryoo : [20070613_1] open remote quickly
		self.iframe_timer =  utils.Timer(2000, self.send_iframe)
		self.iframe_repeat = 3
		# hcryoo : [20070613_1] open remote quickly==

		self.keyBuffer = ''

		self.hangup_after_timer = None
		self.test_hangup_after_timer = None
		
		self.micMuteFlag = False
		self.interceptAutoAnswer = False
		
		if status.KT_CALL_TESTER:
			def test_auto_Hangup():
				self.handle_key(config.Red)
				self.test_hangup_after_timer = None

			self.test_hangup_after_timer = utils.Timer(status.KT_CALL_TESTER.getCallDuration()*1000, test_auto_Hangup)

		baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
		if setting.autoAnswer and baseCallStatus in [SP_Context.INCOMING_AUDIO, SP_Context.INCOMING_VIDEO] and not status.receiveCallInIncoming and isAutoAnswerPossible:
			def auto_Hangup():
				runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
										code2=config.MESG_AUTO_ANSWER_STOP)
				runtime.SP_context.SP_setMicEnable()
				#status.AutoAnswering = False
				runtime.manager.stage.handle_key(config.Red)

			currentAutoAnswerMessage = setting.autoAnswerMessage
			currentAutoAnswerFile = config.auto_answer_dir + currentAutoAnswerMessage

			runtime.SP_context.SP_setMicDisable()
			status.AutoAnswering = True
			runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
									code2=config.MESG_AUTO_ANSWER_PLAY, \
									mesg1=currentAutoAnswerFile, \
									mesg3=1)

			runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
									code2=config.MESG_SET_VIDEO_MUTE, \
									mesg1=1)
			self.showAutoAnswering()								
			self.hangup_after_timer = utils.Timer(10000, auto_Hangup)
		else:
			status.receiveCallInIncoming = False

			if status.call_status == status.IncomingCall:
				if setting.privacy_category != 3:
					status.videocall_mute = status.VideoMuteOn
					runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
											code2=config.MESG_SET_VIDEO_MUTE, \
											mesg1=1)
				else:
					status.videocall_mute = status.VideoMuteOff
					runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
											code2=config.MESG_SET_VIDEO_MUTE, \
											mesg1=0)

		self.modalMode = None
		self.b2h_VideoTransfer = None
		self.secondCallNumberTimer = None
		
		if status.pushVideoAd:
			self.ADTxMuteTimer = utils.Timer(200, self.setVideoTxMute)
		else:
			self.ADTxMuteTimer = None
		debugLogN("VideoCallConnectedStage.__init__() end")		
	def clearSecondCallNumberTimer(self):
		if self.secondCallNumberTimer:
			self.secondCallNumberTimer = None

	def showAutoAnswering(self):
		self.ui.showAutoAnswering()

	def autoHangupClose(self):
		runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
								code2=config.MESG_AUTO_ANSWER_STOP)
		runtime.SP_context.SP_setMicEnable()
		self.deleteAutoAnswering()
		self.hangup_after_timer = None
		if self.interceptAutoAnswer:
			status.AutoAnswering = False

	def deleteAutoAnswering(self):
		self.ui.deleteAutoAnswering()
		
	def removeCallTest_CB(self):
		if self.test_hangup_after_timer:
			self.test_hangup_after_timer = None
		
	def stopCallDuration(self):
		self.ui.stopCallDuration()
		
	def showVideoView(self):
		runtime.evas.use_transparency(True)
		self.ui.showLargeView()
		self.ui.showSmallView()

	def showThreeWayConference(self, firstCallNumber, secondCallNumber):
		self.ui.showThreeWayConference(firstCallNumber, secondCallNumber)

	def showCallWaiting(self, firstCallNumber, secondCallNumber, firstIsBusy=None):
		self.ui.showCallWaiting(firstCallNumber, secondCallNumber, firstIsBusy)

	def changeCallerInfo(self, callerNumber, changeMessage=False):
		self.ui.changeCallerInfo(callerNumber, changeMessage)

	def changeConnectedNumber(self):
		self.ui.changeConnectedNumber()

	def checkAndRemoveSecondCallNumber(self):
		if self.secondCallNumberTimer:
			self.ui.removeSecondCallNumber()
			self.secondCallNumberTimer = None
		
	def showSecondCallNumber(self, secondCallNumber):
		def removeSecondCallNumber_CB():
			self.ui.removeSecondCallNumber()
			self.ui.showInfoMessage()
			self.secondCallNumberTimer = None
		if self.secondCallNumberTimer:
			self.secondCallNumberTimer= None
		self.ui.showSecondCallNumber(secondCallNumber)
		self.secondCallNumberTimer = utils.Timer(uiconfig.SECOND_CALL_NUMBER_SHOW_TIME, removeSecondCallNumber_CB)

	def changeMessagePrefix(self):
		self.ui.changeMessagePrefix()

	def showSoftkey(self):
		self.ui.hideLargeView()
		self.ui.showLargeViewForMenu()
		self.ui.showSoftkey()

	def hideSoftkey(self):
		self.ui.hideLargeViewForMenu()
		self.ui.showLargeView()
		self.ui.hideSoftkey()

	def showSoftkeyAndMessageInB2H_Transfer(self):
		self.ui.hideLargeView()
		self.ui.showLargeViewForMenu()
		#self.ui.showB2H_TransferSoftkey()
		self.ui.showB2H_TransferMessage()

	def hideSoftkeyAndMessageInB2H_Transfer(self):
		self.ui.hideLargeViewForMenu()
		self.ui.hideB2H_TransferSoftkey()
		self.ui.showLargeView()
		self.ui.hideB2H_TransferMessage()
		
	def showSoftkeyAndMessageInH2B_Transfer(self):
		self.ui.hideLargeView()
		self.ui.showLargeViewForMenu()
		self.ui.showH2B_TransferSoftkey()
		self.ui.showH2B_TransferMessage()

	def hideSoftkeyAndMessageInH2B_Transfer(self):
		self.ui.hideLargeViewForMenu()
		self.ui.showLargeView()
		self.ui.hideH2B_TransferSoftkey()
		self.ui.hideH2B_TransferMessage()

	def stopCallAnimation(self):
		self.ui.stopCallAnimation()
		
	# hcryoo : [20070613_1] open remote quickly
	def send_iframe(self):
		runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
					code2=config.MESG_GET_INFO, mesg1=1)
		if self.iframe_repeat > 0:
			self.iframe_repeat = self.iframe_repeat - 1
			return True
		self.iframe_timer = None
		return False
	# hcryoo : [20070613_1] open remote quickly==
		
	def end_call(self,error=False):
		roxia_trace('VideoCallConnectedStage.end_call(), error=', error, 'exiting=', 'exiting=', self.exiting)
		#self.ui.stopCallDuration()
		runtime.evas.use_transparency(False)
		runtime.manager.stop_video_call(error)
		return False

	def end_call_by_red(self):
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)		
		self.ui.stopCallDuration()
		runtime.evas.use_transparency(False)
		return True
		
	def end_call_by_onhook(self):
		self.ui.stopCallDuration()
		runtime.evas.use_transparency(False)
		if status.modem_audio_state == status.HS:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				status.set_modem_audio_state(status.IDLE)
				dspg.set_state(dspg.ST_IDLE)
			return True
		return False

	def activate_menu1(self):
		import options
		stage = options.OptionsVideoStage
		runtime.manager.stack_stage(stage)

	def activate_menu2(self):
		if status.audio_mute == 1:	# if current status is video mute,
			status.toggle_audio_mute()
			self.ui.set_right('')
			self.ui.draw_icons()

	def handle_key(self, key):
		if not self.modalMode:
			result = self.handle_modaless_key(key)
		elif self.modalMode == self.B2H_VIDEO_TRANSFER:
			result = self.handle_B2H_TRANSFER_key(key)
		elif self.modalMode == self.H2B_VIDEO_TRANSFER:
			result = self.handle_H2B_TRANSFER_key(key)

		return result

	def handle_B2H_TRANSFER_key(self, key):
		if key == config.Menu4:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *Menu4*')
			self.B2h_transferCancelledByBase()
			self.hideSoftkeyAndMessageInB2H_Transfer()
			self.modalMode = None
			
		elif key == config.Green:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					#self.B2h_transferCancelledByBase()

					if spkOffHook.next():
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림
						runtime.SP_context.SP_setMicDisable()
						# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림==
				
		elif key == config.Red:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *Red*')
			self.B2h_transferCancelledByBase()

			self.ui.stopCallDuration()
			runtime.evas.use_transparency(False)
			runtime.SP_context.goIdleState()

			if self.hangup_after_timer:
				self.hangup_after_timer = None
			
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)		

		elif key == config.OnHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *OnHook*')
			#self.ui.hideSmallView()
			# [20080919_2]: hcryoo : [QA 7-18] group call 영상 통화 중 전환 후 on hook 하면 mute되는 오류 
			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				currentStateName = runtime.SP_context.getCurrentStateName()
				if currentStateName in ['SP_HS_OffHook_SPK_OffHook','SP_HS_OffHook_SPK_OffHook_TS1_OffHook']:		
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
				else:
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("VideoCallConnectedStage.handle_B2H_TRANSFER_key() : OnHook : Only Path Change.")
					runtime.SP_context.speaker.setTone(config.PLAY_RINGBACK_TONE)				
					runtime.SP_context.startTonePlay()	
				else:
					MD.mmiTrace("VideoCallConnectedStage.handle_B2H_TRANSFER_key() : OnHook : Stage closed.")

					self.B2h_transferCancelledByBase()

					self.ui.stopCallDuration()
					runtime.evas.use_transparency(False)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					
			return True
			# [20080919_2]: hcryoo : [QA 7-18] group call 영상 통화 중 전환 후 on hook 하면 mute되는 오류 ==

		elif key == config.OffHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *OffHook*')

			# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					runtime.SP_context.handset.setTone(config.PLAY_RINGBACK_TONE)				
					runtime.SP_context.startTonePlay()		
					runtime.SP_context.SP_setMicDisable()
			# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림==

		elif key == config.TS1_OFF_HOOK:
			MD.mmiTrace('VideoCallConnectedStage.handle_B2H_TRANSFER_key(), press *TS1_OFF_HOOK*')
			self.clearTransferTimer()
			self.hideSoftkeyAndMessageInB2H_Transfer()
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.stopTonePlay()

			runtime.SP_context.SP_setMicEnableAll()
			self.setAudioRxUnmute()
			self.setVideoUnmute()

			runtime.dectCallManager.openPcmChannel(1)

			runtime.dectCallManager.setDectStatus(DectCallManager.CONNECTED)
			runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
			
			self.modalMode = None
			
		return True

	def handle_H2B_TRANSFER_key(self, key):
		if key in [config.Green, config.Menu1]:
			MD.mmiTrace('handle_H2B_TRANSFER_key(), press *Green*')

			self.modalMode = None
			self.hideSoftkeyAndMessageInB2H_Transfer()
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			self.setAudioRxUnmute()
			self.setVideoUnmute()
			self.stopTransferRinging()
			
			runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				spkOffHook.next()

			runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
			runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
			runtime.dectCallManager.sendTransResult(0)
			self.modalMode = None

			self.ui.update_soundpath()	
			self.ui.soundPath.show()
			
		elif key == config.OffHook:
			MD.mmiTrace('handle_H2B_TRANSFER_key(), press *Off hook*')

			self.modalMode = None
			self.hideSoftkeyAndMessageInB2H_Transfer()
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			self.setAudioRxUnmute()
			self.setVideoUnmute()
			self.stopTransferRinging()

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()

			runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
			runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
			runtime.dectCallManager.sendTransResult(0)

			self.modalMode = None

			self.ui.update_soundpath()	
			self.ui.soundPath.show()
		else:
			MD.mmiTrace('handle_H2B_TRANSFER_key(), press *...*')

		return True
		
	def handle_modaless_key(self, key):
		def hide_softkey():
			self.softkey_timer = None
			self.hideSoftkey()
			return False
		def hide_volume():
			self.volume_timer = None
			self.hideVolume()
			return False

		if self.softkey_timer == None and key in (config.Menu1, config.Menu2, config.Menu3, config.Menu4, 'Left', 'Right'): ## status: hide
			if not status.showSoftkeyFlag:
				return
				
			self.volume_timer = None
			self.hideVolume()

			self.softkey_timer = utils.Timer(2000, hide_softkey)
			self.showSoftkey()
			return True

		if key in ('Up', 'Down'):
			if not status.showSoftkeyFlag:
				return

			baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
			if baseStatus == SP_Context.CONNECTED and dectStatus == DectCallManager.CONNECTED:
				return
				
			self.softkey_timer = None
			self.hideSoftkey()

			if self.volume_timer == None:
				self.volume_control(first_flag=True)
				self.volume_timer = utils.Timer(3000, hide_volume)
				return True
			else:
				del(self.volume_timer)
				self.volume_timer = None
				self.volume_timer = utils.Timer(3000, hide_volume)
				pass	

		if key in '0123456789#*':
			runtime.vdciapp.send_dtmf(key)
			# hcryoo : [20071120_4] : 부가 서비스 사용 중 눌러진 DTMF의 화면 표시
			status.video_number_on = True
			if len(self.keyBuffer) >= 20:
				self.keyBuffer = self.keyBuffer[1:] + key
				pressedNumber = _('Input number') + ' : ' + self.keyBuffer
				self.ui.write_number(pressedNumber)
			else:
				self.keyBuffer += key
				pressedNumber = _('Input number') + ' : ' + self.keyBuffer
				self.ui.write_number(pressedNumber)			
			# hcryoo : [20071120_4] : 부가 서비스 사용 중 눌러진 DTMF의 화면 표시==
		elif key == config.Menu1:
			if self.micMuteFlag:
				runtime.SP_context.SP_setMicEnable()
				self.micMuteFlag = False
				self.ui.changeSoftkeyFlag(False)
			else:
				runtime.SP_context.SP_setMicDisable()
				self.micMuteFlag = True
				self.ui.changeSoftkeyFlag(True)
		elif key == config.Menu2:
			if status.pushVideoAd:
				if self.ui.hideAD == False:
					self.ui.hideADView()
				else:
					self.ui.showADView()
			else:
				if self.micMuteFlag:
					runtime.SP_context.SP_setMicEnable()
					self.micMuteFlag = False
					self.ui.changeSoftkeyFlag(False)
				runtime.vdciapp.send_hook_flash()			
		
		elif key == config.HookFlash:
			if self.micMuteFlag:
				runtime.SP_context.SP_setMicEnable()
				self.micMuteFlag = False
				self.ui.changeSoftkeyFlag(False)
			runtime.vdciapp.send_hook_flash()

		elif key == config.Menu3:
			if status.pushVideoAd:
				return True
			#SWAP
			runtime.vdciapp.changeDimension()

		elif key== config.Menu4:	
			# phonebook
			from phonedb import phonedb
			if phonedb.is_empty():
				if self.ui.notify_timer:
					return
				self.ui.notify_msg_show(msg = _('Phonebook empty'))	
			else:
				runtime.manager.stack_stage(SearchStage(call_flag=True))
			
		#elif key == config.AudioMute:
		#	if status.audio_mute == 1:
		#		status.toggle_audio_mute()
		#		#self.ui.draw_icons()
		elif key == 'Up':
			# audio volume
			#stage = AudioCallVolumeStage()
			#runtime.manager.stack_stage(stage)
			# volume up
			self.volume_control(increase = True)
		elif key == 'Down':
			#stage = AudioCallVolumeStage()
			#runtime.manager.stack_stage(stage)
			# volume down
			self.volume_control(increase = False)

		elif key == config.Camera: # snapshot(camera key) pressed
			if status.pushVideoAd:
				return True
			if self.ui.notify_timer:
				return
			if status.videocall_remote_mute == status.VideoMuteOn:
				self.ui.notify_msg_show(msg = _('Remote capture not available'))
			elif not utils.check_free_storage():
				self.ui.notify_msg_show(msg = _('Memory full..'))
			elif config.snap_shot_max <= utils.get_file_count(\
						config.image_taken_dir):
				self.ui.notify_msg_show(msg = _('Memory full..'))
			else:
				runtime.vdciapp.send_mesg(code1=config.MESG_GET_SNAPSHOT, \
								mesg1='/tmp/cap.yuv420')

		elif key == config.VideoSize:
			if not self.enable_resize or self.tag_resize:
				return True
			self.enable_resize = False
			runtime.vdciapp.change_dimension()
			time.sleep(0.2)
			
			if self.ui:
				self.ui.draw_icons()
			def cb():
				self.enable_resize = True
				self.tag_resize = None
				return False
			self.tag_resize = utils.Timer(config.timerResize, cb)

			self.init_softkey()

		elif key == config.VideoMute:
			if status.pushVideoAd:
				return True
			status.videocall_mute = 1 - status.videocall_mute
			runtime.vdci_send_mesg(code1=config.MESG_SET_PARAMS, \
									code2=config.MESG_SET_VIDEO_MUTE, \
									mesg1=status.videocall_mute)
			#runtime.vdciapp.set_screen_clip()
			#self.ui.draw_icons()

		elif key == config.Video:
			if status.pushVideoAd:
				return True
			if self.hangup_after_timer:
				# [20080903_8] : hcryoo : [QA 6-26] 자동 응답 실행중  영상통화 버튼으로 수신하면 부재중 전화로 처리됨. 
				self.interceptAutoAnswer = True
				# [20080903_8] : hcryoo : [QA 6-26] 자동 응답 실행중  영상통화 버튼으로 수신하면 부재중 전화로 처리됨. ==
				self.autoHangupClose()
			if status.KT_CALL_TESTER:
				self.test_hangup_after_timer = None
		
		elif key == config.Green:
			roxia_event('VideoCallConnectedStage.handle_modaless_key.handle_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					if self.hangup_after_timer:
						self.autoHangupClose()
					if status.KT_CALL_TESTER:
						self.test_hangup_after_timer = None
				else:
					if spkOffHook.next():
						if self.hangup_after_timer:
							self.interceptAutoAnswer = True # no missed call log
							self.autoHangupClose()
						if status.KT_CALL_TESTER:
							self.test_hangup_after_timer = None
					else:
						spkOffHook.next()
						# mic mute 상태 유지
						if self.micMuteFlag:
							runtime.SP_context.SP_setMicDisable()
						else:
							runtime.SP_context.SP_setMicEnable()
		elif key == config.Red:
			MD.mmiTrace('VideoCallConnectedStage.handle_modaless_key.handle_key(), press *Red*')

			baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
			if baseStatus == SP_Context.CONNECTED and dectStatus == DectCallManager.CONNECTED:
				self.ui.stopCallDuration()
				runtime.dectCallManager.dropCall()
			else:
				self.ui.stopCallDuration()
				runtime.evas.use_transparency(False)

				runtime.SP_context.goIdleState()				
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)	

			if self.hangup_after_timer:
				self.hangup_after_timer = None

		elif key == config.OnHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_key(), press *OnHook*')
			#self.ui.hideSmallView()
			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				currentDevices = hsOnHook.next()
				if not currentDevices:
					self.ui.stopCallDuration()
					runtime.evas.use_transparency(False)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		elif key == config.OffHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_key(), press *OffHook*')
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():

				# choinhwa:20081027 스트림 종료 후 사운드 패스 정리되도록
				if self.hangup_after_timer:
					self.interceptAutoAnswer = True
					self.autoHangupClose()

				hsOffHook.next()

				# mic mute 상태 유지
				if self.micMuteFlag:
					runtime.SP_context.SP_setMicDisable()
				else:
					runtime.SP_context.SP_setMicEnable()
				'''
				if self.hangup_after_timer:
					self.interceptAutoAnswer = True
					self.autoHangupClose()
				'''
				if status.KT_CALL_TESTER:
					self.test_hangup_after_timer = None
			
		elif key == config.Transfer:
			if runtime.dectCallManager.isSubcribedDect():
				dectStatus = runtime.dectCallManager.getDectStatus()
				if dectStatus == DectCallManager.IDLE:
					# [20080903_5] : hcryoo : [QA 5-35] 자동 응답 메시지  송출중 휴대 장치 호출하여 통화 하여도  통화 끊어짐.
					if self.hangup_after_timer:
						self.interceptAutoAnswer = True
						self.autoHangupClose()
					# [20080903_5] : hcryoo : [QA 5-35] 자동 응답 메시지  송출중 휴대 장치 호출하여 통화 하여도  통화 끊어짐.==
					if self.micMuteFlag:
						runtime.SP_context.SP_setMicEnable()
						self.micMuteFlag = False
						self.ui.changeSoftkeyFlag(False)
					#self.modalMode = self.B2H_VIDEO_TRANSFER
					self.startB2h_VideoTransfer()
					self.showSoftkeyAndMessageInB2H_Transfer()
		else:
			return False

		if key in (config.Green, config.OffHook):
			self.ui.update_soundpath()			
		return True

	def remove_softkey_timer(self):
		if self.softkey_timer:
			self.softkey_timer = None

	def init_softkey(self):
		self.remove_softkey_timer()
		utils.show_softkey()
		
	# KA: [20080514] call menu - volume
	def volume_control(self, first_flag=False, increase=True):
		self.ui.volume_control(first_flag, increase)
		
	def hideVolume(self):
		self.ui.hideVolume()
	# KA: [20080514] call menu - volume ==
		
	def hide(self):
		self.remove_softkey_timer()
		self.volume_timer = None
		self.hideVolume()
		utils.show_softkey()
		Stage.hide(self)

	def show(self):
		debugLogN("VideoCallConnectedStage.show() start")
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)
		self.hideSoftkey()
		runtime.manager.stage.showVideoView()

		runtime.mmiDebug.mmiTrace('status.serviceStatusType = ', status.serviceStatusType)		
		runtime.mmiDebug.mmiTrace('status.first_info_number = ', status.first_info_number)
		runtime.mmiDebug.mmiTrace('status.second_info_number = ', status.second_info_number)

		if status.serviceStatusType == 'BR':
			self.showSecondCallNumber(status.second_info_number)
		elif status.serviceStatusType == 'RB':
			self.showSecondCallNumber(status.first_info_number)
		elif status.serviceStatusType in ['BW', 'WB']:
			self.showCallWaiting(status.first_info_number, status.second_info_number)
		elif status.serviceStatusType == 'BB':
			self.showThreeWayConference(status.first_info_number, status.second_info_number)
		debugLogN("VideoCallConnectedStage.show() end")
	def destroy(self):
		self.remove_softkey_timer()
		utils.show_softkey()

		if self.test_hangup_after_timer:
			self.test_hangup_after_timer = None

		if self.hangup_after_timer:
			self.hangup_after_timer = None
			runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
									code2=config.MESG_AUTO_ANSWER_STOP)
			runtime.SP_context.SP_setMicEnable()

		if self.secondCallNumberTimer:
			self.secondCallNumberTimer = None
		status.video_number_on = False
		
		self.tag_check_ppp = 0
		status.videocall_dimension = setting.video_dimension
		status.AnalogOption = False		# eicho. 05.09.27

		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		self.tag_hide_minimum_info = None
		self.tag_hide_details = None
		self.tag_snapshot = None
		self.tag_resize = None
		# hcryoo : [20070613_1] open remote quickly
		self.iframe_timer = 0
		# hcryoo : [20070613_1] open remote quickly==
		if self.tag_get_fps:
			runtime.evas.idle_remove(self.tag_get_fps)

		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		self.ADTxMuteTimer = None

		Stage.destroy(self)

class HMConnectedStage(Stage, VideoTransfer):
	name = "HMConnected"

	B2H_VIDEO_TRANSFER = 1
	H2B_VIDEO_TRANSFER = 2
	
	def __init__(self, isAutoAnswerPossible=True):
		VideoTransfer.__init__(self)
		
		runtime.timer.hide()
		import videosetting
		videosetting.temp_fluency = 0
		self.softkey_timer = None

		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		status.set_video_mode(status.VideoConnected)
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		status.phone_status = status.VoiceConnected
		status.videocall_remote_mute = status.VideoMuteOff
		status.phone_status = status.VoiceConnected
		status.videocall_show_details = status.VideoDetailsShowMinimum

		os.system('fb0top 1')
		self.ui = ui.VideoCallConnectedUI()

		status.AnalogOption = True
		status.save_current_call_status()

		def cb():
			self.work_snapshot = True
			return False
		self.tag_snapshot = utils.Timer(config.timerSnapshot, cb)

		# Set data's for detail screen
		status.videocall_show_details = status.VideoDetailsShowMinimum
		
		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		icon, pos = uiconfig.HM_background
		self.HMView = utils.put_image(icon, pos)
		self.ui.HM_msg_show(msg=_('HM activated'))		

		self.setAudioRxMute()		
		self.setVideoUnmute()

	def stopCallDuration(self):
		self.ui.stopCallDuration()
		
	def stopCallAnimation(self):
		self.ui.stopCallAnimation()		
		
	def end_call(self,error=False):
		roxia_trace('HMConnectedStage.end_call(), error=', error)
		runtime.evas.use_transparency(False)
		runtime.manager.stop_video_call(error)
		return False

	def end_call_by_red(self):
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)		
		self.ui.stopCallDuration()
		runtime.evas.use_transparency(False)
		return True
		
	def end_call_by_onhook(self):
		self.ui.stopCallDuration()
		runtime.evas.use_transparency(False)
		return False
		
	def handle_key(self, key):
		if key == config.Green:
			self.setAudioRxUnmute()			
			stage = VideoCallConnectedStage
			runtime.manager.change_stage(stage,True)
			runtime.manager.stage.handle_key(config.Green)	

		elif key == config.Red:
			MD.mmiTrace('VideoCallConnectedStage.handle_modaless_key.handle_key(), press *Red*')

			baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
			if baseStatus == SP_Context.CONNECTED and dectStatus == DectCallManager.CONNECTED:
				self.ui.stopCallDuration()
				runtime.dectCallManager.dropCall()
			else:
				self.ui.stopCallDuration()
				runtime.evas.use_transparency(False)

				runtime.SP_context.goIdleState()				
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)	

		elif key == config.OnHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_key(), press *OnHook*')
			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				currentDevices = hsOnHook.next()
				if not currentDevices:
					self.ui.stopCallDuration()
					runtime.evas.use_transparency(False)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		elif key == config.OffHook:
			MD.mmiTrace('VideoCallConnectedStage.handle_key(), press *OffHook*')
			self.setAudioRxUnmute()			
			stage = VideoCallConnectedStage
			runtime.manager.change_stage(stage,True)
			runtime.manager.stage.handle_key(config.OffHook)			
		
		return True
		
	def hideSoftkey(self):
		self.ui.hideSoftkey()
		
	def hideVideoView(self):
		runtime.evas.use_transparency(True)
		self.ui.hideLargeView()
		
	def hide(self):
		Stage.hide(self)
		
	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)
		self.hideSoftkey()
		self.hideVideoView()

	def destroy(self):
		utils.show_softkey()
		self.HMView.free()
		self.ui.notify_msg_free()
		status.video_number_on = False		
		status.videocall_dimension = setting.video_dimension
		status.AnalogOption = False		# eicho. 05.09.27

		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)

		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False

		Stage.destroy(self)

class CannotDialNotifyStage(NotifyStage):
	def __init__(self):
		icon = uiconfig.baloon_calling_icon
		message = _('Cannot dial yourself.')
		NotifyStage.__init__(self, message, icon, None, 3000)

class VideoCallNotifyStage2(NotifyStage):
	def __init__(self, message, cb=None):
		runtime.vdciapp.change_dimension(status.precapture_dimension, True)
		NotifyStage.__init__(self, message, icon = uiconfig.baloon_image_sound_image_icon, cb = cb, duration = 3000)
		self.job = utils.Idle(self.job_cb)

	def destroy(self):
		self.job = None
		NotifyStage.destroy(self)

	def job_cb(self):
		self.do_job()
		return False

	def do_job(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_GET_SNAPSHOT, \
								mesg1='/tmp/cap.yuv420')

class VideoCallImpossibleStage(NotifyStage):
	name = "VideoCallImpossible"
	def __init__(self):
		icon = uiconfig.baloon_terminated_icon
		NotifyStage.__init__(self, _('Video call impossible'), icon, None, 3000)

class VideoCallTerminatedStage(Stage):
	name = 'VideoCallTerminated'
	agenda_forbidden = True

	def __init__(self, with_error, play_message=False, name = '', number='', isOutgoingCall=False):
		roxia_event('VideoCallTerminatedStage.__init__(), with_error=', with_error, 'play_message=', play_message)
		self.with_error = with_error
		status.videocall_byuser = False
		status.critical_entered = True
		status.showSoftkeyFlag = True
		status.AutoAnswering = False
		#status.pushVideoAd = False

		# ringback 시에 소리가 불규칙한 문제점 해결.
		runtime.SP_context.SP_setMicEnable()		
		#status.firstCallType = None

		#KA: [20080610] call term test (remove to stop_video_call) 
		'''
		MD.mmiTrace('VideoCallTerminatedStage::sendCallInfoTrap $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
		def sendCallInfoTrap():
			runtime.trapHandler.callInfoTrap(status.sipResponseCodeForTrap)
			status.sipResponseCodeForTrap = None
			self.callInfoTrapTimer = None
			status.trapChecked = False
		DELAYED_SENDING_TRAP_TIME = 4000
		self.callInfoTrapTimer = utils.Timer(DELAYED_SENDING_TRAP_TIME, sendCallInfoTrap)
		'''
		#KA: [20080610] call term test ==
		self.ui = ui.VideoCallTerminatedUI(with_error, name, number, isOutgoingCall)
		#KA: [20080610] call term test (remove to below-show)
		'''
		def cb():
			def check_phone_status():
				runtime.SP_context.stopTonePlay()
				status.phone_status = status.Disconnected
				stage = None
				try:   
					if '0' in open('/proc/driver/hook_sense').read():  
						MD.mmiTrace('/proc/driver/hook_sense 검사')
						status.dtmf_overlap_mode = False            

						hsOffHook = runtime.SP_context.HS_OffHook()
						if hsOffHook.next():
							hsOffHook.next()
							runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				

						stage = EnblockEditStage
					else:
						if runtime.eaHandler.isAppInUse():
							stage = IdleStage
						elif status.missed_call_count > 0:
							stage = MissedIncomingCallStage
						else:
							stage = IdleStage
				except:   
					MD.mmiTrace('/proc/driver/hook_sense 검사 시 오류')   

				if not stage:
					print 'ERROR in stage'
					
				status.phone_status = status.Disconnected

				if status.mwi_notification_window == 1:
					import tdeservice
					stage = tdeservice.MWINotifyStage

				runtime.manager.change_stage(stage,True)
				return False
			runtime.evas.timeout_add(100,check_phone_status)
			return False
			
		self.destroyTimer = utils.Timer(500, cb)
		'''
		self.destroyTimer = None
		#KA: [20080610] call term test ==
		
		if status.KT_CALL_TESTER:
			print 'VideoCallTerminatedStage' 
			status.KT_CALL_TESTER.restartTestCall()

	#KA: [20080610] call term test
	def show(self):
		self.ui.show()
		status.phone_status = status.Disconnected
		stage = None
		
		def cb():
			try:
				runtime.SP_context.stopTonePlay()
				runtime.SP_context.goIdleState()	
				if runtime.eaHandler.isAppInUse():
					stage = IdleStage
				elif '0' in open('/proc/driver/hook_sense').read():  
					MD.mmiTrace('/proc/driver/hook_sense 검사')
					status.dtmf_overlap_mode = False
					runtime.manager.handle_offhook()
					return
				#elif status.missed_call_count > 0:
				#	stage = MissedIncomingCallStage
				else:
					stage = IdleStage
			except:   
				MD.mmiTrace('/proc/driver/hook_sense 검사 시 오류')   

			if not stage:
				print 'ERROR in stage'
			else:
				runtime.manager.change_stage(stage,True)
				runtime.evas.render_now()	
		if self.with_error == 'busy':
			self.destroyTimer = utils.Timer(6000, cb)
		elif self.with_error:
			self.destroyTimer = utils.Timer(3000, cb)			
		else:
			self.destroyTimer = utils.Timer(1000, cb)
	#KA: [20080610] call term test ==

	def handle_key(self,key):
		if runtime.eaHandler.isAppInUse():
			return True
		if key == config.OffHook:
			roxia_event('VideoCallTerminatedStage.handle_key(), press *OffHook*')

			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.startTonePlay(SP_State.DEVICE_HS)

					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
				else:
					runtime.SP_context.stopTonePlay()
					runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				

					if self.destroyTimer:
						self.destroyTimer = None
					runtime.manager.change_stage(EnblockEditStage,True)
			
		elif key == config.OnHook:
			roxia_event('VideoCallTerminatedStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("VideoCallTerminatedStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("VideoCallTerminatedStage : OnHook : Stage closed.")

					if self.destroyTimer:
						self.destroyTimer = None

					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)

					if runtime.eaHandler.isAppInUse():
						stage = IdleStage
					elif status.missed_call_count > 0:
						stage = MissedIncomingCallStage
					else:
						stage = IdleStage
					runtime.manager.change_stage(stage,True)

		elif key == config.Green:
			roxia_event('VideoCallTerminatedStage.handle_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						MD.mmiTrace("VideoCallTerminatedStage : SPK OnHook : Only Path Change.")

						if self.destroyTimer:
							self.destroyTimer = None

						runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
						'''
						status.dial_number = ''
						status.dialed_by_user = False

						runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
						runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
						'''
						if runtime.eaHandler.isAppInUse():
							stage = IdleStage
						elif status.missed_call_count > 0:
							stage = MissedIncomingCallStage
						else:
							stage = IdleStage
						runtime.manager.change_stage(stage,True)
					else:
						spkOffHook.next()
						MD.mmiTrace("VideoCallTerminatedStage : SPK OffHook : Only Path Change.")
						tone = runtime.SP_context.handset.getTone()
						runtime.SP_context.speaker.setTone(tone)
						runtime.SP_context.startTonePlay(SP_State.DEVICE_SPK)
		
		elif key == config.Red:
			roxia_event('VideoCallTerminatedStage.handle_key(), press *Red*')
			
			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("VideoCallTerminatedStage : Red : Stop tone play and Stage clear.")

					if self.destroyTimer:
						self.destroyTimer = None

					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)

					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					if runtime.eaHandler.isAppInUse():
						stage = IdleStage
					elif status.missed_call_count > 0:
						stage = MissedIncomingCallStage
					else:
						stage = IdleStage
					runtime.manager.change_stage(stage,True)
			else:
				MD.mmiTrace("VideoCallTerminatedStage : Red : ERROR CASE.")

		return True

	def destroy(self):
		roxia_trace('VideoCallTerminatedStage.destroy()')
		#runtime.SP_context.stopTonePlay()
		#runtime.SP_context.goIdleState()	
		if self.destroyTimer:
			self.destroyTimer = None
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		Stage.destroy(self)
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False

		status.phone_status = status.Disconnected
		status.pushVideoAd = False
		status.firstCallType = None
		

class AudioCallTerminatedStage(Stage):
	name = 'AudioCallTerminated'
	agenda_forbidden = True

	def __init__(self, with_error, play_message=False, name='', number='', isOutgoingCall=False):
		roxia_event('AudioCallTerminatedStage.__init__(), with_error=', with_error, 'play_message=', play_message)
		#status.pushVideoAd = False
		self.with_error = with_error
		
		status.videocall_byuser = False
		status.showSoftkeyFlag = True
		status.AutoAnswering = False
		# ringback 시에 소리가 불규칙한 문제점 해결.
		runtime.SP_context.SP_setMicEnable()		
		#status.firstCallType = None
		self.ui = ui.AudioCallTerminatedUI(with_error, name, number, isOutgoingCall)
		self.destroyTimer = None
		if status.KT_CALL_TESTER:
			print 'AudioCallTerminatedStage'
			status.KT_CALL_TESTER.restartTestCall()

	def handle_key(self,key):
		if runtime.eaHandler.isAppInUse():
			return True
		
		if key == config.OffHook:
			roxia_event('AudioCallTerminatedStage.handle_key(), press *OffHook*')

			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
					runtime.SP_context.startTonePlay(SP_State.DEVICE_HS)					
				else:
					runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
					runtime.SP_context.stopTonePlay()		
					runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)			

					if self.destroyTimer:
						self.destroyTimer = None
					runtime.manager.change_stage(EnblockEditStage,True)

		elif key == config.OnHook:
			roxia_event('AudioCallTerminatedStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("AudioCallTerminatedStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("AudioCallTerminatedStage : OnHook : Stage closed.")

					if self.destroyTimer:
						self.destroyTimer = None

					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)

					if runtime.eaHandler.isAppInUse():
						stage = IdleStage
					elif status.missed_call_count > 0:
						stage = MissedIncomingCallStage
					else:
						stage = IdleStage
					runtime.manager.change_stage(stage,True)

		elif key == config.Green:
			roxia_event('AudioCallConnectedStage.handle_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						MD.mmiTrace("AudioCallTerminatedStage : SPK OnHook : Only Path Change.")

						if self.destroyTimer:
							self.destroyTimer = None

						runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)

						if runtime.eaHandler.isAppInUse():
							stage = IdleStage
						elif status.missed_call_count > 0:
							stage = MissedIncomingCallStage
						else:
							stage = IdleStage
						runtime.manager.change_stage(stage,True)
					else:
						spkOffHook.next()
						MD.mmiTrace("AudioCallTerminatedStage : SPK OffHook : Only Path Change.")
						tone = runtime.SP_context.handset.getTone()
						runtime.SP_context.speaker.setTone(tone)
						runtime.SP_context.startTonePlay(SP_State.DEVICE_SPK)
		
		elif key == config.Red:
			roxia_event('AudioCallTerminatedStage.handle_key(), press *Red*')
			
			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("AudioCallTerminatedStage : Red : Stop tone play and Stage clear.")

					if self.destroyTimer:
						self.destroyTimer = None

					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)

					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					if runtime.eaHandler.isAppInUse():
						stage = IdleStage
					elif status.missed_call_count > 0:
						stage = MissedIncomingCallStage
					else:
						stage = IdleStage
					runtime.manager.change_stage(stage,True)
			else:
				MD.mmiTrace("AudioCallConnectedStage : Red : ERROR CASE.")

		return True

	#KA: [20080610] call term test
	def show(self):
		self.ui.show()
		status.phone_status = status.Disconnected
		stage = None

		def cb():
			try:
				runtime.SP_context.stopTonePlay()
				runtime.SP_context.goIdleState()	
				if runtime.eaHandler.isAppInUse():
					stage = IdleStage
				elif '0' in open('/proc/driver/hook_sense').read():  
					MD.mmiTrace('/proc/driver/hook_sense 검사')
					status.dtmf_overlap_mode = False
					runtime.manager.handle_offhook()
					return
				#elif status.missed_call_count > 0:
				#	stage = MissedIncomingCallStage
				else:
					stage = IdleStage
			except:   
				MD.mmiTrace('/proc/driver/hook_sense 검사 시 오류')   

			if not stage:
				print 'ERROR in stage'

			else:
				runtime.manager.change_stage(stage,True)
				runtime.evas.render_now()
		if self.with_error == 'busy':
			self.destroyTimer = utils.Timer(6000, cb)
		elif self.with_error:
			self.destroyTimer = utils.Timer(3000, cb)
		else:
			self.destroyTimer = utils.Timer(1000, cb)
	#KA: [20080610] call term test ==

	def destroy(self):
		Stage.destroy(self)
		#runtime.SP_context.stopTonePlay()
		#runtime.SP_context.goIdleState()	
		runtime.manager.set_videocall_mode(status.VideoCallDisconnected)
		if self.destroyTimer:
			self.destroyTimer = None
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		status.pushVideoAd = False
		status.firstCallType = None


class OffHookStage(Stage):
	# Page 4
	name = 'offhook'
	def __init__(self):
		roxia_event('OffHookStage.__init__()')
		icon = uiconfig.baloon_calling_icon
		self.ui = baseui.NotifyCallUI(_('REDIAL'), _('PHONEBOOK'), '', _('Calling to')+':', '', icon)
		self.ui.show_bg = True
		self.ui.show_cursor(True)
		status.dtmf_overlap_mode = True
		status.phone_status = status.Dialing
		status.dialed_by_user = True

		# eicho add 06.10.16
		status.dialed_TdESupplementary = False

	def handle_key(self, key):
		roxia_event('OffHookStage.handle_key(), key=', key)

		if key in '0123456789*#':
			roxia_event('OffHookStage.handle_key(), press *number*')

			# check call barring..
			if runtime.manager.check_call_barring(key):
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.IDLE)
					dspg.set_state(dspg.ST_IDLE)
				stage = CallBarringStage(status.dial_number)
				runtime.manager.change_stage(stage)
				return

			status.dial_number = key
			stage = ConnectedStage()
			runtime.manager.change_stage(stage)
			runtime.evas.render_now()
			# Tde Prefix in PSTN
			if profile.ip_mode == 0 and setting.set_supplement_tde_prefix == 1:
				r_number = config.FAC_TELEFONICA_PREFIX_CODE + status.dial_number
				dspg.send_dtmf(r_number, False)

			else:
				dspg.send_dtmf(key, True)

		elif key  == config.Menu1:
			roxia_event('OffHookStage.handle_key(), press *Menu1*, Redial')
			if config.key_debug:
				print 'Redial'
			# Phase2 Page 146
			import calldb
			try:
				'''
				# eicho modify 06.10.16
				detail = calldb.get_detail('dialed', 0)
				status.dialed_by_user = False
				runtime.manager.start_call(detail.number)
				'''
				#print '#### Menu1: Redial.'
				detail_num = calldb.getNumber_Redial()
				status.dialed_by_user = False
				if detail_num != '':
					runtime.manager.start_call(detail_num)
				
				return True
			except:
				return True

			# Page 27
			import calllog
			stage = calllog.PerformedCallStage
			runtime.manager.stack_stage(stage)

		elif key == 'Up':
			roxia_event('OffHookStage.handle_key(), press *Up*')
			if status.modem_audio_state == status.HS:
				import calldb
				try:
					detail = calldb.get_detail('dialed', 0)
					runtime.manager.start_call(detail.number)
					return True
				except:
					return True
			else:
				import calllog
				stage = calllog.PerformedCallStage
				runtime.manager.stack_stage(stage)

		elif key in (config.Menu2, 'Down'):
			roxia_event('OffHookStage.handle_key(), press *Menu2/Down*, run Phonebook')
			# Phase2 Page 147
			import phonebook
			stage = phonebook.FindForCallStage(include_all=False, _isemergency=True)
			runtime.manager.stack_stage(stage)

		elif key == config.Video:
# eicho add 06.08.16 for w. 123.1 BB
			status.videocall_byuser = True
			status.dtmf_overlap_mode = False
			stage = EnblockEditStage()
			runtime.manager.change_stage(stage, True)
				
			return True

		elif key == config.OnHook:
			roxia_event('OffHookStage.handle_key(), press *OnHook*')
			if config.key_debug:
				print 'Line Tone -> On Hook'
				print 'goto idle'
			return False # handle this in manager
		elif key == config.Green:
			roxia_event('OffHookStage.handle_key(), press *Green*')
			return False # handle this in manager
		elif key == config.Red:
			roxia_event('OffHookStage.handle_key(), press *Red*')
			return False # handle this in manager.
		else:
			return False
		return True

class VideoResultNotifyStage(NotifyStage):
	def __init__(self,message):
		status.call_time = -1
		status.video_call_time = 0
		status.video_mode = status.VideoIdle
		status.dial_number = status.caller_number = ''

		def cb():
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.IDLE)
			runtime.manager.change_stage(IdleStage)
			return False

		icon = uiconfig.baloon_video_setting_icon
		NotifyStage.__init__(self,message,icon)

class DirectVideoCallingStage(Stage):
	name = 'directvideocalling'
	def __init__(self, number, hostName):
		roxia_event('DirectVideoCallingStage.__init__(), number=', number)

		# ringback 시에 소리가 불규칙한 문제점 해결.
		runtime.SP_context.SP_setMicDisable()	

		runtime.SP_context.setBaseStatus(SP_Context.DIALING)
		runtime.SP_context.setBaseCallStatus(SP_Context.OUTGOING_VIDEO)

		status.firstCallType = 2
		status.isFirstCallTypeChanged = False
		status.serviceStatusType = None
		status.showSoftkeyFlag = False
		
		from ui import DirectVideoCallingUI
		self.ui = DirectVideoCallingUI(number)
		#self.tstmode = tstmode
		self.remoteID = None
		self.tag_invite = 0
		runtime.manager.set_videocall_mode(status.VideoCallConnecting)

		if runtime.dectCallManager.isSubcribedDect():
			from dectConfig import MessageCode
			runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.VIDEO_CALL)

		self.ui.show()
		runtime.evas.render_now()

		self.connect_start_time = ntptime.ntime()
		status.video_call_time = self.connect_start_time
		self.exiting = False
		self.remoteID = status.dial_number
		status.video_codec = status.AudioAndVideo
		status.video_mode = status.VideoRequesting
		status.trapChecked = False
		status.save_current_call_status() # vpark-05.08.25
		self.hostName = hostName
		self.invite_request()

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		self.hangup_after_timer = None
		
		def auto_Hangup():
			self.handle_key(config.Red)
			self.hangup_after_timer = None

		if status.KT_CALL_TESTER:
			self.hangup_after_timer = utils.Timer(status.KT_CALL_TESTER.getCallDuration()*1000, auto_Hangup)


		# eicho add 06.08.21
		# os.system('fb0top 1')

	def stopCallDuration(self):
		if self.ui:
			self.ui.stopCallDuration()		
		else:
			runtime.manager.stage.stopCallDuration()


	def handle_key(self, key):
		if key in '0123456789#*':
			return True
			'''
			status.dial_number += key
			self.ui.change_caller_number(status.dial_number)
			return True
			'''
		elif key == config.Video:
			return True

		elif key == config.Menu2:
			pass

		elif key == config.Red:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *Red*')
			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("DirectVideoCallingStage : Red : Stop tone play and Stage clear.")
					self.stopCallDuration()
					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					runtime.SP_context.goIdleState()
					
					status.video_mode = status.VideoDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_video_call(with_error=False)
			else:
				MD.mmiTrace("DirectAudioCallingStage : Red : ERROR CASE.")
					
			return True
			
		elif key == config.OnHook:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Stage closed.")

					self.stopCallDuration()

					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)

					#runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					#runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					runtime.SP_context.goIdleState()

					status.video_mode = status.VideoDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_video_call(with_error=False)
					
			return True
			
		elif key == config.OffHook:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *OffHook*')

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
					runtime.SP_context.startTonePlay(SP_State.DEVICE_HS)				
					
			return True

		elif key == config.Green:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *Green*')

			dectStatus = runtime.dectCallManager.getDectStatus()
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						'''
						status.dial_number = ''
						status.dialed_by_user = False

						self.stopCallDuration()

						runtime.SP_context.stopTonePlay()

						runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
						runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
						# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
						runtime.SP_context.goIdleState()

						status.video_mode = status.VideoDisconnected
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						runtime.manager.stop_video_call(with_error=False)
						'''
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						tone = runtime.SP_context.handset.getTone()
						runtime.SP_context.speaker.setTone(tone)
						runtime.SP_context.startTonePlay()	
						
			return True			
		return True

	def invite_request(self):
		self.tag_invite = utils.Timer(config.timeoutInvite, self.invite_cancel)
		# KA: [20080111] tstmode direct videoall
		#if self.tstmode:
		uriPolicy, number = utils.checkUrlPolicy(self.remoteID)
		#number IP인 경우는 number를 mesge2
		if number.find('.') >= 0:
			self.hostName = number
			number = None
		if self.hostName:
			uriPolicy = '0'

		if number[:3] == '010':
			number = '*' + number		
			
		if number == '+':
			number = '+0'
			
		runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
								code2=config.MESG_CALL_VIDEO, \
								mesg1=number, mesg2=self.hostName, mesg9=uriPolicy)
								
	def invite_sucessed(self, call_type, supervision):
		self.tag_invite = 0
		if status.video_mode != status.VideoRequesting:
			return

		# eicho modify following.. 06.06.26
		#status.video_mode == status.VideoConnected
		status.video_mode = status.VideoConnected

		utils.player.stop_message()

		# if supervision, remote full
		if supervision:
			status.supervision_remote = 1
			# eicho remove following line : 06.11.13
			'''
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
								code2=config.MESG_SET_DIMENSION, \
								mesg1=config.DIMENSION_REMOTE_BIG_ONLY, mesg2=0)
			'''

		runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
		
		if call_type == 0: #audio call
			status.video_mode = status.AudioConnected
			status.isFirstCallTypeChanged = True
			runtime.manager.change_stage(AudioCallConnectedStage,True)
		else:
			runtime.manager.change_stage(VideoCallConnectedStage,True)
			runtime.SP_context.setPhysicalDevice()
			runtime.manager.stage.stopCallAnimation()
			# ringo가 없는 상황에서 테스트를 해 봐야 함.
			#runtime.manager.stage.changeMessagePrefix()

			runtime.manager.stage.showVideoView()

	def setCurrentTime(self):
		self.ui.setCurrentTime()

	def invite_failed(self):
		self.tag_invite = 0
		if status.video_mode != status.VideoRequesting:
			return

		status.video_mode = status.VideoDisconnected

		if status.modem_audio_state == status.SPK:
			status.set_modem_audio_state(status.IDLE)
		roxia_trace('call stop_video_call #3')
		self.stopCallDuration()
		runtime.manager.stop_video_call(True)
		return False

	def invite_cancel(self, error=False):
		runtime.mmiDebug.mmiTrace('DirectVideoCallingStage::invite_cancel()')
		
		self.tag_invite = 0
		if status.video_mode != status.VideoRequesting:
			return

		status.video_mode = status.VideoDisconnected
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		roxia_trace('call stop_video_call #4')
		self.stopCallDuration()
		runtime.manager.stop_video_call(error)
		return False


	def invite_error(self):
		temp_mode = status.video_mode
		self.tag_invite = 0
		if temp_mode != status.VideoRequesting:
			return

		if status.modem_audio_state == status.SPK:
			status.set_modem_audio_state(status.IDLE)

		message = 'video connecting failed'
		stage = VideoResultNotifyStage(message)
		runtime.manager.change_stage(stage)

	def destroy(self):
		self.setCurrentTime()
		
		if self.hangup_after_timer:
			self.hangup_after_timer = None
		self.tag_invite = 0
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		self.stopCallDuration()
		Stage.destroy(self)

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)


class DirectAudioCallingStage(Stage):
	name = 'directaudiocalling'
	agenda_forbidden = True
	def __init__(self, number, hostName = ''):
		roxia_event('DirectAudioCallingStage.__init__(), number=', number)

		# ringback 시에 소리가 불규칙한 문제점 해결.
		runtime.SP_context.SP_setMicDisable()		
		status.firstCallType = 1
		status.serviceStatusType = None
		
		runtime.SP_context.setBaseStatus(SP_Context.DIALING)
		runtime.SP_context.setBaseCallStatus(SP_Context.OUTGOING_AUDIO)
		
		self.ui = ui.DirectAudioCallingUI(number)
		self.remoteID = None
		self.tag_invite = 0
		runtime.manager.set_videocall_mode(status.VideoCallConnecting)

		status.pushVideoAd = False
		status.showSoftkeyFlag = False

		if runtime.dectCallManager.isSubcribedDect():
			from dectConfig import MessageCode
			runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)

		self.ui.show()
		runtime.evas.render_now()

		self.connect_start_time = ntptime.ntime()
		status.call_time = self.connect_start_time
		self.exiting = False
		self.remoteID = status.dial_number
		status.video_codec = status.AudioOnly
		status.set_video_mode(status.AudioRequesting)
		status.save_current_call_status()
		status.trapChecked = False
		self.hostName = hostName
		self.invite_request()

		self.hangup_after_timer = None
		
		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		def auto_Hangup():
			self.handle_key(config.Red)
			self.hangup_after_timer = None

		if status.KT_CALL_TESTER:
			self.hangup_after_timer = utils.Timer(status.KT_CALL_TESTER.getCallDuration()*1000, auto_Hangup)


	def handle_key(self, key):
		roxia_event('DirectAudioCallingStage.handle_key(), key=', key)
		if key in '0123456789#*':
			return True
			'''
			roxia_event('DirectAudioCallingStage.handle_key(), press *number*')
			status.dial_number += key
			self.ui.change_caller_number(status.dial_number)
			'''
		elif key == config.Video:
			roxia_event('DirectAudioCallingStage.handle_key(), press *Video*')

		elif key == config.Menu2:
			roxia_event('DirectAudioCallingStage.handle_key(), press *Menu2*')

		elif key == config.Red:
			roxia_event('DirectAudioCallingStage.handle_key(), press *Red*')

			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("DirectAudioCallingStage : Red : Stop tone play and Stage clear.")
					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					runtime.SP_context.goIdleState()
					
					status.video_mode = status.AudioDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_audio_call(with_error=False)
			else:
				MD.mmiTrace("DirectAudioCallingStage : Red : ERROR CASE.")
					
			return True

		elif key == config.OnHook:
			roxia_event('DirectAudioCallingStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Stage closed.")

					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)

					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					runtime.SP_context.goIdleState()

					status.video_mode = status.AudioDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_audio_call(with_error=False)
					
			return True
			
		elif key == config.OffHook:
			roxia_event('DirectAudioCallingStage.handle_key(), press *OffHook*')

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
					runtime.SP_context.startTonePlay(SP_State.DEVICE_HS)				
					
			return True

		elif key == config.Green:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *Green*')

			dectStatus = runtime.dectCallManager.getDectStatus()
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						'''
						status.dial_number = ''
						status.dialed_by_user = False

						runtime.SP_context.stopTonePlay()

						runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
						runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
						# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
						runtime.SP_context.goIdleState()

						status.video_mode = status.AudioDisconnected
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						#runtime.manager.stop_audio_call(with_error=False)
						'''
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						tone = runtime.SP_context.handset.getTone()
						runtime.SP_context.speaker.setTone(tone)
						runtime.SP_context.startTonePlay()						
			return True			
		else:
			roxia_event('DirectAudioCallingStage.handle_key(), press *...*')
			return False

		return True


	def invite_request(self):
		runtime.mmiDebug.mmiTrace('DirectAudioCallingStage::invite_request()')
		self.tag_invite = utils.Timer(config.timeoutInvite, self.invite_cancel)
		
		uriPolicy, number = utils.checkUrlPolicy(self.remoteID)
		#number IP인 경우는 number를 mesge2
		if number.find('.') >= 0:
			self.hostName = number
			number = None
		if self.hostName:
			uriPolicy = '0'		

		if number == '+':
			number = '+0'
			
		runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
							code2=config.MESG_CALL_AUDIO, \
							mesg1=number, mesg2=self.hostName, mesg9=uriPolicy)

	def setCurrentTime(self):
		self.ui.setCurrentTime()
		
	def invite_sucessed(self):
		runtime.mmiDebug.mmiTrace('DirectAudioCallingStage::invite_sucessed()')
		
		self.tag_invite = 0

		if status.video_mode != status.AudioRequesting:
			return

		status.video_mode = status.AudioConnected

		utils.player.stop_message()
		runtime.manager.change_stage(AudioCallConnectedStage,True)

	def invite_failed(self):
		self.tag_invite = 0
		if status.video_mode != status.AudioRequesting:
			return

		status.video_mode = status.AudioDisconnected

		roxia_trace('DirectAudioCallingState.invite_failed()')
		runtime.manager.stop_audio_call(True)
		return False

	def invite_cancel(self, error=False):
		runtime.mmiDebug.mmiTrace('DirectAudioCallingStage::invite_cancel()')

		self.tag_invite = 0
		'''
		if status.first_video_mode == status.AudioIncoming or \
			status.second_video_mode == status.AudioIncoming:
			runtime.manager.back_stage('SecondIncomingCall')
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			if runtime.manager.stage.get_name() == 'SecondIncomingCall':
				runtime.manager.stage.connected_disconnected()
				return
			else:
				runtime.manager.stop_audio_call(False)
				return
		'''
		if status.video_mode != status.AudioRequesting:
			return

		status.video_mode = status.AudioDisconnected
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		runtime.manager.stop_audio_call(error)
		return False


	def invite_error(self):
		temp_mode = status.video_mode
		self.tag_invite = 0
		if temp_mode != status.AudioRequesting:
			return


		if status.modem_audio_state == status.SPK:
			status.set_modem_audio_state(status.IDLE)

		message = 'video connecting failed'
		stage = VideoResultNotifyStage(message)
		runtime.manager.change_stage(stage)

	def setCurrentTime(self):
		self.ui.setCurrentTime()
		
	def destroy(self):
		self.setCurrentTime()
		self.tag_invite = 0
		if self.hangup_after_timer:
			self.hangup_after_timer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)

class IncomingCallStage(Stage):
	name = 'incomingcall'
	agenda_forbidden = True
	in_progress = 0
	def __init__(self, media, mesg1, mesg2, alertinfo, answer_after, myCardInfoList=None):
		debugLogN("IncomingCallStage.__init__() start")
		self.media = media
		self.isPlayingRing = False
		# audio호이면 ring이 가게 되므로 사용 상태를 보내면 안됨.
		from dectConfig import MessageCode
		if self.media=='1':
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.VIDEO_CALL)

		if self.media=='1':
			status.firstCallType = 2 # video
			status.video_call_time = ntptime.ntime()
			status.call_time = 0
		else:
			status.firstCallType = 1 # audio
			status.call_time = ntptime.ntime()
			status.video_call_time = 0
		
		status.dial_number = ''
		status.serviceStatusType = None
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		runtime.manager.isUpdate = False
		if runtime.updComm:
			runtime.updComm.destroy()
			runtime.updComm = None
		callerNumber = mesg2
		self.caller_name = ''
		snapshot = None
		
		if mesg2 == '': # number
			self.caller_name = 'anonymous'
		elif mesg2.strip().lower() == 'anonymous':
			self.caller_name = 'anonymous'
		else:
			from phonedb import phonedb
			self.caller_name = phonedb.get_name(mesg2)
			snapshot = phonedb.get_snapshot(status.caller_number)
			if snapshot:
				if not os.access(snapshot, os.R_OK):
					snapshot = None
			if self.caller_name == mesg2:
				#phonebook not found
				self.caller_name = ''

		self.answerCallFlag = False
		if answer_after != '':
			def auto_answer():
				self.answerCallFlag = True
				runtime.manager.stage.handle_key(config.Green)
			self.answer_after_timer = utils.Timer(6000, auto_answer)

		#self.caller_name = status.display_caller_name(status.active_call_index)
		if self.caller_name == 'anonymous':
			snapshot = None
		self.ui = ui.IncomingUI(self.caller_name, snapshot, video=media, myCardInfo=myCardInfoList)

		runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)

		if self.media=='1':
			status.video_mode = status.VideoIncoming
			runtime.SP_context.setBaseCallStatus(SP_Context.INCOMING_VIDEO)
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.setDectCallStatus(DectCallManager.INCOMING_VIDEO)
		else:
			status.video_mode = status.AudioIncoming
			runtime.SP_context.setBaseCallStatus(SP_Context.INCOMING_AUDIO)
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.setDectCallStatus(DectCallManager.INCOMING_AUDIO)

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		#### Ring 관련 업무 처리
		def play_ring():
			self.isPlayingRing = True
			utils.player.play_ring(runtime.manager.get_melody())
			#self.ui.set_left(_('MUTE'))	
			self.play_ring_timer = None
			return False
		
		def stop_ring():
			spkOnHook = runtime.SP_context.SPK_OnHook()
			if spkOnHook.next():
				spkOnHook.next()
				spkOnHook.next()

			runtime.manager.kill_ringer()
			self.stop_ring_timer = None

			self.invite_reject(False, True)

			return True
	
		# 착신 제한 번호 검사
		if setting.in_restrict and (callerNumber  in setting.in_restrict_nums):
			self.incomingRestrictionTimer = None
			def incomingRestriction_cb():
				baseStatus = runtime.SP_context.getBaseStatus()
				if baseStatus == SP_Context.RINGING:
					runtime.vdciapp.send_mesg(code1=config.MESG_INCOMING_CALL, code2=config.MESG_CALL_REJECT, mesg1=config.REASON_TEMPORARILY_UNAVAILABLE)
				self.incomingRestrictionTimer = None
				
			runtime.SP_context.setBaseStatus(SP_Context.RINGING) # 실제로는 ring이 울리지 않는 상태
			self.incomingRestrictionTimer = utils.Timer(5000, incomingRestriction_cb)
		else:
			runtime.SP_context.setBaseStatus(SP_Context.RINGING)
			runtime.mmedia.unload()
			self.play_ring_timer = utils.Timer(300, play_ring)
			'''
			runtime.mmedia.unload()
			self.isPlayingRing = True
			utils.player.play_ring(runtime.manager.get_melody())
			'''
			if self.media != '1': # audio
				if runtime.dectCallManager.isSubcribedDect():
					runtime.dectCallManager.setDectStatus(DectCallManager.RINGING)
					runtime.dectCallManager.startIncomingCall(mesg1, mesg2)
			self.stop_ring_timer = utils.Timer(config.stop_ring_timer, stop_ring)

		self.firstRedKeyPressed = True
		self.isAcceptKey = False
		self.isOffHook = False
		def acceptKey():
			self.isAcceptKey = True	
			self.acceptKeyTimer = None
		self.acceptKeyTimer = utils.Timer(200, acceptKey)
		debugLogN("IncomingCallStage.__init__() end")
	def setCurrentTime(self):
		self.ui.setCurrentTime()

	def handle_key(self, key):
		roxia_event('IncomingCallStage.handle_key(), key=', key)

		if not self.isAcceptKey:
			if key == config.OffHook:
				self.isOffHook = True
			elif key == config.OnHook:
				self.isOffHook  = False
			return True
			
		self.setCurrentTime()
		
		if key == config.Green:
			self.in_progress = 1
			if self.isOffHook:
				roxia_event('IncomingCallStage.handle_key(), press *Green* - isOffHook=True')
				runtime.manager.kill_ringer()
				
				runtime.SP_context.speaker.setStatus(Device.ON_HOOK)
				runtime.SP_context.goIdleState()

				runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
				# HS 연결
				hsOffHook = runtime.SP_context.HS_OffHook()
				if hsOffHook.next():
					hsOffHook.next()

				# DECT 링 상태 종료
				if self.media != '1':
					if runtime.dectCallManager.isSubscription():
						runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
						runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
						from dectConfig import MessageCode
						runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
						runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
			
				self.answer_after_timer = None
				self.stop_ring_timer = None

				if self.media=='1':
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
					status.videocall_mute = status.VideoMuteOn
				else:
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

				#runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				if self.media == '1':
					mesg = _('Video call connecting...')
				elif self.media == '2':
					mesg = _('Connecting HM')
				else:
					mesg = _('Audio call connecting...')
				self.ui.change_message(mesg)

				status.set_call_time()
				status.receiveCallInIncoming = True
				return True
			else:
				roxia_event('IncomingCallStage.handle_key(), press *Green* - in_progress=0')
				utils.print_hw_debug('ON-HOOK')
				runtime.manager.kill_ringer()
				# SPK-->SPK 이므로 링 상태를 종료할 필요 없다.
				
				# SPK 연결
				spkOffHook = runtime.SP_context.SPK_OffHook()
				if spkOffHook.next():
					spkOffHook.next()

				if self.media != '1':
					# DECT 링 상태 종료
					if runtime.dectCallManager.isSubscription():
						runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
						runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
						from dectConfig import MessageCode
						runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
						runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
						
				self.answer_after_timer = None
				self.stop_ring_timer = None

				if self.media=='1':
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
					status.videocall_mute = status.VideoMuteOn
				else:
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

				#runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				if self.media == '1':
					mesg = _('Video call connecting...')
				elif self.media == '2':
					mesg = _('Connecting HM')
				else:
					mesg = _('Audio call connecting...')
				self.ui.change_message(mesg)

				status.set_call_time()
				if self.answerCallFlag:
					status.receiveCallInIncoming = False
				else:
					status.receiveCallInIncoming = True
				return True

		elif key == config.OffHook:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *OffHook* - in_progress=0')
			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			utils.print_hw_debug('OFF-HOOK')
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()

			# HS 연결
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()
			runtime.SP_context.speaker.setStatus(Device.ON_HOOK)

			# DECT 링 상태 종료
			if self.media != '1':
				if runtime.dectCallManager.isSubscription():
					runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
					runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
					from dectConfig import MessageCode
					runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
					runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
			
			self.answer_after_timer = None
			self.stop_ring_timer = None

			if self.media=='1':
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
				status.videocall_mute = status.VideoMuteOn

			else:
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

			#runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
			if self.media == '1':
				mesg = _('Video call connecting...')
			elif self.media == '2':
				mesg = _('Connecting HM')
			else:
				mesg = _('Audio call connecting...')
			self.ui.change_message(mesg)

			status.set_call_time()
			status.receiveCallInIncoming = True
			return True

		elif key == config.Video:
			if status.video_mode == status.VideoIncoming :
				self.in_progress = 1
				roxia_event('IncomingCallStage.handle_key(), press *VideoGreen* - in_progress=0')
				utils.print_hw_debug('ON-HOOK')
				runtime.manager.kill_ringer()
				# SPK-->SPK 이므로 링 상태를 종료할 필요 없다.
				
				# SPK 연결
				spkOffHook = runtime.SP_context.SPK_OffHook()
				if spkOffHook.next():
					spkOffHook.next()

				if self.media != '1':
					# DECT 링 상태 종료
					if runtime.dectCallManager.isSubscription():
						runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
						runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
						from dectConfig import MessageCode
						runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
						runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				

				#self.after_ring = None
				self.answer_after_timer = None
				self.stop_ring_timer = None
				
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
				status.videocall_mute = status.VideoMuteOn

				#runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				if self.media == '1':
					mesg = _('Video call connecting...')
				elif self.media == '2':
					mesg = _('Connecting HM')
				else:
					mesg = _('Audio call connecting...')
				self.ui.change_message(mesg)

				status.set_call_time()
				status.receiveCallInIncoming = True
				return True			

		elif key == config.Red:
			roxia_event('IncomingCallStage.handle_key(), press *Red* - in_progress=0')
			if self.firstRedKeyPressed:
				if self.isPlayingRing:
					self.firstRedKeyPressed = False
					runtime.manager.kill_ringer()
			else:
				self.invite_reject(reject=True) # 수신 거부 호에 대한 missed call 처리
			return True
		elif key == config.OnHook:
			# 수화기를 든 상황에서 호가 들어오면 수화기를 올려 놓고 GREEN key로 받는다.
			'''
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *OnHook* - in_progress=0')
			dspg.dtmf_abort()
			status.set_modem_audio_state(status.IDLE)

			if runtime.dectCallManager.isSubscription():
				runtime.dectCallManager.cancelCall()
			self.invite_reject()
			'''
			return True

		elif key == config.Menu1:
			roxia_event('IncomingCallStage.handle_key(), press *Menu1*, Ring mute- in_progress=0')
			#runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			#runtime.SP_context.goIdleState()
			#runtime.SP_context.speaker.setStatus(Device.ON_HOOK)
			#utils.player.stop(onTup=True)
			self.ui.set_left('')
			return True

		elif key == config.Menu2:
			return True
			roxia_event('IncomingCallStage.handle_key(), press *Menu2*, Reject - in_progress=0')
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()

			self.in_progress = 1

			if self.media != '1':
				if runtime.dectCallManager.isSubscription():
					runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
					runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
					from dectConfig import MessageCode
					runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
					runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				

			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)

			runtime.SP_context.speaker.setStatus(Device.ON_HOOK)

			self.invite_reject()
			return True

		elif key == config.TS1_OFF_HOOK:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *TS1_OFF_HOOK* - in_progress=0')
			runtime.SP_context.dect1.setStatus(Device.OFF_HOOK)
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()
			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)
				
			# DECT1 연결
			ts1OffHook = runtime.SP_context.TS1_OffHook()
			if ts1OffHook.next():
				ts1OffHook.next()

			#self.after_ring = None
			self.answer_after_timer = None
			self.stop_ring_timer = None

			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, 	code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

			if self.media=='1':
				# 영상 통화 중에는 dect로 ring이 가지 않도록 정책이 변경되어 이 부분은 진행되지 않음.
				# runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				pass
			else:
				runtime.manager.change_stage(IdleStage, True)
			status.set_call_time()
		elif key == config.TS2_OFF_HOOK:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *TS2_OFF_HOOK* - in_progress=0')
			runtime.manager.kill_ringer()
			runtime.SP_context.goIdleState()
			ts2OffHook = runtime.SP_context.TS2_OffHook()
			if ts2OffHook.next():
				ts2OffHook.next()
			
			#self.after_ring = None
			self.answer_after_timer = None
			self.stop_ring_timer = None

			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
							code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)
			runtime.manager.stack_stage(IdleStage)
			status.set_call_time()
			
		return True

	def invite_reject(self, error=False, reject=False):
		runtime.mmiDebug.mmiTrace('IncomingCallStage::invite_reject')
		self.in_progress = 0
		if status.video_mode != status.AudioIncoming and status.video_mode != status.VideoIncoming:
			return

		#self.after_ring = None
		self.answer_after_timer = None
		self.stop_ring_timer = None
		
		runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
						code2=config.MESG_CALL_REJECT, \
						mesg1=config.REASON_TEMPORARILY_UNAVAILABLE)

		if runtime.dectCallManager.isSubcribedDect():
	 		runtime.dectCallManager.rejectCallByBase()

		if status.video_mode == status.VideoIncoming:
			if reject:
				status.video_call_time = 0
			else:
				status.video_call_time = ntptime.ntime() # for received call log
			runtime.manager.stop_video_call(error)
		else:
			if reject:
				status.call_time = 0
			else:
				status.call_time = ntptime.ntime() # for received call log
			runtime.manager.stop_audio_call(error)

	def invite_sucessed(self, call_type):
		runtime.manager.kill_ringer()
		if call_type == 0: #audio call
			stage = AudioCallConnectedStage(self.caller_name)
		else:
			stage = VideoCallConnectedStage

		runtime.manager.change_stage(stage,True)


	def invite_error(self):
		self.in_progress = 0

		if status.video_mode != status.AudioIncoming:
			return

		message = 'video connecting failed'
		stage = VideoResultNotifyStage(message)
		runtime.manager.change_stage(stage)

		if status.video_mode == status.VideoIncoming:
			runtime.manager.stop_video_call(error)
		else:
			runtime.manager.stop_audio_call(True)

	def destroy(self):
		self.in_progress = 0
		#self.after_ring = None
		self.answer_after_timer = None
		self.stop_ring_timer = None
		self.play_ring_timer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)
		
	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)


#class IncomingAudioCallStage(Stage):
# this class is not in use.  Please delete! vpark 06.02.08

# This class is used when switching from two call stages to one call connecting.
class AudioCallConnectingStage(Stage):
	name = 'AudioCallConnecting'
	agenda_forbidden = True
	def __init__(self, number):
		roxia_event('AudioConnectingStage.__init__(), number=', number)
		self.ui = ui.CallingUI(number)
		self.remoteID = None

		status.video_codec = status.AudioOnly
		status.video_mode = status.AudioRequesting

		runtime.manager.set_videocall_mode(status.VideoCallConnecting)
		self.ui.show()
		runtime.evas.render_now()
		self.exiting = False
		status.save_current_call_status()

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		self.tag_invite = utils.Timer(config.timeoutInvite, self.invite_cancel)

	def handle_key(self, key):
		roxia_event('AudioConnectingStage.handle_key(), key=', key)

		if key == config.Red:
			roxia_event('AudioConnectingStage.handle_key(), press *Red*')
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.IDLE)
				self.invite_cancel()
				return True
			else:
				pass

			return False
		elif key == config.OnHook:
			roxia_event('AudioConnectingStage.handle_key(), press *OnHook*')
			if status.modem_audio_state == status.HS:
				status.set_modem_audio_state(status.IDLE)
				self.invite_cancel()
				return True
			else:
				pass

			return False
		else:
			roxia_event('AudioConnectingStage.handle_key(), press *...*')
			return False

		return True

	def invite_cancel(self):
		runtime.mmiDebug.mmiTrace('AudioCallConnectingStage::invite_cancel()')

		self.tag_invite = 0
		if status.video_mode != status.AudioRequesting:
			return

		status.video_mode = status.AudioDisconnected

		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		runtime.manager.stop_audio_call(False)

		return False


	def destroy(self):
		self.tag_invite = 0
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)

class CallConnectingStage(Stage):
	name = 'callconnecting'
	def __init__(self, caller_type='', media_type=''):
		debugLogC("CallConnectingStage.__init__(): start");
		self.media_type = media_type
		self.ui = ui.CallConnectingUI('', media_type)
		self.ui.show_bg = True
		self.ui.show()
		self.caller_stage = caller_type
		debugLogC("CallConnectingStage.end(): start");
		#runtime.evas.render_now()

	def handle_key(self, key):
		self.setCurrentTime()
		
		if key in (config.Red, config.OnHook):
			if self.caller_stage == 'incomingcall' :
				roxia_event('IncomingCallStage.handle_key(), press *OnHook*')
				runtime.SP_context.goIdleState()

				if not status.trapChecked:
					status.trapChecked = True
					setting.dropCall = setting.dropCall + 1
					runtime.mmiDebug.mmiTrace('CallConnectingStage / setting.dropCall = ', setting.dropCall)

				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				if self.media_type == '1' or self.media_type == '2':
					runtime.manager.stop_video_call(False)				
				else:
					runtime.manager.stop_audio_call(False)				
			else:
				runtime.manager.back[-1].handle_key(key)

		elif key == config.OffHook:
			status.set_modem_audio_state(status.HS)
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()
		return True

	def setCurrentTime(self):
		self.ui.setCurrentTime()

	def end_call(self, call_error=False):
		print '### CallConnecting Stage calls end_call!!!'

	def show(self):
		debugLogC("CallConnectingStage.show(): start");
		Stage.show(self)
		debugLogC("CallConnectingStage.show(): end");

	def destroy(self):
		self.setCurrentTime()
		debugLogC("CallConnectingStage.destroy()");		
		Stage.destroy(self)
		
# KA:[20081013] 영상 모니터링
class HMIncomingStage(Stage): # incoming # obselete
	name = 'HMIncoming'
	agenda_forbidden = True
	in_progress = 0
	def __init__(self, media, mesg1, mesg2, alertinfo, answer_after, myCardInfoList=None):
		self.media = media
		# audio호이면 ring이 가게 되므로 사용 상태를 보내면 안됨.
		from dectConfig import MessageCode
		if self.media=='1':
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.VIDEO_CALL)
		if self.media=='1':
			status.firstCallType = 2 # video
			status.video_call_time = ntptime.ntime()
			status.call_time = 0
		else:
			status.firstCallType = 1 # audio
			status.call_time = ntptime.ntime()
			status.video_call_time = 0
		
		status.dial_number = ''
		status.serviceStatusType = None
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		runtime.manager.isUpdate = False
		if runtime.updComm:
			runtime.updComm.destroy()
			runtime.updComm = None
		callerNumber = mesg2
		self.caller_name = ''
		snapshot = None
		
		if mesg2 == '': # number
			self.caller_name = 'anonymous'
		elif mesg2.strip().lower() == 'anonymous':
			self.caller_name = 'anonymous'
		else:
			from phonedb import phonedb
			self.caller_name = phonedb.get_name(mesg2)
			snapshot = phonedb.get_snapshot(status.caller_number)
			if snapshot:
				if not os.access(snapshot, os.R_OK):
					snapshot = None
			if self.caller_name == mesg2:
				#phonebook not found
				self.caller_name = ''

		self.answerCallFlag = False

		def auto_answer():
			self.answerCallFlag = True
			self.HMaccept()
		self.answer_after_timer = utils.Timer(2000, auto_answer)

		#self.caller_name = status.display_caller_name(status.active_call_index)
		if self.caller_name == 'anonymous':
			snapshot = None
		self.ui = ui.IncomingUI(caller_name=self.caller_name, avata=snapshot, video='2')

		runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
		if self.media=='1':
			status.video_mode = status.VideoIncoming
			runtime.SP_context.setBaseCallStatus(SP_Context.INCOMING_VIDEO)
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.setDectCallStatus(DectCallManager.INCOMING_VIDEO)
		else:
			status.video_mode = status.AudioIncoming
			runtime.SP_context.setBaseCallStatus(SP_Context.INCOMING_AUDIO)
			if runtime.dectCallManager.isSubcribedDect():
				runtime.dectCallManager.setDectCallStatus(DectCallManager.INCOMING_AUDIO)

		if setting.screen_saver_enabled:
			status.not_screen_saver = True
	
		#runtime.SP_context.setBaseStatus(SP_Context.RINGING)
		#runtime.mmedia.unload()
		#self.play_ring_timer = utils.Timer(300, play_ring)
		self.firstRedKeyPressed = True
		self.isAcceptKey = False
		self.isOffHook = False
		def acceptKey():
			self.isAcceptKey = True	
			self.acceptKeyTimer = None
		self.acceptKeyTimer = utils.Timer(200, acceptKey)

	def setCurrentTime(self):
		self.ui.setCurrentTime()

	def HMaccept(self):
		roxia_event('HMIncomingStage')
		#utils.print_hw_debug('ON-HOOK')
		#runtime.manager.kill_ringer()
		# SPK-->SPK 이므로 링 상태를 종료할 필요 없다.		
		# SPK 연결
		spkOffHook = runtime.SP_context.SPK_OffHook()
		if spkOffHook.next():
			spkOffHook.next()

		if self.media != '1':
			# DECT 링 상태 종료
			if runtime.dectCallManager.isSubscription():
				runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
				runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
				from dectConfig import MessageCode
				runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
				runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
				
		self.answer_after_timer = None
		self.stop_ring_timer = None

		if self.media=='1':
			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
							code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
			status.videocall_mute = status.VideoMuteOn
		else:
			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
							code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

		runtime.manager.stack_stage(CallConnectingStage('incomingcall', '2'))
		status.set_call_time()
		if self.answerCallFlag:
			status.receiveCallInIncoming = False
		else:
			status.receiveCallInIncoming = True
		return True	

	def handle_key(self, key):
		roxia_event('IncomingCallStage.handle_key(), key=', key)

		if not self.isAcceptKey:
			if key == config.OffHook:
				self.isOffHook = True
			elif key == config.OnHook:
				self.isOffHook  = False
			return True
			
		self.setCurrentTime()
		
		if key == config.Green:
			self.in_progress = 1
			
			'''
			if self.isOffHook:
				roxia_event('IncomingCallStage.handle_key(), press *Green* - isOffHook=True')
				#runtime.manager.kill_ringer()
				
				runtime.SP_context.speaker.setStatus(Device.ON_HOOK)
				runtime.SP_context.goIdleState()

				runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
				# HS 연결
				hsOffHook = runtime.SP_context.HS_OffHook()
				if hsOffHook.next():
					hsOffHook.next()

				# DECT 링 상태 종료
				if self.media != '1':
					if runtime.dectCallManager.isSubscription():
						runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
						runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
						from dectConfig import MessageCode
						runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
						runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
			
				self.answer_after_timer = None
				self.stop_ring_timer = None

				if self.media=='1':
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
					status.videocall_mute = status.VideoMuteOn
				else:
					runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
									code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)
				runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				status.set_call_time()
				status.receiveCallInIncoming = True
				return True

			'''
				
			#else:
			roxia_event('IncomingCallStage.handle_key(), press *Green* - in_progress=0')
			#utils.print_hw_debug('ON-HOOK')
			#runtime.manager.kill_ringer()
			# SPK-->SPK 이므로 링 상태를 종료할 필요 없다.
			
			# SPK 연결
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				spkOffHook.next()

			if self.media != '1':
				# DECT 링 상태 종료
				if runtime.dectCallManager.isSubscription():
					runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
					runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
					from dectConfig import MessageCode
					runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
					runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
					
			self.answer_after_timer = None
			self.stop_ring_timer = None

			if self.media=='1':
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
				status.videocall_mute = status.VideoMuteOn
			else:
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

			runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
			status.set_call_time()
			if self.answerCallFlag:
				status.receiveCallInIncoming = False
			else:
				status.receiveCallInIncoming = True
			return True

		elif key == config.OffHook:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *OffHook* - in_progress=0')
			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			utils.print_hw_debug('OFF-HOOK')
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()

			# HS 연결
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()
			runtime.SP_context.speaker.setStatus(Device.ON_HOOK)

			# DECT 링 상태 종료
			if self.media != '1':
				if runtime.dectCallManager.isSubscription():
					runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
					runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
					from dectConfig import MessageCode
					runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
					runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				
			
			self.answer_after_timer = None
			self.stop_ring_timer = None

			if self.media=='1':
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
				status.videocall_mute = status.VideoMuteOn

			else:
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

			runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
			status.set_call_time()
			status.receiveCallInIncoming = True
			return True

		elif key == config.Video:
			if status.video_mode == status.VideoIncoming :
				self.in_progress = 1
				roxia_event('IncomingCallStage.handle_key(), press *VideoGreen* - in_progress=0')
				utils.print_hw_debug('ON-HOOK')
				runtime.manager.kill_ringer()
				# SPK-->SPK 이므로 링 상태를 종료할 필요 없다.
				
				# SPK 연결
				spkOffHook = runtime.SP_context.SPK_OffHook()
				if spkOffHook.next():
					spkOffHook.next()

				if self.media != '1':
					# DECT 링 상태 종료
					if runtime.dectCallManager.isSubscription():
						runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
						runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
						from dectConfig import MessageCode
						runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
						runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				

				#self.after_ring = None
				self.answer_after_timer = None
				self.stop_ring_timer = None
				
				runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
								code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL, mesg2='1')
				status.videocall_mute = status.VideoMuteOn

				runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))			
				status.set_call_time()
				status.receiveCallInIncoming = True
				return True			

		elif key == config.Red:
			roxia_event('IncomingCallStage.handle_key(), press *Red* - in_progress=0')
			if self.firstRedKeyPressed:
				if self.isPlayingRing:
					self.firstRedKeyPressed = False
					runtime.manager.kill_ringer()
			else:
				self.invite_reject(reject=True) # 수신 거부 호에 대한 missed call 처리
			return True
		elif key == config.OnHook:
			# 수화기를 든 상황에서 호가 들어오면 수화기를 올려 놓고 GREEN key로 받는다.
			'''
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *OnHook* - in_progress=0')
			dspg.dtmf_abort()
			status.set_modem_audio_state(status.IDLE)

			if runtime.dectCallManager.isSubscription():
				runtime.dectCallManager.cancelCall()
			self.invite_reject()
			'''
			return True

		elif key == config.Menu1:
			roxia_event('IncomingCallStage.handle_key(), press *Menu1*, Ring mute- in_progress=0')
			#runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			#runtime.SP_context.goIdleState()
			#runtime.SP_context.speaker.setStatus(Device.ON_HOOK)
			#utils.player.stop(onTup=True)
			self.ui.set_left('')
			return True

		elif key == config.Menu2:
			return True
			roxia_event('IncomingCallStage.handle_key(), press *Menu2*, Reject - in_progress=0')
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()

			self.in_progress = 1

			if self.media != '1':
				if runtime.dectCallManager.isSubscription():
					runtime.dectCallManager.setDectCallStatus(DectCallManager.IDLE)
					runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
					from dectConfig import MessageCode
					runtime.dectCallManager.cancelCall(MessageCode.LGN_Define.VIDEOPHONE_ANSWERED)
					runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)				

			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)

			runtime.SP_context.speaker.setStatus(Device.ON_HOOK)

			self.invite_reject()
			return True

		elif key == config.TS1_OFF_HOOK:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *TS1_OFF_HOOK* - in_progress=0')
			runtime.SP_context.dect1.setStatus(Device.OFF_HOOK)
			runtime.manager.kill_ringer()
			# 링 상태 종료 -->  SPEAKER close
			runtime.SP_context.goIdleState()
			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)
				
			# DECT1 연결
			ts1OffHook = runtime.SP_context.TS1_OffHook()
			if ts1OffHook.next():
				ts1OffHook.next()

			#self.after_ring = None
			self.answer_after_timer = None
			self.stop_ring_timer = None

			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, 	code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

			if self.media=='1':
				# 영상 통화 중에는 dect로 ring이 가지 않도록 정책이 변경되어 이 부분은 진행되지 않음.
				# runtime.manager.stack_stage(CallConnectingStage('incomingcall', self.media))
				pass
			else:
				runtime.manager.change_stage(IdleStage, True)
			status.set_call_time()
		elif key == config.TS2_OFF_HOOK:
			self.in_progress = 1
			roxia_event('IncomingCallStage.handle_key(), press *TS2_OFF_HOOK* - in_progress=0')
			runtime.manager.kill_ringer()
			runtime.SP_context.goIdleState()
			ts2OffHook = runtime.SP_context.TS2_OffHook()
			if ts2OffHook.next():
				ts2OffHook.next()
			
			#self.after_ring = None
			self.answer_after_timer = None
			self.stop_ring_timer = None

			runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
							code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)
			runtime.manager.stack_stage(IdleStage)
			status.set_call_time()
			
		return True

	def invite_reject(self, error=False, reject=False):
		runtime.mmiDebug.mmiTrace('IncomingCallStage::invite_reject')
		self.in_progress = 0
		if status.video_mode != status.AudioIncoming and status.video_mode != status.VideoIncoming:
			return

		#self.after_ring = None
		self.answer_after_timer = None
		self.stop_ring_timer = None
		
		runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
						code2=config.MESG_CALL_REJECT, \
						mesg1=config.REASON_TEMPORARILY_UNAVAILABLE)

		if runtime.dectCallManager.isSubcribedDect():
	 		runtime.dectCallManager.rejectCallByBase()

		if status.video_mode == status.VideoIncoming:
			if reject:
				status.video_call_time = 0
			else:
				status.video_call_time = ntptime.ntime() # for received call log
			runtime.manager.stop_video_call(error)
		else:
			if reject:
				status.call_time = 0
			else:
				status.call_time = ntptime.ntime() # for received call log
			runtime.manager.stop_audio_call(error)

	def invite_sucessed(self):
		print 'ka.....invite_sucessed'
		#if call_type == 0: #audio call
		#	stage = AudioCallConnectedStage(self.caller_name)
		#else:
		#stage = VideoCallConnectedStage
		stage = HMConnectedStage

		runtime.manager.change_stage(stage,True)


	def invite_error(self):
		self.in_progress = 0

		if status.video_mode != status.AudioIncoming:
			return

		message = 'video connecting failed'
		stage = VideoResultNotifyStage(message)
		runtime.manager.change_stage(stage)

		if status.video_mode == status.VideoIncoming:
			runtime.manager.stop_video_call(error)
		else:
			runtime.manager.stop_audio_call(True)

	def destroy(self):
		self.in_progress = 0
		#self.after_ring = None
		self.answer_after_timer = None
		self.stop_ring_timer = None
		self.play_ring_timer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)
		
	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)


		

class AudioCallConnectedStage(Stage):
	name = 'AudioCallConnected'
	def __init__(self, caller_name=''):
		roxia_event('AudioCallConnectedStage.__init__(), caller_name=', caller_name)
		status.AutoAnswering = False
		runtime.SP_context.setEqualizer()
		runtime.manager.set_videocall_mode(status.VideoCallConnected)
		status.set_video_mode(status.AudioConnected)
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected

		self.update_time_tag = 0
		self.softkey_timer = None
		self.volume_timer = None

		status.set_call_time()
		self.connect_start_time = ntptime.ntime()

		status.received_call_time = utils.make_call_time()

		status.phone_status = status.VoiceConnected

		status.save_current_call_status()
		self.exiting = False

		connected_number = status.display_caller_number(status.active_call_index)
		self.ui = ui.AudioCallConnectedUI(connected_number)

		#runtime.log.log('Audio call started')

		self.keyBuffer = ''

		self.hangup_after_timer = None
		self.test_hangup_after_timer = None
		
		self.micMuteFlag = False
		self.secondCallNumberTimer = None
		self.interceptAutoAnswer = False
		
		if status.KT_CALL_TESTER:
			def test_auto_Hangup():
				self.handle_key(config.Red)
				self.test_hangup_after_timer = None

			self.test_hangup_after_timer = utils.Timer(status.KT_CALL_TESTER.getCallDuration()*1000, test_auto_Hangup)
			
		baseCallStatus = runtime.SP_context.getBaseCallStatus()
		if setting.autoAnswer and baseCallStatus in [SP_Context.INCOMING_AUDIO, SP_Context.INCOMING_VIDEO] and not status.receiveCallInIncoming:
			def auto_Hangup():
				runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
										code2=config.MESG_AUTO_ANSWER_STOP)
				runtime.SP_context.SP_setMicEnable()
				#status.AutoAnswering = False
				runtime.manager.stage.handle_key(config.Red)

			currentAutoAnswerMessage = setting.autoAnswerMessage
			currentAutoAnswerFile = config.auto_answer_dir + currentAutoAnswerMessage
			status.AutoAnswering = True
			runtime.SP_context.SP_setMicDisable()
			runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
									code2=config.MESG_AUTO_ANSWER_PLAY, \
									mesg1=currentAutoAnswerFile, 
									mesg3=1)
			self.showAutoAnswering()
			self.hangup_after_timer = utils.Timer(uiconfig.AUTO_ANSWER_TIME, auto_Hangup)
		else:
			status.receiveCallInIncoming = False

	def showAutoAnswering(self):
		self.ui.showAutoAnswering()

	def autoHangupClose(self):
		runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
								code2=config.MESG_AUTO_ANSWER_STOP)
		runtime.SP_context.SP_setMicEnable()
		self.changeMessagePrefix()
		self.hangup_after_timer = None
		if self.interceptAutoAnswer:
			status.AutoAnswering = False
	
	def removeCallTest_CB(self):
		if self.test_hangup_after_timer:
			self.test_hangup_after_timer = None
		
	def stopCallDuration(self):
		self.ui.stopCallDuration()		

	def checkAndRemoveSecondCallNumber(self):
		if self.secondCallNumberTimer:
			self.ui.removeSecondCallNumber()
			self.secondCallNumberTimer = None
			
	def showSecondCallNumber(self, secondCallNumber):
		def removeSecondCallNumber_CB():
			self.ui.removeSecondCallNumber()
			self.ui.showInfoMessage()
			self.secondCallNumberTimer = None
		if self.secondCallNumberTimer:
			self.secondCallNumberTimer= None
		self.ui.showSecondCallNumber(secondCallNumber)
		self.secondCallNumberTimer = utils.Timer(uiconfig.SECOND_CALL_NUMBER_SHOW_TIME, removeSecondCallNumber_CB)

	def showThreeWayConference(self, firstCallNumber, secondCallNumber):
		self.ui.showThreeWayConference(firstCallNumber, secondCallNumber)

	def showCallWaiting(self, firstCallNumber, secondCallNumber, firstIsBusy=None):
		self.ui.showCallWaiting(firstCallNumber, secondCallNumber, firstIsBusy)

	def changeCallerInfo(self, callerNumber, changeMessage=False):
		self.ui.changeCallerInfo(callerNumber, changeMessage)
		
	def clearSecondCallNumberTimer(self):
		if self.secondCallNumberTimer:
			self.secondCallNumberTimer = None
		
	def changeConnectedNumber(self):
		self.ui.changeConnectedNumber()
		
	def changeMessagePrefix(self):
		self.ui.changeMessagePrefix()
		
	def showSoftkey(self):
		self.ui.showSoftkey()

	def hideSoftkey(self):
		self.ui.hideSoftkey()
		
	def end_call(self,error=False):
		roxia_event('AudioCallConnectedStage.end_call(), error=', error)
		self.stopCallDuration()
		runtime.manager.stop_audio_call(error)
		return False

	def end_call_by_red(self):
		roxia_event('AudioCallConnectedStage.end_call_by_red()')
		self.stopCallDuration()
		if status.modem_audio_state == status.SPK:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
# eicho add for warning 83.BB 06.10.26
		elif status.modem_audio_state == status.HS:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
# end.
		return False

	def end_call_by_onhook(self):
		roxia_event('AudioCallConnectedStage.end_call_by_onhook()')
		self.stopCallDuration()
		if status.modem_audio_state == status.HS:
			if not self.exiting:
				self.exiting = True
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				status.set_modem_audio_state(status.IDLE)
				dspg.set_state(dspg.ST_IDLE)
			return True
		return False

	def activate_menu1(self):
		roxia_event('AudioCallConnectedStage.activate_menu1()')
		runtime.vdciapp.send_hook_flash()
		return True		

	def handle_key(self, key):
		roxia_event('AudioCallConnectedStage.handle_key(), key=', key)
		def hide_softkey():
			self.softkey_timer = None
			self.hideSoftkey()
			return False
		def hide_volume():
			self.volume_timer = None
			self.hideVolume()
			return False

		# KA:[20081002] Base호 중 BANKING실행
		if self.softkey_timer == None and key in (config.Menu1, config.Menu2, 'Left', 'Right'):
		#if self.softkey_timer == None and key in (config.Menu1, config.Menu2, config.Menu3, config.Menu4):
			if not status.showSoftkeyFlag:
				return				
			self.volume_timer = None
			self.hideVolume()
			self.softkey_timer = utils.Timer(2000, hide_softkey)
			self.showSoftkey()
			return True
			
		# KA:[20081002] Base호 중 BANKING실행	
		#if key == 'Up':
		#	from eaHandler import EaHandler
		#	runtime.eaHandler.startBANKING()		
		# KA:[20081002] Base호 중 BANKING실행 ==

		if key in ('Up', 'Down'): # KA:[20081002] Base호 중 BANKING실행
		#if key in ('Right', 'Left'):
			if not status.showSoftkeyFlag:
				return

			self.softkey_timer = None
			self.hideSoftkey()
			if self.volume_timer == None:
				self.volume_control(first_flag=True)
				self.volume_timer = utils.Timer(3000, hide_volume)
				return True
			else:
				del(self.volume_timer)
				self.volume_timer = None
				self.volume_timer = utils.Timer(3000, hide_volume)
				pass
		
		if key in '0123456789#*':			
			runtime.vdciapp.send_dtmf(key)
			status.video_number_on = True
			if len(self.keyBuffer) >= 20:
				self.keyBuffer = self.keyBuffer[1:] + key
				pressedNumber = _('Input number') + ' : ' + self.keyBuffer
				self.ui.write_number(pressedNumber)
			else:
				self.keyBuffer += key
				pressedNumber = _('Input number') + ' : ' + self.keyBuffer
				self.ui.write_number(pressedNumber)			

		elif key == config.Menu2 or key == config.HookFlash:
			roxia_event('AudioCallConnectedStage.handle_key(), press *Menu2 or HookFlash*')
			self.activate_menu1()
			if self.micMuteFlag:
				runtime.SP_context.SP_setMicEnable()
				self.micMuteFlag = False
				self.ui.changeSoftkeyFlag(False)

		elif key == config.Menu1:
			if self.micMuteFlag:
				runtime.SP_context.SP_setMicEnable()
				self.micMuteFlag = False
				self.ui.changeSoftkeyFlag(False)
			else:
				runtime.SP_context.SP_setMicDisable()
				self.micMuteFlag = True
				self.ui.changeSoftkeyFlag(True)

		elif key == config.Menu4:
			from phonedb import phonedb
			if phonedb.is_empty():
				if self.ui.notify_timer:
					return
				self.ui.notify_msg_show(msg = _('Phonebook empty'))	
			else:
				runtime.manager.stack_stage(SearchStage(call_flag=True))
		elif key == 'Up': # KA:[20081002] Base호 중 BANKING실행
		#elif key == 'Right':
			roxia_event('AudioCallConnectedStage.handle_key(), press *Up*')
			self.volume_control(increase = True)

		elif key == 'Down': # KA:[20081002] Base호 중 BANKING실행
		#elif key == 'Left':
			roxia_event('AudioCallConnectedStage.handle_key(), press *Down*')
			self.volume_control(increase = False)

		elif key == config.Green:
			roxia_event('AudioCallConnectedStage.handle_key(), press *Green*')
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				if spkOffHook.next():
					if self.hangup_after_timer:
						self.autoHangupClose()
					if status.KT_CALL_TESTER:
						self.test_hangup_after_timer = None
				else:
					if spkOffHook.next():
						if self.hangup_after_timer:
							self.interceptAutoAnswer = True
							self.autoHangupClose()
						if status.KT_CALL_TESTER:
							self.test_hangup_after_timer = None
					else:
						spkOffHook.next() 
						# mic mute 상태 유지
						if self.micMuteFlag:
							runtime.SP_context.SP_setMicDisable()
						else:
							runtime.SP_context.SP_setMicEnable()
				
		elif key == config.Red:
			roxia_event('AudioCallConnectedStage.handle_key(), press *Red*')
			self.stopCallDuration()
			runtime.SP_context.goIdleState()

			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			self.exiting = True
			if self.hangup_after_timer:
				self.hangup_after_timer = None

		elif key == config.OnHook: 
			MD.mmiTrace('AudioCallConnectedStage.handle_key(), press *OnHook*')

			runtime.SP_context.handset.setStatus(Device.ON_HOOK)
			runtime.SP_context.handset.clearStatus()

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				currentDevices = hsOnHook.next()
				if not currentDevices:
					self.stopCallDuration()
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)

		elif key == config.OffHook:
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():

				# choinhwa:20081027 스트림 종료 후 사운드 패스 정리되도록
				if self.hangup_after_timer:
					self.interceptAutoAnswer = True
					self.autoHangupClose()
			
				hsOffHook.next()

				# mic mute 상태 유지
				if self.micMuteFlag:
					runtime.SP_context.SP_setMicDisable()
				else:
					runtime.SP_context.SP_setMicEnable()
				'''
				if self.hangup_after_timer:
					self.interceptAutoAnswer = True
					self.autoHangupClose()
				'''
				if status.KT_CALL_TESTER:
					self.test_hangup_after_timer = None

		elif key == config.Transfer:
			# [20080904_7] : hcryoo : [QE 29078] 음성호 통화중에 Second call착신도중 본체전환하여 본체응답시 LCD중첩됨
			if status.serviceStatusType in ['RB', 'BR', 'RW', 'WR']:
				return 
			# [20080904_7] : hcryoo : [QE 29078] 음성호 통화중에 Second call착신도중 본체전환하여 본체응답시 LCD중첩됨 ==

			# [20080904_2] : hcryoo : [QA 6-07] 2G로의 3인통화 시도시 전환을 하면 베이스의 영상 화면이 IDLE로 된다.	
			baseCallStatus, baseStatus, dectCallStatus, dectStatus = status.getCurrentCallStatus()
			if status.serviceStatusType in ['WB', 'BW'] and \
				baseCallStatus in [SP_Context.OUTGOING_VIDEO, SP_Context.INCOMING_VIDEO] and \
				dectStatus == DectCallManager.IDLE:
				return
			# [20080904_2] : hcryoo : [QA 6-07] 2G로의 3인통화 시도시 전환을 하면 베이스의 영상 화면이 IDLE로 된다.	==
				
			if runtime.dectCallManager.isSubcribedDect():
				self.stopCallDuration()
				if self.micMuteFlag:
					runtime.SP_context.SP_setMicEnable()
					self.micMuteFlag = False
					self.ui.changeSoftkeyFlag(False)
				runtime.manager.stack_stage(B2H_TransferStage)			
		else:
			roxia_event('AudioCallConnectedStage.handle_key(), press *...*')
			return False

		if key in (config.Green, config.OffHook):
			self.ui.update_soundpath()
			
		return True

#########################
# answer delay 수정분 - 06.06.09
#########################
	def set_callee_held(self):
		#status.waiting = 1
		#print '###model - set_callee_held'
		status.heldline = 1
		self.ui.set_connectedHeld_icon()
		# 06.07.06 Mr.Gun 
		runtime.evas.render_now()
		
	def cancel_callee_held(self):
		#print '###model - cancel_callee_held'
		status.heldline = 0
		self.ui.cancel_connectedHeld_icon()
	
	# 06.06.26
	def held_to_VideoCallconnected(self):
		#print '###AudioCallConnectedStage() / held_to_VideoCallconnected:'

		runtime.manager.set_videocall_mode(status.VideoCallConnecting)
		#self.ui.show()
		#runtime.evas.render_now()

		#self.connect_start_time = ntptime.ntime()
		#status.call_time = self.connect_start_time
		self.exiting = False
		self.remoteID = status.dial_number
		status.video_codec = status.AudioAndVideo
		status.save_current_call_status() # vpark-05.08.25
	
		#status.video_mode = status.VideoConnected
		status.video_mode = status.VideoIncoming
		# 06.07.06 Mr.Gun
		time.sleep(1)
		runtime.manager.change_stage(VideoCallConnectedStage,True)

	def hide(self):
		roxia_event('AudioCallConnectedStage.hide()')
		self.softkey_timer = None
		self.volume_timer = None
		self.hideVolume()
		utils.show_softkey()
		Stage.hide(self)
		
	def show(self):
		roxia_event('AudioCallConnectedStage.show()')
		self.softkey_timer = None
		Stage.show(self)
		self.hideSoftkey()

		runtime.mmiDebug.mmiTrace('status.serviceStatusType = ', status.serviceStatusType)		
		runtime.mmiDebug.mmiTrace('status.first_info_number = ', status.first_info_number)
		runtime.mmiDebug.mmiTrace('status.second_info_number = ', status.second_info_number)

		if status.serviceStatusType == 'BR':
			self.showSecondCallNumber(status.second_info_number)
		elif status.serviceStatusType == 'RB':
			self.showSecondCallNumber(status.first_info_number)
		elif status.serviceStatusType in ['BW', 'WB']:
			self.showCallWaiting(status.first_info_number, status.second_info_number)
		elif status.serviceStatusType == 'BB':
			self.showThreeWayConference(status.first_info_number, status.second_info_number)			

	def destroy(self):
		roxia_event('AudioCallConnectedStage.destroy()')

		if self.secondCallNumberTimer:
			self.secondCallNumberTimer = None

		if self.test_hangup_after_timer:
			self.test_hangup_after_timer = None
			
		if self.hangup_after_timer:
			self.hangup_after_timer = None
			runtime.vdci_send_mesg(code1=config.MESG_AUTO_ANSWER_INFO, \
									code2=config.MESG_AUTO_ANSWER_STOP)
			runtime.SP_context.SP_setMicEnable()
		utils.show_softkey()
		status.video_number_on = False
		self.tag_check_ppp = 0
		Stage.destroy(self)

	# KA: [20080514] call menu - volume
	def volume_control(self, first_flag=False, increase=True):
		self.ui.volume_control(first_flag, increase)
		
	def hideVolume(self):
		self.ui.hideVolume()
	# KA: [20080514] call menu - volume ==
	
	

class CallingStage(Stage):
	name = 'calling'
	def __init__(self, number, timeout=0, notPrefix=False):
		roxia_event('CallingStage.__init__(), number=', number, 'timeout=', timeout)
		if profile.ip_mode == 0:				# PSTN mode
			if setting.set_supplement_tde_prefix == 1:	# tde prefix enabled.

				if notPrefix == False:          # tde prefix enabled. but not adjust.
					number = config.FAC_TELEFONICA_PREFIX_CODE + number
		self.ui = ui.CallingUI2(number)
		self.ui.show()
		runtime.evas.render_now()
		self.dtmf_send_timer = None
		if timeout:
			def send_dtmf():
				self.dtmf_send_timer = None
				# PSTN mode && TdE prefix enabled.
				if profile.ip_mode == 0 and setting.set_supplement_tde_prefix == 1:
					if notPrefix == False:
						number = config.FAC_TELEFONICA_PREFIX_CODE + status.dial_number
					else:
						number = status.dial_number
					roxia_event('CallingStage.send_dtmf(), number=', number, '\n')
					dspg.send_dtmf(number, False)
				else:
					dspg.send_dtmf(status.dial_number, False)
				return False
			self.dtmf_send_timer = utils.Timer(timeout, send_dtmf)

	def handle_key(self, key):
		roxia_event('CallingStage.handle_key(), key=', key)

		if key in '0123456789#*':
			roxia_event('CallingStage.handle_key(), press *number*')
			status.dial_number += key
			self.ui.change_caller_number(status.dial_number)
			if not self.dtmf_send_timer:
				dspg.send_dtmf(key, True)

			return True
		return False
	def destroy(self):
		self.dtmf_send_timer = None
		Stage.destroy(self)

class CallProhibitStage(Stage):
	def __init__(self, message):
		roxia_trace('model.CallProhibitStage.__init__()')
		self.ui = ui.CallProhibitUI(message)
		def destroy():
			status.dial_number = ''
			if status.modem_audio_state == status.IDLE:
				runtime.manager.stop_call(IdleStage)
			else:
				if profile.ip_mode == 0:
					runtime.manager.stop_call(OffHookStage)
				else:
					status.dtmf_overlap_mode = False
					runtime.manager.stop_call(EnblockEditStage)

			self.timer = None
			return False

		self.timer = utils.Timer(2000, destroy)

	def destroy(self):
		self.timer = 0
		Stage.destroy(self)

	def handle_key(self, key):
		if key == config.Red:
			self.timer = None
			status.dial_number = ''
			runtime.manager.stop_call(IdleStage)
		return False

class CallLimitedStage(Stage):
	def __init__(self, number):
		self.ui = ui.CallLimitedUI(number)
		def destroy():
			status.dial_number = ''
			if status.modem_audio_state == status.IDLE:
				runtime.manager.stop_call(IdleStage)
			else:
				if profile.ip_mode == 0:
					runtime.manager.stop_call(OffHookStage)
				else:
					status.dtmf_overlap_mode = False
					runtime.manager.stop_call(EnblockEditStage)

			self.timer = None
			return False

		self.timer = utils.Timer(2000, destroy)

	def destroy(self):
		self.timer = 0
		Stage.destroy(self)
	def handle_key(self, key):
		if key == config.Red:
			self.timer = None
			status.dial_number = ''
			runtime.manager.stop_call(IdleStage)
		return False

class CallBarringStage(Stage):
	def __init__(self, number):
		self.ui = ui.CallBarringUI(number)
		def destroy():
			status.dial_number = ''
			runtime.mmedia.unload()
			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)
			runtime.manager.stop_call(IdleStage)			
			self.timer = None
			return False
		self.timer = utils.Timer(2000, destroy)

	def destroy(self):
		self.timer = 0
		Stage.destroy(self)

	def handle_key(self, key):
		if key == config.Red:
			self.timer = None
			status.dial_number = ''
			runtime.manager.stop_call(IdleStage)
		return False
		
	def align_center(self, l, pos):
		x, y = pos
		width,height = l.size
		l.move(x - width/2, y)

	def show(self):
		Stage.show(self)
		self.align_center(self.ui.message1, (240,137))

class EnblockEditStage(Stage):
	name = 'enblock edit'
	agenda_forbidden = True

	def __init__(self):
		roxia_event('EnblockEditStage.__init__()')

		if runtime.dectCallManager.isSubcribedDect():
			from dectConfig import MessageCode
			runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.COMMON_NOTIFICATION)
		
		self.ui = baseui.EnblockEditUI()
		status.dial_number = ''
		status.dialed_by_user = True

		if setting.screen_saver_enabled:
			status.not_screen_saver = True

		self.isFirstKey = True
		runtime.SP_context.SP_stereoStopPlayback()
		runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)	
		runtime.SP_context.startTonePlay()

		def gotoIdleStage():
			runtime.mmiDebug.mmiTrace('EnblockEditStage:: BACK TO IDLE STAGE')
			
			self.enblockStageTimer = None
			self.handle_key(config.Red)
		self.enblockStageTimer = utils.Timer(120*1000, gotoIdleStage)
		
	def destroy(self):
		runtime.SP_context.stopTonePlay()

		self.enblockStageTimer = None
		runtime.SP_context.setKeyTonePlaying(False)
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

	def handle_key(self, key):
		roxia_event('EnblockEditStage.handle_key(), key=', key)
		if key in '0123456789*#+':		
			if self.ui.isKeyFull():
				return
				
			if self.isFirstKey:
				runtime.SP_context.stopTonePlay()
				self.isFirstKey = False
			#runtime.SP_context.startTonePlay(commonTone=key)
			currentDevices = runtime.SP_context.getCurrentDevice()
			for currentDevice in currentDevices:
				if currentDevice in [SP_State.DEVICE_HS, SP_State.DEVICE_SPK]:
					runtime.SP_context.startKeyTonePlay(currentDevice, key, 65)

			status.set_dial_number(status.dial_number + key)

			from menu import CheckPasswordStage
			#KT management
#			if status.dial_number == '*147359*12358*':
			# Telio management fake
			if status.dial_number == '*159357*78952*':
				status.setClearCallStatus()
				stage = CheckPasswordStage
				runtime.manager.change_stage(stage)
				return
			elif status.dial_number == '*12358*123478956*' and config.test_menu:
				status.setClearCallStatus()
				stage = CheckPasswordStage(mode=2)
				runtime.manager.stack_stage(stage)
				return
			elif status.dial_number == '#963':
				if status.TEMP_MSG_CONDITION:
					status.TEMP_MSG_CONDITION = False
					print 'TEMP_MSG_CONDITION ==>> FALSE'
				else:
					status.TEMP_MSG_CONDITION = True
					print 'TEMP_MSG_CONDITION ==>> TRUE'
			##############
			if len(status.dial_number) < 2 or len(status.dial_number) > 13:
				self.ui.showKey(key)
			else:
				self.ui.showKey('')	# this routine is for conv_telnum()
			##############
			
			self.ui.set_right(_('AUDIO CALL'))
			self.ui.set_menu3(_('VIDEO CALL'))
			self.ui.set_menu4(_('CLEAR'))
			self.ui.set_left(_('SAVE'))
			
		# KA: [20080506] long key 처리 -speed dialing
		elif key.startswith('Long'):
			if len(status.dial_number) > 1:
				speed = status.dial_number[:-1] + key.split('Long')[1]
			else:				
				speed = key.split('Long')[1]
				
			if status.dial_number == '0'  and speed == '0':
				status.dial_number = ''
				self.ui.hideKey()
				self.handle_key('+')
			else:
				from phonedb import phonedb
				number = phonedb.get_speed_dial(speed)
				roxia_event('EnblockEditStage.Speed dial number =', number)
				if number:
					status.set_dial_number(number)
					runtime.manager.handle_key(True, config.Green)
				else:
					status.dial_number = ''
					runtime.manager.change_stage(NotifyStage(_('Speed dial empty'), uiconfig.baloon_phonebook_icon))
					return	
		# KA: [20080506] long key 처리 -speed dialing ==	
			
		elif key == config.Menu2:
			roxia_event('EnblockEditStage.handle_key(), press *Menu1*')
			self.enblockStageTimer = None
			
			if status.dial_number:
				return self.handle_key(config.Green)

			if setting.recent_number:
				status.dialed_by_user = False
				status.videocall_byuser = False
				runtime.manager.start_ip_call(setting.recent_number)		
			return True			
			#import calldb			
			#if calldb.is_empty('dialed'):
			#	return True				
			#detail = calldb.get_detail('dialed', 0)
			#status.dialed_by_user = False
			#runtime.SP_context.stopTonePlay()
			#status.videocall_byuser = False
			#runtime.manager.start_call(detail.number)
			#return True

		elif key == config.Menu3:
			roxia_event('EnblockEditStage.handle_key(), press *Menu2*')
			self.enblockStageTimer = None
			
			if status.dial_number:
				return self.handle_key(config.Video)
			if setting.recent_number:
				status.dialed_by_user = False
				status.videocall_byuser = False
				runtime.SP_context.stopTonePlay()				
				runtime.manager.start_ip_call(setting.recent_number, video_call=True)		
			return True				
			# REDIAL VIDEO
			#import calldb
			#if calldb.is_empty('dialed'):
			#	return True
			#detail = calldb.get_detail('dialed', 0)
			#status.dialed_by_user = False
			#runtime.SP_context.stopTonePlay()
			#runtime.manager.start_call(detail.number, video_call=True)
			
		elif key == config.Menu1:
			roxia_event('EnblockEditStage.handle_key(), press *Menu4*')
			# PHONEBOOK
			from phonedb import phonedb
			if self.ui.menu4 == _('SAVE'):
				import phonebook
				if phonedb.count() >= config.phone_db_size:
					stage = phonebook.PhonebookNotifyStage(_('Memory full'))
				elif len(status.dial_number) > 20:
					stage = phonebook.PhonebookNotifyStage(_('Max 20 characters exceeded'))
				else:
					stage = phonebook.AddPhoneBookStage(number = status.dial_number)
				runtime.manager.stack_stage(stage)
				return
			
			if phonedb.is_empty():
				runtime.manager.stack_stage(NotifyStage(_('Phonebook empty'), uiconfig.baloon_phonebook_icon))
				return
			runtime.manager.stack_stage(SearchStage(call_flag=True))

		elif key == config.CLEAR:			
			if self.ui.isKeyEmpty():
				return

			status.dial_number = status.dial_number[:-1]
			##############
			if len(status.dial_number) < 2 or len(status.dial_number) > 13:
				self.ui.hideKey()
			else:
				self.ui.showKey('')	# this routine is for conv_telnum()
			##############
			
			if not status.dial_number:
				self.handle_key(config.Red)					
					
		elif key == config.OffHook:
			roxia_event('EnblockEditStage.handle_key(), press *OffHook*')
			#return True
			self.enblockStageTimer = None
			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					tone = runtime.SP_context.speaker.getTone()
					runtime.SP_context.handset.setTone(tone)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
				elif SP_State.DEVICE_HSS1_TS1 in originalDevices:
					dectStatus = runtime.dectCallManager.getDectStatus()
					if dectStatus == DectCallManager.IDLE:
						runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
					else:
						runtime.SP_context.handset.setTone(config.PLAY_BUSY_TONE)				
				else:
					runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
					
				runtime.SP_context.startTonePlay()				

		elif key == config.OnHook:
			roxia_event('EnblockEditStage.handle_key(), press *OnHook*')
			self.enblockStageTimer = None

			hsOnHook = runtime.SP_context.HS_OnHook()
			if hsOnHook.next():
				originalDevices = hsOnHook.next()
				if originalDevices and not SP_State.DEVICE_HSS1_TS1 in originalDevices :
					MD.mmiTrace("EnblockEditStage : OnHook : Only Path Change.")
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				else:
					MD.mmiTrace("EnblockEditStage : OnHook : Stage closed.")
					status.dial_number = ''
					status.dialed_by_user = False

					runtime.mmedia.unload()
					
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
					runtime.manager.stop_call(IdleStage)
			else:
				MD.mmiTrace("EnblockEditStage : OnHook : Stage closed.")
				status.dial_number = ''
				status.dialed_by_user = False
				runtime.mmedia.unload()				
				runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
				runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
				runtime.manager.stop_call(IdleStage)			
					
		elif key == config.Red:
			roxia_event('EnblockEditStage.handle_key(), press *Red*')
			self.enblockStageTimer = None

			runtime.mmiDebug.mmiTodo('키톤이 enable된 경우에만 적용할 것.')
			runtime.mmedia.unload()
			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					MD.mmiTrace("EnblockEditStage : Red : Stop tone play and Stage clear.")
					for device in originalDevices:
						runtime.SP_context.stopTonePlay(device)

					status.dial_number = ''
					status.dialed_by_user = False

					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

					runtime.manager.stop_call(IdleStage)
				else:
					status.dial_number = ''
					status.dialed_by_user = False		
			else:
					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					

					runtime.manager.stop_call(IdleStage)
				
		elif key == config.LongMenu2:
			roxia_event('EnblockEditStage.handle_key(), press *LongMenu2*')
			self.remove_dtmf_timer()
			status.dial_number = ''
			self.ui.change_caller_number(status.dial_number)
			self.ui.set_left(_('REDIAL'))
			self.ui.set_right(_('PHONEBOOK'))
			self.ui.icon.file = uiconfig.image_dir + uiconfig.baloon_calling_icon[0]

		elif key == config.Green:
			roxia_event('EnblockEditStage.handle_key(), press *Green*')
			self.enblockStageTimer = None

			MD.mmiTrace('status.dial_number = ', status.dial_number)
			dectStatus = runtime.dectCallManager.getDectStatus()
			if status.dial_number and dectStatus == DectCallManager.IDLE:
				spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=True)
			else:
				spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
			if spkOffHook.next():
				if spkOffHook.next():
					if dectStatus == DectCallManager.IDLE:
						runtime.mmiDebug.mmiTrace('call start')
						#runtime.vdci_stop_tone()
						runtime.SP_context.stopTonePlay()
						if status.videocall_byuser:
							runtime.manager.start_call(number=status.dial_number, video_call=True)
						else:
							runtime.manager.start_call(number=status.dial_number, video_call=False)
					else:
						if dectStatus == DectCallManager.IDLE:
							runtime.SP_context.speaker.setTone(config.PLAY_DIAL_TONE)				
						else:
							runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
						runtime.SP_context.startTonePlay()								
				else:
					if spkOffHook.next():
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						if dectStatus == DectCallManager.IDLE:
							runtime.SP_context.speaker.setTone(config.PLAY_DIAL_TONE)				
						else:
							runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
						runtime.SP_context.startTonePlay()			

		elif key == config.Video:
			MD.mmiTrace('EnblockEditStage.handle_key(), press *Video*')
			self.enblockStageTimer = None

			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=True)
			if spkOffHook.next():
				spkOffHook.next()
				if status.dial_number:
					runtime.SP_context.setBaseCallStatus(SP_Context.OUTGOING_VIDEO)
					runtime.mmiDebug.mmiTrace('video call start')
					#runtime.vdci_stop_tone()
					runtime.SP_context.stopTonePlay()
					status.videocall_byuser = True
					'''
					if status.dial_number[:3] == '010':
						status.dial_number = '*' + status.dial_number
					'''
					runtime.manager.start_call(number=status.dial_number, video_call=True)
				else:
					return True
			else:
				return True
		elif key == 'Down':
			roxia_event('EnblockEditStage.handle_key(), press *Down*, run callhistory')
			#import phonebook
			#runtime.manager.stack_stage(phonebook.CallHistoryStage)
			import calldb, callhistory
			missed_lists = calldb.get_list('missed')
			dialed_lists = calldb.get_list('dialed')
			received_lists = calldb.get_list('received')
			if (len(missed_lists) == 0) and (len(dialed_lists) == 0) and (len(received_lists) == 0):
				stage = NotifyStage(_('Empty call history'), uiconfig.baloon_call_log_icon)
				runtime.manager.stack_stage(stage)
				return
			runtime.manager.stack_stage(callhistory.CallHistoryStage(call_type = 'recent', call_flag = True))	
		elif key == config.Menu4:
			if self.ui.isKeyEmpty():
				self.handle_key('Down')			
			else:
				self.handle_key('CLR')					
		else:
			roxia_event('EnblockEditStage.handle_key(), press *...*')
			return False
		return True

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
		Stage.show(self)
		
		try:   
			if '1' in open('/proc/driver/hook_sense').read():   
				hsOnHook = runtime.SP_context.HS_OnHook()
				if hsOnHook.next():
					originalDevices = hsOnHook.next()
					if originalDevices and not SP_State.DEVICE_HSS1_TS1 in originalDevices :
						MD.mmiTrace("EnblockEditStage : OnHook : Only Path Change.")
						runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
					else:
						MD.mmiTrace("EnblockEditStage : OnHook : Stage closed.")
						status.dial_number = ''
						status.dialed_by_user = False
						runtime.mmedia.unload()						
						runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
						runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
						runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
						runtime.manager.stop_call(IdleStage)
		except:   
			pass			
			
class StartCallStage(Stage):
	service_name = ''
	def __init__(self, number=None):
		if not number:
			number = self.number
		if self.service_name:
			status.service_name = self.service_name
		def start_call():
			runtime.manager.start_call(number)
			return False
		runtime.evas.idle_add(start_call)
		from baseui import BaseUI
		self.ui = BaseUI('','','')

class StartCallnotPrefixStage(Stage):
	service_name = ''
	def __init__(self, number=None):
		if not number:
			number = self.number
		if self.service_name:
			status.service_name = self.service_name
		def start_call():
			runtime.manager.start_call(number, notPrefix=True)
			return False
		runtime.evas.idle_add(start_call)
		from baseui import BaseUI
		self.ui = BaseUI('','','')

class IdleStage(Stage):
	name = 'idle'
	saveSettingTimer = None
	def __init__(self, vmStageRestore=False):
		runtime.SP_context.goIdleState(includingDect=False)	
		status.supervision_not_allowed = 0
		roxia_event('IdleStage.__init__()')
		self.ui = ui.IdleUI()
		status.dialed_by_user = False
		status.WhatFrom = status.from_none
		self.vmStageRestore = vmStageRestore
		# showing과 offhook이 동시에 내려 가는 것을 막기 위한 것.
		self.isShowing = False
#		if runtime.dectCallManager.isSubcribedDect():
#			from dectConfig import MessageCode
#			runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.IDLE)
		self.showingFlagTimer = None
		
	def onDoinit(self):
		if runtime.dectCallManager:
			dectStatus = runtime.dectCallManager.getDectStatus()
			if dectStatus == DectCallManager.CONNECTED:
				runtime.mmedia.unload()
				runtime.SP_context.SP_stereoStopPlayback()

		if status.get_regstatus() == 1 :
			if runtime.dectCallManager.isSubcribedDect():
				from dectConfig import MessageCode
				runtime.dectCallManager.sendStatusReportToDect(MessageCode.VP_STATUS.IDLE)				

		if runtime.eaHandler.isAppInUse():
			if status.missed_call_count > 0:
				stage = MissedIncomingCallStage(vm_flag = True)
				runtime.manager.change_stage(stage)
				return
			#if self.oninitFlag:
			runtime.mmiDebug.mmiTrace('=============>>> START endCall()')
			runtime.eaHandler.endCall()

		#RSS
		#runtime.manager.rss_manager.Rss_network_check()	


	def update_calendar(self):
		print '### IdleStage.update_calendar() called'
		self.ui.update_calendar()
		
	def handle_key(self, key):
		roxia_event('IdleStage.handle_key(), key=', key)

		if key == config.Menu3:
			print 'handle key'
			if config.global_version_flag:
				if setting.idle_style == 0:
					setting.set_idle_style(1)
				elif setting.idle_style == 1:
					setting.set_idle_style(2)
				# temporary blocked for global version by hdkim 20081030
				#elif setting.idle_style == 2:
				#	setting.set_idle_style(3)
				else:
					setting.set_idle_style(0)
				# print 'values ----->',setting.idle_style
				self.ui.update_calendar()
				print 'render'
				if self.saveSettingTimer:
					runtime.evas.timeout_remove(self.saveSettingTimer)
				self.saveSettingTimer = runtime.evas.timeout_add(5*1000, setting._save)
			else:
				if (status.get_regstatus_mmi() == 0) and (config.myann_test_flag == False):
					stage = NotifyStage(_('Please use after register to server'), icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					return
					
				cur_profile=profile.profile.get_profile()
				if (cur_profile == 1 and not runtime.peek_lanlink()) or \
							(cur_profile == 2 and not runtime.peek_wifilink()):	
					msg = _('Check network connection.')
					stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					return True
					
				if runtime.myannapp:
					import myannapp
					if not runtime.myannapp.is_running():
						runtime.manager.stack_stage(myannapp.MyAnnStage(config.HANGUL_URL))
						from eaHandler import EaHandler
						runtime.eaHandler.activateApplication_browser(destination=EaHandler.BROWSER)
				return
	
		if key == config.Menu1:
			roxia_event('IdleStage.handle_key(), press *Menu1*, run MainMenu')
			runtime.manager.stack_stage(MenuStage)
		elif key == config.Menu2:
			roxia_event('IdleStage.handle_key(), press *Menu2*, run Phonebook')
			import phonebook
			#stage = phonebook.get_phonebook_stage()
			stage = phonebook.PhoneBookStage
			runtime.manager.stack_stage(stage)
		elif key == config.Menu4 or key == config.MyAnn:
			if (status.get_regstatus_mmi() == 0) and (config.myann_test_flag == False):
				msg = _('Please use after register to server')
				stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
				runtime.manager.stack_stage(stage)
				return True
				
			cur_profile=profile.profile.get_profile()
			if (cur_profile == 1 and not runtime.peek_lanlink()) or \
						(cur_profile == 2 and not runtime.peek_wifilink()):	
				msg = _('Check network connection.')
				stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
				runtime.manager.stack_stage(stage)
				return True
			
			if runtime.myannapp:
				import myannapp
				if not runtime.myannapp.is_running():
					# 이벤트 속도보다 화면 전환 속도가 느려서...
					if runtime.eaHandler.isAppInUse():
						return	
					runtime.manager.stack_stage(myannapp.MyAnnStage(config.MY_SERVICE_HOME_URL))
#					runtime.manager.stack_stage(myannapp.MyAnnStage('http://news.bbc.co.uk/go/rss/-/1/hi/technology/7823387.stm'))
					from eaHandler import EaHandler
					runtime.eaHandler.activateApplication_browser(destination=EaHandler.BROWSER)		
		elif key == config.CLEAR and config.Rss_enable == True :
			#RSS test
			if runtime.manager.rss_manager.rss_feed != None : 
				url = runtime.manager.rss_manager.rss_feed['entries'][runtime.manager.rss_manager.rss_count]['link'].strip()
				print 'RSS test Web browser', url
				if (status.get_regstatus_mmi() == 0) and (config.myann_test_flag == False):
					msg = _('Please use after register to server')
					stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
					runtime.manager.stack_stage(stage)
					return True
				if runtime.myannapp:
					import myannapp
					if not runtime.myannapp.is_running():
						# 이벤트 속도보다 화면 전환 속도가 느려서...
						if runtime.eaHandler.isAppInUse():
							return	
							
						runtime.manager.stack_stage(myannapp.MyAnnStage(url))
						from eaHandler import EaHandler
						runtime.eaHandler.activateApplication_browser(destination=EaHandler.BROWSER)		
						return			

		elif key == config.Camera:
			from eaHandler import EaHandler
			runtime.eaHandler.startMediaPlayer()
		
		elif key in '0123456789*#':
			roxia_event('IdleStage.handle_key(), press *number*')
			# KA: [20080420] new register
			#if not status.get_regstatus_mmi():
			#	stage = RegiNotifyStage(_('Please use after register to server'))
			#	runtime.manager.stack_stage(stage)
			#	return True
			# KA: [20080420] new register
			import errorcode
			if not status.get_connection() or \
				errorcode.get_idle_errmsg() == errorcode.msg_M102 or \
				errorcode.get_idle_errmsg() == errorcode.msg_SR103:				
				stage = RegiNotifyStage(_('Please use after register to server'))
				runtime.manager.stack_stage(stage)
				return True			

			dectStatus = runtime.dectCallManager.getDectStatus()
			if dectStatus != DectCallManager.IDLE:
				spkOffHook = runtime.SP_context.SPK_OffHook()
				if spkOffHook.next():
					spkOffHook.next()

				runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
				runtime.SP_context.setBaseStatus(SP_Context.BUSY)
				runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				

				stage = InUseByDectStage()
				runtime.manager.change_stage(stage)
				
				return True

			status.dtmf_overlap_mode = False
			# default 발신을 뭘로 하나 ?
			runtime.SP_context.setBaseCallStatus(SP_Context.OUTGOING_AUDIO)
			runtime.SP_context.setBaseStatus(SP_Context.DIALING)
			runtime.SP_context.setKeyTonePlaying(True)

			runtime.mmiDebug.mmiTodo('키톤이 enable된 경우에만 적용할 것.')
			runtime.mmedia.unload()
			
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				spkOffHook.next()
			# tone  설정 없음.
			stage = EnblockEditStage()
			runtime.manager.stack_stage(stage)
			runtime.manager.handle_key(True, key)

#		elif key in ('Left', 'Right', 'Up', 'Down', 'OK'):
#			return True

		elif key == 'Left':
			roxia_event('IdleStage.handle_key(), press *Left*')

			msg = _('Sorry, we are preparing this service.')
			stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
			runtime.manager.stack_stage(stage)

			#from eaHandler import EaHandler
			##runtime.eaHandler.activateApplication(destination=EaHandler.MMSC)	
			#runtime.eaHandler.startMMSC()

		elif key == 'Right':
			roxia_event('IdleStage.handle_key(), press *Right*')
			from phonedb import phonedb
			if phonedb.is_empty():
				runtime.manager.stack_stage(NotifyStage(_('Phonebook empty'), uiconfig.baloon_phonebook_icon))
				return
			import phonebook
			runtime.manager.stack_stage(phonebook.SearchStage)

		elif key == 'Up':
			msg = _('Sorry, we are preparing this service.')
			stage = NotifyStage(msg, icon = uiconfig.video_call_connect_icon)
			runtime.manager.stack_stage(stage)

			# shchun: remove banking. 
		elif key == 'Down':
			roxia_event('IdleStage.handle_key(), press *Down*, run Phonebook')
			#import phonebook
			#runtime.manager.stack_stage(phonebook.CallHistoryStage)
			import calldb, callhistory
			missed_lists = calldb.get_list('missed')
			dialed_lists = calldb.get_list('dialed')
			received_lists = calldb.get_list('received')
			if (len(missed_lists) == 0) and (len(dialed_lists) == 0) and (len(received_lists) == 0):
				stage = NotifyStage(_('Empty call history'), uiconfig.baloon_call_log_icon)
				runtime.manager.stack_stage(stage)
				return
			runtime.manager.stack_stage(callhistory.CallHistoryStage('recent'))

		elif key in [config.Green, config.Video]:
			roxia_event('IdleStage.handle_key(), press Green, run Phonebook')
			# KA: [20080710] green key
			#import errorcode
			#if errorcode.get_idle_errmsg() ==  errorcode.msg_SR404 or \
			#	errorcode.get_idle_errmsg() == errorcode.msg_SR403:
			#	return True

			if key == config.Green:
				if not status.get_regstatus_mmi():
					runtime.manager.linkmonitor.restart_net_monitor(callnow=True)
					return True
			# KA: [20080710] green key ==

			if not(status.network_status == status.NetOk and status.get_regstatus() == 1):
				return True

			dectStatus = runtime.dectCallManager.getDectStatus()
			if dectStatus != DectCallManager.IDLE:
				spkOffHook = runtime.SP_context.SPK_OffHook()
				if spkOffHook.next():
					spkOffHook.next()
				runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
				
				runtime.SP_context.setBaseStatus(SP_Context.BUSY)
				runtime.SP_context.speaker.setTone(config.PLAY_BUSY_TONE)				
				runtime.SP_context.SP_stereoStopPlayback()				
				runtime.SP_context.dect1.clearTone()

				stage = InUseByDectStage()
				runtime.manager.change_stage(stage)
			else:
				import calldb, callhistory
				missed_lists = calldb.get_list('missed')
				dialed_lists = calldb.get_list('dialed')
				received_lists = calldb.get_list('received')
				if (len(missed_lists) == 0) and (len(dialed_lists) == 0) and (len(received_lists) == 0):
					stage = NotifyStage(_('Empty call history'), uiconfig.baloon_call_log_icon)
					runtime.manager.stack_stage(stage)
					return True
				runtime.manager.stack_stage(callhistory.CallHistoryStage('recent'))
			return True

		elif key == config.ASTERISK_4:
			roxia_event('IdleStage.handle_key(), press *4**')
				
			if profile.ip_mode == 1:
				return True

		elif key == config.Snapshot:
			roxia_event('IdleStage.handle_key(), press *Snapshot*')
			import mmtools
			stage = mmtools.MMToolsStage
			runtime.manager.stack_stage(stage)
		elif key == 'WEB':
			roxia_event('IdleStage.handle_key(), press *FAVORITES*')

			from elbrowser import WebNotAvailableNotifyStage, WebBrowserStage
			if profile.ip_mode == 0:
				stage = WebNotAvailableNotifyStage
			else:
				stage = WebBrowserStage
			runtime.manager.stack_stage(stage)

		elif key == config.Red:
			roxia_event('IdleStage.handle_key(), press *F6*')
		
		elif key == config.OffHook:
			runtime.mmedia.unload()
			# KA: [20080420] new register
			#if not status.get_regstatus_mmi():
			#	stage = RegiNotifyStage(_('Please use after register to server'))
			#	runtime.manager.stack_stage(stage)
			#	return True
			# KA: [20080420] new register
			if self.isShowing:
				return True
		
			utils.print_hw_debug('OFF-HOOK')
			if status.save_callback_other:
				self.emergency_save_other()

			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)

			dectStatus = runtime.dectCallManager.getDectStatus()
			if dectStatus == DectCallManager.IDLE:
				# default 발신을 뭘로 하나 ?
				MD.mmiTrace('SET BASE IN USE by HS OFF HOOK ***')
				runtime.SP_context.setBaseCallStatus(SP_Context.OUTGOING_AUDIO)
				runtime.SP_context.setBaseStatus(SP_Context.DIALING)
				runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
				runtime.SP_context.SP_stereoStopPlayback()				
				runtime.manager.handle_call_action(config.OffHook)
			else:
				runtime.SP_context.setBaseStatus(SP_Context.BUSY)
				runtime.SP_context.handset.setTone(config.PLAY_BUSY_TONE)
				runtime.SP_context.SP_stereoStopPlayback()				
				runtime.SP_context.dect1.clearTone()

				stage = InUseByDectStage()
				runtime.manager.change_stage(stage)
		elif key == config.Transfer:
			roxia_event('IdleStage.handle_key(), press *TRNSFER*')
			if runtime.dectCallManager.isSubcribedDect():
				dectStatus = runtime.dectCallManager.getDectStatus()
				if dectStatus == DectCallManager.IDLE:
					from phonesetting import DectPagingStage
					runtime.manager.stack_stage(DectPagingStage)		
		else:
			roxia_event('IdleStage.handle_key(), press *...*')
			if config.key_debug:
				print 'idle stage key:', key
			return False
		return True


	def handle_mwi_waiting(self):
		roxia_event('IdleStage.handle_mwi_waiting()')
		self.ui.set_mwi_waiting(setting.mwi_waiting)

	def handle_msg_waiting(self):
		roxia_event('IdleStage.handle_msg_waiting()')
		self.ui.set_msg_waiting(setting.msg_waiting)

	def hide(self):
		runtime.day.hide()
		Stage.hide(self)

	def destroy(self):
		#RSS
		#print 'idle destroy'

		self.showingFlagTimer = None
		Stage.destroy(self)
		
	def show(self):
		if self.vmStageRestore:
			return
		self.ui.show()
		self.onDoinit()
		def clearShowingFlag():
			self.isShowing = False
			self.showingFlagTimer = None
		self.isShowing = True
		self.showingFlagTimer = utils.Timer(100, clearShowingFlag)
		
		if not runtime.timer.hidden:
			runtime.day.show()

		if runtime.manager.back:
			pass
			
		if runtime.eaHandler.isAppInUse():
			#print 'ka..........APP in use: dont check OffHook'
			return

		if status.mms_notify_exist:
			runtime.manager.stage.SMS_Notify_free()
			return True

		# syncML check
		if setting.sync_complete != 0:
			import phonebook
			stage = phonebook.SyncStage(error=True)
			runtime.manager.change_stage(stage, True)
			return
			
		if status.missed_call_count > 0:
			stage = MissedIncomingCallStage
			runtime.manager.stack_stage(stage)
			return
			
		# KA: [20080420] new register	
		#if not status.get_regstatus_mmi():
		#	return
			
		try:   
			if '0' in open('/proc/driver/hook_sense').read():   
				if runtime.vdciapp:
					MD.mmiTrace('OFF HOOK START ----------')
					runtime.mmedia.unload()
					hsOffHook = runtime.SP_context.HS_OffHook()
					if hsOffHook.next():
						hsOffHook.next()
						dectStatus = runtime.dectCallManager.getDectStatus()
						if dectStatus == DectCallManager.IDLE:
							runtime.SP_context.handset.setTone(config.PLAY_DIAL_TONE)				
						else:
							runtime.SP_context.handset.setTone(config.PLAY_BUSY_TONE)					

					dectStatus = runtime.dectCallManager.getDectStatus()
					self.isShowing = False
					if dectStatus == DectCallManager.IDLE:
						status.dtmf_overlap_mode = False
						runtime.manager.stack_stage(EnblockEditStage)
					else:
						stage = InUseByDectStage()
						runtime.manager.stack_stage(stage)

			else:
				if runtime.dectCallManager.isSubcribedDect():
					runtime.mmiDebug.mmiTrace('IdleStage:VP_STATUS REPORT')

		except:   
			pass			

		self.isShowing = False
		
class IncomingStage(Stage):
	name = 'incoming'
	agenda_forbidden = True
	def __init__(self):
		snapshot = None
		caller_name = ''
		#ka...CLIP name 2006.11.06
		status.caller_CLIP_name = ''
		
		if status.received_name != None and status.caller_number not in ('P', 'O'):
			if status.caller_number:
				caller_name = status.received_name + ' ' + '(' + status.caller_number +')' 
				caller_name = utils.resize_text(caller_name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]
				from phonedb import phonedb
				snapshot = phonedb.get_snapshot(status.caller_number)
				if snapshot:
					# 알 수 없는 이유로 인해 파일이 존재 하지 않을때
					if not os.access(snapshot, os.R_OK):
						snapshot = None
			else:
				caller_name = status.received_name
			status.caller_CLIP_name = caller_name
		else:
			if status.caller_number:
				from phonedb import phonedb
				caller_name = phonedb.get_name(status.caller_number)
				caller_name = utils.resize_text(caller_name, uiconfig.incoming_call_text_width, uiconfig.incoming_call_font)[0]
				snapshot = phonedb.get_snapshot(status.caller_number)
				if snapshot:
					# 알 수 없는 이유로 인해 파일이 존재 하지 않을때
					if not os.access(snapshot, os.R_OK):
						snapshot = None
			else:
				caller_name = _('Unknown')
				
		self.ui = ui.IncomingUI(caller_name, snapshot, reject_on=False)

		# ring disable, filter 동작시에는 play 중이 아니다,[
		# 그때에는 mute 버튼 보이지 않게 한다
		if not utils.player.playing():
			self.ui.set_left('')

	def handle_key(self, key):


		if key == config.Green:
			utils.print_hw_debug('ON-HOOK')

			runtime.manager.kill_ringer()
			status.set_modem_audio_state(status.SPK)
			dspg.set_state(dspg.ST_SPK_OFFHK)
			runtime.manager.answer_call()
			return True

		elif key == config.OffHook:
			utils.print_hw_debug('OFF-HOOK')
			runtime.manager.kill_ringer()
			status.set_modem_audio_state(status.HS)
			dspg.set_state(dspg.ST_HS_OFFHK)
			runtime.manager.answer_call()
			return True

		elif key == config.Red:
			if config.key_debug:
				print 'Incoming: ignore red key'
			return True

		elif key == config.Menu1:
			if config.ring_debug:
				print 'Ring Mute'
			utils.player.stop()
			self.ui.set_left('')
			return True

		elif key == config.Menu2:
			# do nothing
			return True
			# REJECT
			if config.key_debug:
				print 'reject call'
		return False

	def destroy(self):
		Stage.destroy(self)

class IncomingMissedCallNoCIDStage(Stage):
	def __init__(self):
		icon = uiconfig.baloon_call_log_icon
		if status.missed_call_count == 1:
			message = _('1 missed call')
		else:
			message = '%d ' % status.missed_call_count + \
				_('missed calls')

		self.ui = baseui.BaloonMessageUI('', _('EXIT'), '', icon, message)

	def handle_key(self, key):
		# eicho modify 06.04.12
		if status.screensaver_activated == True:
			setting.reset_screen_saver_timer()
			return True
		if key == config.Menu2:
			runtime.manager.change_stage(IdleStage, True)
			status.missed_call_count = 0
			return True
		return False

class IncomingSMSStage_KT(Stage):
	name  = 'incoming_sms'
	def __init__(self, message):
		from smsmanager import smsmgr
		self.mNotificationIndSms = message
		
		num_sms = smsmgr.count_unread()
		icon = uiconfig.baloon_message_icon
		self.ui = ui.IncomingSMSUI(num_sms, icon)
		self.ui.show_bg = True

	def update_num_sms(self):
		from smsmanager import smsmgr
		num_sms = smsmgr.count_unread()
		self.ui.set_num_sms(num_sms)

		icon = uiconfig.baloon_message_icon

		icon_name, pos = icon
		self.ui.remove(self.ui.icon)
		self.ui.icon = utils.put_image(icon_name, pos)
		self.ui.add(self.ui.icon)

		if config.message_entry_max <= smsmgr.count_received():
			self.ui.remove(self.ui.icon)
			icon_name, pos = uiconfig.idle_icon_messagefull
			self.ui.icon = utils.put_image(icon_name, pos)
			self.ui.add(self.ui.icon)

	def handle_key(self, key):
		if key == config.Menu1:
			from smsstage import SMSListStage
			runtime.manager.change_stage(SMSListStage)
		elif key == config.Menu2:
			runtime.manager.back_stage()
		else:
			return self.ui.handle_key(key)
		return True

class IncomingSMSStage(Stage):
	name  = 'incoming_sms'
	def __init__(self):
		from smsmanager import smsmgr
		num_sms = smsmgr.count_unread()
		if setting.incoming_sms_type == 'status report':
			icon = uiconfig.baloon_notify_message_icon
		elif setting.incoming_sms_type == 'ems':
			icon = uiconfig.baloon_ems_icon
		else:
			icon = uiconfig.baloon_message_icon
		self.ui = ui.IncomingSMSUI(num_sms, icon)
		self.ui.show_bg = True

	def update_num_sms(self):
		from smsmanager import smsmgr
		num_sms = smsmgr.count_unread()
		self.ui.set_num_sms(num_sms)

		if setting.incoming_sms_type == 'status report':
			icon = uiconfig.baloon_notify_message_icon
		elif setting.incoming_sms_type == 'ems':
			icon = uiconfig.baloon_ems_icon
		else:
			icon = uiconfig.baloon_message_icon
		icon_name, pos = icon
		self.ui.remove(self.ui.icon)
		self.ui.icon = utils.put_image(icon_name, pos)
		self.ui.add(self.ui.icon)

		if config.message_entry_max <= smsmgr.count():
			self.ui.remove(self.ui.icon)
			icon_name, pos = uiconfig.idle_icon_messagefull
			self.ui.icon = utils.put_image(icon_name, pos)
			self.ui.add(self.ui.icon)

	def handle_key(self, key):
		if key == config.Menu1:
			from smsstage import SMSListStage
			runtime.manager.change_stage(SMSListStage)
		elif key == config.Menu2:
			runtime.manager.back_stage()
		else:
			return self.ui.handle_key(key)
		return True

class MaintenanceMessageStage(Stage):
	def __init__(self, message):
		self.ui = ui.MaintenanceMessageUI(message)

	def handle_key(self, key):
		self.last_key = key
		return True

class StorageShortStage(NotifyStage):
	def __init__(self, icon=None):
		message = _('Storage is short')
		if not icon:
			icon = uiconfig.baloon_phone_setting_icon
		NotifyStage.__init__(self, message, icon)

class SMSReceivingStage(Stage):
	name = 'smsreceivingstage'
	agenda_forbidden = True
	def __init__(self):
		message = _('SMS receiving...')
		icon = uiconfig.baloon_message_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.got_error = False
		self.next_stage = None

	def clear(self, mmsnotireceived, smsreceived):
		status.incoming_sms = False
		self.destroy_tag = None
		if self.got_error:
			runtime.manager.back_stage()
			return False

		if config.stage_debug:
			print 'stage name = ', runtime.manager.stage.name
		if self.next_stage:
			runtime.manager.change_stage(self.next_stage)
			return False


		if False == mmsnotireceived and False == smsreceived:
			runtime.manager.back_stage()
			return False

		if mmsnotireceived:
			if smsreceived:
				s = runtime.manager.find_stage('incoming_sms')
				if s: s.update_num_sms()
			if setting.mms_retrieval:
				runtime.manager.change_stage(MMS_Downloading_Stage)
			else:
				pop = runtime.manager.pop_stage()
				if pop.name == 'idle':
					from mms_net_sendstage import IncomingMMSStage
					runtime.manager.change_stage(IncomingMMSStage, True)
					return False
				runtime.manager.change_stage(pop)
				if pop.name == 'incoming_mms':
					pop.update_num_mms()
				else:
					s = runtime.manager.find_stage('incoming_mms')
					if s: s.update_num_mms()
				return False

			return False

		if smsreceived:
			pop = runtime.manager.pop_stage()
			if pop.name == 'idle':
				runtime.manager.change_stage(IncomingSMSStage, True)
				return False
			runtime.manager.change_stage(pop)
			if pop.name == 'incoming_sms':
				pop.update_num_sms()
			else:
				s = runtime.manager.find_stage('incoming_sms')
				if s: s.update_num_sms()
			return False


	def handle_key(self, key):
		if key == config.OffHook:
			return False
		if config.key_debug:
			print 'SMSReceivingStage: ignore this key', key
		return True # Ignore all key

class PhoneListBase(ListStage):
	def __init__(self, focus):
		self.phonedb_indexes, choice = self.get_phonelist()
		if self.isemergency():
			self.phonedb_indexes.insert(0,-1)
			choice.insert(0,_('Emergency(112)'))
		ListStage.__init__(self, choice)
		if len(choice) == 0:
			return
		# focus를 맨 위로 보내기위해서
		if type(focus) == type(''):
			if focus:
				from phonedb import phonedb
				if self.isemergency():
					focus = phonedb.find_by_name_near(focus, self.phonedb_indexes[1:])
				else:
					focus = phonedb.find_by_name_near(focus, self.phonedb_indexes)
				if self.isemergency():
					focus += 1
			else:
				focus = 0
		self.ui.set_focus(-1)
		self.ui.set_focus(focus)
		self.last_digit = '0'
#		assert status.editing_phone_number_index < 0
		# RHC / [20060819_1]
		#status.editing_phone_number_index = self.phonedb_indexes[self.ui.get_focus()]
		if self.phonedb_indexes:
			status.editing_phone_number_index = self.phonedb_indexes[self.ui.get_focus()]
		# RHC / [20060819_1]--

		# for update icon columns
		self.refresh_lists(False)

	def show(self):
		ListStage.show(self)
		# RHC / [20060819_1]
		#status.editing_phone_number_index = self.phonedb_indexes[self.ui.get_focus()]
		if self.phonedb_indexes:
			status.editing_phone_number_index = self.phonedb_indexes[self.ui.get_focus()]
		# RHC / [20060819_1]--

	def isemergency(self):
		return False

	def get_phonelist(self):
		# should return phonedb index list and ui string
		#assert False
		pass

	def get_phonedb_item(self, index):
		from phonedb import phonedb
		return phonedb.get_item(self.phonedb_indexes[index])

	def refresh_lists(self, reset_index=True):
		if reset_index:
			self.phonedb_indexes, choice = self.get_phonelist()
			if self.isemergency():
				self.phonedb_indexes.insert(0,-1)
				choice.insert(0,_('Emergency(112)'))
			if len(self.phonedb_indexes) > 0:
				self.change_choice(choice)
				status.editing_phone_number_index = self.phonedb_indexes[0]
		self.ui.remove_all_icon_columns()

		num_icons = []
		mob_icons = []
		email_icons = []
		fax_icons = []

		if self.isemergency():
			num_icons.append(uiconfig.list_icon_small_normal)
			mob_icons.append(None)
			email_icons.append(None)
			fax_icons.append(None)

		from phonedb import phonedb
		if self.isemergency():
			phdb_index = self.phonedb_indexes[1:]
		else:
			phdb_index = self.phonedb_indexes

		for i in phdb_index:
			db = phonedb.get_item(i)
			if db.number:
				if db.call_type=='1':
					num_icons.append(uiconfig.list_icon_small_videocall)
				elif db.call_type=='2':
					num_icons.append(uiconfig.list_icon_small_normal_int)
				elif db.call_type=='3':
					num_icons.append(uiconfig.list_icon_small_videocall_int)
				else:
					num_icons.append(uiconfig.list_icon_small_normal)
			else:
				num_icons.append(None)

			if db.mobile:
				mob_icons.append(uiconfig.list_icon_small_mobile)
			else:
				mob_icons.append(None)

			if db.email:
				email_icons.append(uiconfig.list_icon_small_email)
			else:
				email_icons.append(None)

			if db.fax:
				fax_icons.append(uiconfig.list_icon_small_fax)
			else:
				fax_icons.append(None)

		self.ui.create_icon_column( uiconfig.pb_list_icon_num_x, num_icons)
		self.ui.create_icon_column( uiconfig.pb_list_icon_mob_x, mob_icons)
		self.ui.create_icon_column( uiconfig.pb_list_icon_email_x, email_icons)
		self.ui.create_icon_column( uiconfig.pb_list_icon_fax_x, fax_icons)

		if not reset_index:
			# focus가 0이아닌 경우 Icon column의 top index를 sync시켜주어야한다.
			self.ui.list.update_icon_index()

	def handle_key(self, key):
		if key in '23456789':
			a_lists = {'2':'abc', '3':'def', '4':'ghi',
				'5':'jkl', '6':'mno', '7':'pqrs', '8':'tuv', '9':'wxyz'}
			alphabet = a_lists[key]
			if self.last_digit in alphabet:
				i = alphabet.find(self.last_digit) + 1
				if i >= len(alphabet):
					i = 0
				self.last_digit = alphabet[i]
			else:
				self.last_digit = alphabet[0]


			from phonedb import phonedb
			if self.isemergency():
				focus = phonedb.find_by_char(self.last_digit, self.phonedb_indexes[1:])
			else:
				focus = phonedb.find_by_char(self.last_digit, self.phonedb_indexes)
			if focus >= 0:
				if self.isemergency():
					status.editing_phone_number_index = self.phonedb_indexes[focus+1]
				else:
					status.editing_phone_number_index = self.phonedb_indexes[focus]
				if self.isemergency():
					self.ui.set_focus(focus+1)
				else:
					self.ui.set_focus(focus)
			self.show()
			return True
		ret = ListStage.handle_key(self, key)
		if key in ('Up', 'Down'):
			status.editing_phone_number_index = self.phonedb_indexes[self.ui.get_focus()]
		return ret

	def destroy(self):
		ListStage.destroy(self)
		status.editing_phone_number_index = -1

class B2H_TransferStage(Stage):
	name = 'B2H_Transfer'
	agenda_forbidden = True

	TRANSFER_TIMEOUT = 40*1000 # 40 second
	def __init__(self):
		MD.mmiTrace('B2H_Transfer.__init__()')

		# send message to dect
		runtime.dectCallManager.setDectStatus(DectCallManager.TRANSFER_RINGING)
		#runtime.SP_context.setBaseStatus(SP_Context.TRANSFER_RINGING)
		
		callerNumber = status.display_caller_number(status.active_call_index)
		callerName = status.display_caller_name(status.active_call_index)
		runtime.SP_context.SP_setMicDisable()
		self.setAudioRxMute()
		runtime.dectCallManager.start_B2H_Transfer(callerName, callerNumber)
		runtime.dectCallManager.playTransferMoh()
		runtime.SP_context.startTonePlay(commonTone=config.PLAY_RINGBACK_TONE)	

		#hangleMessage = '전환중입니다.'
		#message = unicode(hangleMessage, 'euc-kr').encode('utf-8')
		#self.ui = baseui.TransferUI(_('CANCEL'), '', '', '', message)
		self.ui = baseui.TransferUI('', '', '', _('CANCEL'), _('Transfering to handy'))

	def setAudioRxMute(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
					code2=config.MESG_SET_AUDIO_MUTE, \
					mesg1=1, mesg2=1)

	def setAudioRxUnmute(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
					code2=config.MESG_SET_AUDIO_MUTE, \
					mesg1=0, mesg2=1)

	def startTransferTimer(self):
		def transferTimeout_callback():
			self.transferCancelledByBase()
			self.transferTimer = None
			runtime.manager.back_stage()		
		self.transferTimer = utils.Timer(self.TRANSFER_TIMEOUT, transferTimeout_callback)
	
	def clearTransferTimer(self):
		self.transferTimer = None
		
	def transferCancelledByDectBusy(self):
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		runtime.SP_context.stopTonePlay()
		
		stage = NotifyStage(_('Dect in use.'), uiconfig.baloon_phonebook_icon)
		runtime.manager.change_stage(stage)

	def transferCancelledByBase(self):		
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.stopTonePlay()

		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()

		# [20080904_3] : hcryoo : [QA 6-16] BS 음성 통화 중 모드 전환 후 전환 취소하면 아이콘 상태 불일치함.
		runtime.SP_context.setPhysicalDevice()
		# [20080904_3] : hcryoo : [QA 6-16] BS 음성 통화 중 모드 전환 후 전환 취소하면 아이콘 상태 불일치함. ==

		from dectConfig import MessageCode
		runtime.dectCallManager.cancelCall(MessageCode.Normal.NORMAL_RELEASE)

		runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
	
	def handle_key(self, key):
		MD.mmiTrace('B2H_TransferStage.handle_key(), key=', key)
		if key == config.Menu4 or key == config.CLEAR:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *Menu4*')
			self.transferCancelledByBase()
			runtime.SP_context.SP_stereoStopPlayback()
			runtime.manager.back_stage()
			
			return True
					
		elif key == config.Red:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *Red*')

			redPressed = runtime.SP_context.RED_Pressed()
			if redPressed.next():
				originalDevices = redPressed.next()
				if originalDevices:
					self.transferCancelledByBase()
					stage = runtime.manager.find_stage('AudioCallConnected')
					if stage:
						stage.stopCallDuration()
						
					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)
					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					#runtime.SP_context.goIdleState()

					status.video_mode = status.AudioDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_audio_call(with_error=False)
			else:
				MD.mmiTrace("DirectAudioCallingStage : Red : ERROR CASE.")
					
			return True

		elif key == config.OnHook:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *OnHook*')

			hsOnHook = runtime.SP_context.HS_OnHook()
			# [20080908_1] : hcryoo : 그룹 콜에서 전환 후 HS off hook 하고 바로 전환 취소 시 mute 발생하는 오류 수정
			if hsOnHook.next():
				currentStateName = runtime.SP_context.getCurrentStateName()
				if currentStateName in ['SP_HS_OffHook_SPK_OffHook','SP_HS_OffHook_SPK_OffHook_TS1_OffHook']:		
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)
				else:
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)
				originalDevices = hsOnHook.next()
				if originalDevices and SP_State.DEVICE_SPK in originalDevices:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Only Path Change.")
					# [20080919_1]: hcryoo : 통화 전환 중 mute 발생
					runtime.SP_context.speaker.setTone(config.PLAY_RINGBACK_TONE)				
					runtime.SP_context.startTonePlay()	
					# [20080919_1]: hcryoo : 통화 전환 중 mute 발생==
				else:
					MD.mmiTrace("DirectAudioCallingStage : OnHook : Stage closed.")

					self.transferCancelledByBase()

					#runtime.SP_context.stopTonePlay(SP_State.DEVICE_HS)

					runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
					runtime.SP_context.setBaseStatus(SP_Context.IDLE)					
					# dect 상태를 고려하지 않아도 됨. --> 어차피 cancel된 상태이므로...
					runtime.SP_context.goIdleState()

					status.video_mode = status.AudioDisconnected
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					runtime.manager.stop_audio_call(with_error=False)
			# [20080908_1] : hcryoo : 그룹 콜에서 전환 후 HS off hook 하고 바로 전환 취소 시 mute 발생하는 오류 수정==
					
			return True
			
		elif key == config.OffHook:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *OffHook*')

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				originalDevices = hsOffHook.next()
				if SP_State.DEVICE_SPK in originalDevices:
					runtime.SP_context.stopTonePlay(SP_State.DEVICE_SPK)

					runtime.SP_context.handset.setTone(config.PLAY_RINGBACK_TONE)				
					runtime.SP_context.startTonePlay()		
					# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림
					runtime.SP_context.SP_setMicDisable()
					# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림==

			return True

		elif key == config.Green:
			MD.mmiTrace('DirectVideoCallingStage.handle_key(), press *Green*')
			dectStatus = runtime.dectCallManager.getDectStatus()
			spkOffHook = runtime.SP_context.SPK_OffHook(dialNumber=False)
			if spkOffHook.next():
				if spkOffHook.next():
					pass
				else:
					if spkOffHook.next():
						pass
					else:
						spkOffHook.next() # SP_HS_OffHook_SPK_OffHook 상태를 위한 것.
						#tone = runtime.SP_context.handset.getTone()
						runtime.SP_context.speaker.setTone(config.PLAY_RINGBACK_TONE)
						runtime.SP_context.startTonePlay()	
						# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림
						runtime.SP_context.SP_setMicDisable()
						# [20080904_5] : hcryoo : [QA 28146] 음성발신한 단말기 HS로 전환하는 중에도 마이크가 열려 있어 상대방은 MOH와 말소리가 같이 들림==
			return True			
						
		elif key == config.TS1_OFF_HOOK:
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			self.setAudioRxUnmute()
			runtime.SP_context.stopTonePlay()
			runtime.SP_context.goIdleState()
			runtime.SP_context.setBaseCallStatus(SP_Context.IDLE)
			runtime.SP_context.setBaseStatus(SP_Context.IDLE)
			runtime.dectCallManager.openPcmChannel(1)

			runtime.manager.change_stage(IdleStage, True)
		else:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *...*')

		return True

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
			
		Stage.show(self)

	def destroy(self):
		self.transferTimer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

class H2B_TransferStage(Stage):
	name = 'H2B_Transfer'
	agenda_forbidden = True

	TRANSFER_TIMEOUT = 40*1000 # 40 second
	SUCCESS = 0
	FAILURE = 1
	
	def __init__(self, handsetNumber):
		MD.mmiTrace('H2B_Transfer.__init__()')		
		# slide show 중 일 경우.
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False

		# receive message from dect
		#runtime.dectCallManager.setDectStatus(DectCallManager.TRANSFER_RINGING)
		runtime.SP_context.setBaseStatus(SP_Context.TRANSFER_RINGING)
		self.callerNumber = status.display_caller_number(status.active_call_index)
		self.callerName = status.display_caller_name(status.active_call_index)
		#runtime.dectCallManager.closePcmChannel(1)
		runtime.dectCallManager.playTransferMoh()
		runtime.SP_context.SP_setMicDisable()
		self.setAudioRxMute()
		
		# start RING
		self.ringTimer = utils.Timer(1*1000, self.startTransferRinging)		

		self.ui = baseui.TransferUI('', '', '', '', _('Call transferring...'))

	def setAudioRxMute(self):
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
						code2=config.MESG_SET_AUDIO_MUTE, \
						mesg1=1, mesg2=1)

	def setAudioRxUnmute(self):
			runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
						code2=config.MESG_SET_AUDIO_MUTE, \
						mesg1=0, mesg2=1)

	def  startTransferRinging (self):
		self.ringTimer = None
		runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
		spkOffHook = runtime.SP_context.SPK_OffHook()
		if spkOffHook.next():
			spkOffHook.next()
				
		runtime.SP_context.SP_playWav(SP_State.DEVICE_SPK, config.transferMOH2, True)
		
	def stopTransferRinging(self):
		runtime.SP_context.speaker.setStatus(Device.ON_HOOK)
		spkOnHook = runtime.SP_context.SPK_OnHook()
		if spkOnHook.next():
			spkOnHook.next()

		runtime.SP_context.SP_stopWav()
		
	'''
	def startTransferRinging(self):
		#spkOffHook = runtime.SP_context.SPK_OffHook()
		#if spkOffHook.next():
		#	spkOffHook.next()
		#runtime.SP_context.SP_startPlayback()
		#runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
		runtime.SP_context.setBaseStatus(SP_Context.TRANSFER_RINGING)
		utils.player.play_ring(runtime.manager.get_melody())

	def stopTransferRinging(self):
		runtime.manager.kill_ringer()
		#runtime.SP_context.SP_stopPlayback()	
		#spkOnHook = runtime.SP_context.SPK_OnHook()
		#if spkOnHook.next():
		#	spkOnHook.next()
	'''
	
	def startTransferTimer(self):
		def transferTimeout_callback():
			self.transferCancelledByBase()
			self.transferTimer = None
			runtime.manager.back_stage()		
		self.transferTimer = utils.Timer(self.TRANSFER_TIMEOUT, transferTimeout_callback)
	
	def clearTransferTimer(self):
		self.transferTimer = None

	def transferDroppedByDect(self):
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		self.stopTransferRinging()
		runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)

		stage = NotifyStage(_('Transfer is dropped...'), uiconfig.baloon_phonebook_icon)
		runtime.manager.change_stage(stage)
		
	def transferCancelledByDect(self):
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		self.stopTransferRinging()
		runtime.SP_context.setBaseStatus(SP_Context.IDLE)
		runtime.dectCallManager.openPcmChannel(1)

		stage = NotifyStage(_('Transfer is cancelled...'), uiconfig.baloon_phonebook_icon)
		runtime.manager.change_stage(stage)

	def transferCancelledByBase(self):
		MD.mmiTrace('H2B_Transfer.transferCancelledByBase()')
		
		runtime.dectCallManager.stopTransferMoh()
		runtime.SP_context.SP_setMicEnable()
		self.setAudioRxUnmute()
		self.stopTransferRinging()
		runtime.dectCallManager.openPcmChannel(1)
		runtime.SP_context.setBaseStatus(SP_Context.IDLE)
		#runtime.dectCallManager.sendTransResult(self.FAILURE)
		
	def handle_key(self, key):
		MD.mmiTrace('H2B_Transfer.handle_key(), key=', key)

		if key == config.Green:
			MD.mmiTrace('H2B_Transfer.handle_key(), press *Green*')

			status.currentCallDuration = (0, 0, 0)
			status.currentCallDuration_copy = (0, 0, 0)
		
			self.stopTransferRinging()
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			self.setAudioRxUnmute()

			runtime.SP_context.SP_stereoStopPlayback()

			runtime.SP_context.speaker.setStatus(Device.OFF_HOOK)
			spkOffHook = runtime.SP_context.SPK_OffHook()
			if spkOffHook.next():
				spkOffHook.next()

			runtime.dectCallManager.closePcmChannel(1)			

			runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
			runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
			runtime.dectCallManager.sendTransResult(self.SUCCESS)

			if runtime.dectCallManager.isSubcribedDect():
				from dectConfig import MessageCode 
				runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)

			stage = AudioCallConnectedStage(self.callerNumber)
			runtime.manager.change_stage(stage,True)			
			runtime.manager.stage.changeMessagePrefix()

		elif key == config.OffHook:
			MD.mmiTrace('H2B_Transfer.handle_key(), press *Off hook*')

			status.currentCallDuration = (0, 0, 0)
			status.currentCallDuration_copy = (0, 0, 0)

			self.stopTransferRinging()
			runtime.dectCallManager.stopTransferMoh()
			runtime.SP_context.SP_setMicEnable()
			self.setAudioRxUnmute()

			runtime.SP_context.SP_stereoStopPlayback()

			runtime.SP_context.handset.setStatus(Device.OFF_HOOK)
			hsOffHook = runtime.SP_context.HS_OffHook()
			if hsOffHook.next():
				hsOffHook.next()

			runtime.dectCallManager.closePcmChannel(1)
			
			runtime.SP_context.setBaseStatus(SP_Context.CONNECTED)
			runtime.dectCallManager.setDectStatus(DectCallManager.IDLE)
			runtime.dectCallManager.sendTransResult(self.SUCCESS)

			if runtime.dectCallManager.isSubcribedDect():
				from dectConfig import MessageCode 
				runtime.dectCallManager.sendVideophoneStatusReportToDect(MessageCode.VP_STATUS.AUDIO_CALL)

			stage = AudioCallConnectedStage(self.callerNumber)
			runtime.manager.change_stage(stage,True)			
			runtime.manager.stage.changeMessagePrefix()

		else:
			MD.mmiTrace('B2H_TransferStage.handle_key(), press *...*')

		return True

	def show(self):
		if setting.screen_saver_enabled:
			status.not_screen_saver = True
			
		Stage.show(self)

	def destroy(self):
		self.ringTimer = None
		self.transferTimer = None
		status.not_screen_saver = False
		setting.reset_screen_saver_timer()
		status.screensaver_activated = False
		Stage.destroy(self)

class RegiNotifyStage(NotifyStage):
	def __init__(self, message, cb=None):
		import uiconfig
		icon = uiconfig.baloon_video_setting_icon
		def go_idle():
			runtime.manager.change_stage(IdleStage, True)
			return
		cb = go_idle
		NotifyStage.__init__(self, message, icon, cb)

	def destroy(self):
		status.critical_entered = True
		NotifyStage.destroy(self)
		
	def handle_key(self, key):		
		return True