Newer
Older
Import / projects / LGN-IP3870 / t / orig / options.py
import status, runtime, config, os, utils
import baseui, ui, uiconfig
from setting import setting
from basemodel import ListStage, Stage, EntryStage, NotifyStage, TempStage
from model import IdleStage, AudioCallConnectedStage, IncomingCallStage, AudioCallConnectingStage, ConnectedStage
from phonesetting import ShowVersionStage

from profile import profile
from roxiadebug import *

class PSTNReleaseHoldBackToConnectedStage(Stage):
	name = 'PSTNReleaseHoldBackToConnected'
	def __init__(self,message):
		# release current line
		status.reset_call_status()
		# switch to held line
		status.toggle_active_call()
		status.set_current_call_status()

		# initialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.business_option_status = status.NotSelected
		status.business_option_request_status = 0
		icon = uiconfig.connected_icon

		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

		self.enable_offhook = 0		# initial value is 0.
						# 1, if last event is offhook
						# 2, if last event is onhook

	def next(self):
		self.tag_invite = 0
		# eicho changes. 06.02.13
		#runtime.manager.change_stage(ConnectedStage, True)
		# eicho add 06.02.13
		#runtime.dspg.audio_mute(status.audio_mute)
		runtime.manager.back_stage('connected', True)
		# eicho end.

	def handle_key(self, key):
		# eicho add 06.02.02
		if key == config.OffHook:
			roxia_trace('PSTNReleaseHoldBackToConnected. offhook')
			self.enable_offhook = 1
			"""
			# offhook after terminating the 2nd call.
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				runtime.dspg.change_to_handset()
			"""
			return True
		# eicho end.
		elif key == config.OnHook:
			self.enable_offhook = 2
			return True

		#self.next()
		#runtime.manager.stage.handle_key(key)
		return True

	def destroy(self):
		self.tag_invite = 0
		if self.enable_offhook == 1:
			status.set_modem_audio_state(status.HS)
			runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)

		elif self.enable_offhook == 2:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV)

		else :
			if status.modem_audio_state == status.HS:
				runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)
			else:
				runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV)

		Stage.destroy(self)

class PSTNNotifyMessageBackToOneCallStage(Stage):
	name = 'PSTNNotifyMessageBackToOneCall'
	def __init__(self, message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		runtime.manager.back_stage()
	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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


class PSTNCallConferenceStage(Stage):
	name = 'PSTNCallConference'
	def __init__(self):
		status.business_call_status = status.TwoCallConnected
		self.held_number= status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)

		self.ui = ui.ConferenceUI(self.connected_name, self.held_name)
		self.ui.show_bg = True
		self.ui.set_right('')
		self.is_last_event = 0
		self.on_end_connect = False

	def handle_key(self, key):

		if key in '0123456789#*':
			runtime.dspg.send_dtmf(key, True)
			return True

		elif key == config.Menu1:
			stage = OptionsPSTNStage
			runtime.manager.stack_stage(stage)
			return True

		elif key == config.Menu2:
			if status.audio_mute == 1:
				self.mute()
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				#end both calls 06.28 self.end_both_calls_byonHook()
				#end both calls 07.07 self.release_conference()
				self.end_both_calls_byonHook()
				
				return True
			# eicho add for warning 83.BB 06.10.26
			elif status.modem_audio_state == status.HS:
				self.end_both_calls(status.HS)
			# end.
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				return False
			else:
				return True

		elif key == config.OnHook:
			if self.on_end_connect == False:
### eicho 0628
				#end both calls 06.28 self.end_both_calls_byonHook()
				#end both calls 07.07 status.set_modem_audio_state(status.SPK)
				#end both calls 07.07 self.release_conference()
				self.end_both_calls_byonHook()
				
			else:	# 일단 end_both_calls가 call된 상태
				self.is_last_event = 1
			
			return True

		elif key == config.OffHook:
			if self.on_end_connect:
				self.is_last_event = 2

			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				if status.audio_mute == 1:	# mute 상태 유지.
					runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV_MUTE)
				else:
					runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)

				self.ui.show()
				return True
			else:
				if status.audio_mute == 1:	# mute 상태 유지.
					runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV_MUTE)
				else:
					runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV)
				self.ui.show()
				return True

		elif key == 'Up':
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)

		elif key == 'Down':
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
		return False

	def end_both_calls_byonHook(self):
		self.end_both_calls(status.IDLE)


## eicho add 06.06.28
## no functions - remove it 06.07.07 end both calls
	'''
	def release_conference(self):
		status.business_call_status = status.TwoCallOneHold
		status.clear_audio_mute()
		runtime.dspg.audio_mute(0)
		runtime.manager.back_stage('PSTNTwoCallOneHold')
		runtime.manager.stage.alternate_call()
	'''
## eicho end


	def end_both_calls(self, ch_state=status.IDLE):
		self.on_end_connect = True
		import time
		# eicho 06.02.16
###########  eicho 07.09 (remove all code)
		'''
		runtime.dspg.send_dtmf('R', False)
		import time
		time.sleep(config.PSTN_after_R_interval)
		# not availabe code. it should be removed. 07.08
		#runtime.dspg.send_dtmf(config.PSTN_end_connected_call_dtmf, False)
		'''
		runtime.manager.handle_second_call_log()
		status.reset_call_status()
		status.toggle_active_call()
		status.set_current_call_status()

		# initialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.business_option_status = status.NotSelected
		status.business_option_request_status = 0
		icon = uiconfig.connected_icon

		def cb_call_nextStage():
			self.t_call_nextStage = None
			#runtime.manager.stop_call(IdleStage)
			time.sleep(config.dtmf_duration)
			#print '============eicho))) status.modem_audio_state = ', status.modem_audio_state
			runtime.manager.back_stage('connected')
			if status.modem_audio_state == status.HS:
				runtime.manager.stage.end_call_by_onhook()
				if self.is_last_event == 2:
					#print 'eicho)))))))))))))))))))1 is_last_event is = ', self.is_last_event
					status.set_modem_audio_state(status.HS)
				else:
					#print 'eicho)))))))))))))))))))2 is_last_event is = ', self.is_last_event
					status.set_modem_audio_state(ch_state)
			else:
				#print 'eicho)))))))))))))))))))3 is_last_event is = ', self.is_last_event
				#print '============eicho))) status.modem_audio_state = ', status.modem_audio_state
				runtime.manager.stage.end_call_by_red()
				status.set_modem_audio_state(ch_state)
			self.on_end_connect = False

		#print 'eicho))) CALL TIMER cb_call_nextStage --------------------------'
		self.t_call_nextStage = utils.Timer(100 , cb_call_nextStage)

	def mute(self):
		status.audio_mute = 1- status.audio_mute
		status.first_audio_mute = 1 - status.first_audio_mute
		status.second_audio_mute = 1 - status.second_audio_mute
		runtime.dspg.audio_mute(status.audio_mute)
		self.ui.show()

class PSTNSecondCallBarringStage(Stage):
	name = 'PSTNSecondCallBarring'

	def __init__(self):
		status.set_video_mode(status.AudioConnected)
                status.business_call_status = status.TwoCallOneHold

                self.held_number= status.display_caller_number(1-status.active_call_index)
                self.held_name = status.display_caller_name(1-status.active_call_index)
                self.connected_number = status.display_caller_number(status.active_call_index)
                self.connected_name = status.display_caller_name(status.active_call_index)

                # eicho modify it to display callee's name 06.02.13
                self.ui = ui.TwoCallOneHoldUI(self.connected_name, self.held_name, _('OPTIONS'), _('ALTERNATE'))
		"""
		self.held_number = status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		status.business_call_status = status.TwoCallOneDialing
		#self.ui = ui.TwoCallOneDialingUI(status.dial_number, self.held_name, _('DIAL'), _('DELETE'))
		self.ui = ui.ConnectedUI(status.dial_number)
		self.ui.show_bg = True
		self.ui.show_cursor(False)
		#runtime.manager.stack_stage(PSTNNotifyMessageBackToOneCallStage(_('Number blocked.')))
		"""
		self.dtmf_timer = utils.Timer(2000, self.end_second_dialing)

	def end_second_dialing(self):
		#status.toggle_waiting()
		stage = PSTNReleaseHoldBackToConnectedStage(_('Number blocked.'))
		runtime.manager.stack_stage(stage)

	def destroy(self):
		self.tag_invite = 0
		self.dtmf_timer = None
		Stage.destroy(self)


class PSTNSecondCallEnblockEditStage(Stage):
	name = 'PSTNSecondCallEnblockEdit'

	def __init__(self):
		self.held_number = status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		status.business_call_status = status.TwoCallOneDialing
		self.ui = ui.TwoCallOneDialingUI(status.dial_number, self.held_name, _('DIAL'), _('DELETE'))
		self.ui.show_bg = True
		self.ui.show_cursor(True)
		# eicho delete following 06.01.18
		# self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
		self.dtmf_timer = None

	def remove_dtmf_timer(self):
		if self.dtmf_timer:
			del(self.dtmf_timer)
			self.dtmf_timer = None

	def auto_dial(self):
		if status.dial_number ==  '':
			runtime.manager.stack_stage(PSTNNotifyMessageBackToOneCallStage(_('No dialed number')))
			self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
		else:
			if runtime.manager.check_call_barring(status.dial_number, False):
				runtime.manager.stack_stage(PSTNNotifyMessageBackToOneCallStage(_('Number blocked.')))
				self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
			else:
				self.remove_dtmf_timer()
				status.toggle_waiting()
				status.save_current_call_status()
				stage = PSTNTwoCallOneHoldStage()
				runtime.manager.stack_stage(stage)

	def end_second_dialing(self):
		roxia_trace('PSTNecondCallEnblockEdit::end_second_dialing()')
		# change back to previous values before edit
		status.toggle_waiting()
		stage = PSTNReleaseHoldBackToConnectedStage(_('End second dialing'))
		runtime.manager.stack_stage(stage)

	def handle_key(self, key):

		# dtmf key가 입력되고 5000ms 이후 자동으로 call을 시도한다
		def do_auto_call():
			self.remove_dtmf_timer()
			if runtime.manager.stage.name != 'PSTNSecondCallEnblockEdit':
				return False
			self.auto_dial()
			return False

		self.remove_dtmf_timer()

		if key == '#':
			if status.dial_number:
				self.auto_dial()
			return True

		elif key in '0123456789*':
			#runtime.vdci_stop_tone()
			self.remove_dtmf_timer()
			self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
			status.dial_number = status.dial_number + key
			self.ui.change_caller_number(status.dial_number)
			self.ui.set_left(_('DIAL'))
			self.ui.set_right(_('DELETE'))
			return True

		elif key == config.Menu1:
			#runtime.vdci_stop_tone()
			if not status.dial_number:
				stage = PhoneBookStage
				runtime.manager.stack_stage(stage)
			else:
				self.remove_dtmf_timer()
				self.auto_dial()
			return True

		elif key == config.Menu2:
			if not status.dial_number:
				self.end_second_dialing()
			else:
				self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
				status.dial_number = status.dial_number[:-1]
				self.ui.change_caller_number(status.dial_number)
				if status.dial_number:
					self.ui.set_left(_('DIAL'))
					self.ui.set_right(_('DELETE'))
				else:
					# eicho add first_digit_timer for end_second_dialing. 06.01.18
					self.remove_dtmf_timer()
					self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
					# eicho end
					self.ui.set_left(_('PHONEBOOK'))
					self.ui.set_right(_('BACK'))
			return True
		elif key == config.LongMenu2:
			self.remove_dtmf_timer()
			self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
			status.dial_number = ''
			self.ui.change_caller_number(status.dial_number)
			self.ui.set_left(_('PHONEBOOK'))
			self.ui.set_right(_('BACK'))
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				self.end_second_dialing()
				return True
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.change_to_spk()
			self.end_second_dialing()
			return True

		elif key == config.OffHook:
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				# eicho change func_setting_dspg: 06.01.18
				# runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK)
				runtime.dspg.change_to_handset()
				# eicho end.

				self.ui.show()
				# eicho add handling auto_call or end_second_call.  06.01.18
				if status.dial_number:
					self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
				else:
					self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
				#eicho end.
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				# eicho add handling auto_call or end_second_call.  06.01.18
				if status.dial_number:
					self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
				else:
					self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
				# eicho end.
				return False
			else:
				return True

		elif key == 'Up':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume up

		elif key == 'Down':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume down

		return True

	def show(self):
		self.ui.change_caller_number(status.dial_number)
		if status.dial_number == '':
			self.ui.set_left(_('PHONEBOOK'))
			self.ui.set_right(_('BACK'))
		self.ui.show()

	def end_call_by_onhook(self):
		status.set_modem_audio_state(status.SPK)
		runtime.dspg.change_to_spk()
		self.end_second_dialing()

	def end_call_by_red(self):
		self.end_second_dialing()

	def destroy(self):
		self.tag_invite = 0
		self.remove_dtmf_timer()
		Stage.destroy(self)


class PSTNDialSecondCallStage(Stage):
	name = 'PSTNDialSecondCall'

	def __init__(self):
		status.save_current_call_status()
		self.held_number = status.display_caller_number(status.active_call_index)
		self.held_name = status.display_caller_name(status.active_call_index)
		# eicho add. 06.01.27
		self.isBackFromPhonebook = False
		status.toggle_active_call()
		status.clear_current_call_status()
		if status.waiting == 0:
			status.toggle_waiting()
		status.business_call_status = status.TwoCallOneDialing
		self.ui = ui.TwoCallOneDialingUI(status.dial_number, self.held_name, _('PHONEBOOK'), _('BACK'))
		self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)

	def handle_key(self, key):
		self.remove_dtmf_timer()
		if key in '0123456789*#':
			runtime.manager.stack_stage(PSTNSecondCallEnblockEditStage)
			runtime.manager.handle_key(True, key)
			return True

		elif key == config.Menu1:
			stage = PhoneBookStage
			runtime.manager.stack_stage(stage)
			self.isBackFromPhonebook = True
			return True

		elif key == config.Menu2:
			self.end_second_dialing()
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				self.end_second_dialing()
				return True
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.change_to_spk()
			self.end_second_dialing()
			return True

		elif key == config.OffHook:
			if status.modem_audio_state == status.SPK:
				# eicho add handling auto_call or end_second_call.  06.01.18
				self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
				status.set_modem_audio_state(status.HS)
				# eicho change func_setting_dspg 06.01.18
				# runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
				runtime.dspg.change_to_handset()
				self.ui.show()
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				# eicho add handling auto_call or end_second_call.  06.01.18
				self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
				return False
			else:
				return True

		elif key == 'Up':
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)

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

		return True

	def remove_dtmf_timer(self):
		if self.dtmf_timer:
			del(self.dtmf_timer)
			self.dtmf_timer = None

	# eicho add 06.01.27
	def show(self):
		if self.isBackFromPhonebook :
			if status.dial_number ==  '':
				self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
			else:
				self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)

		self.ui.show()
	# eicho end.

	def end_second_dialing(self):
		# change back to previous values before edit
		roxia_trace('PSTNDialSecondCallStage::end_second_dialing() # close audio mute ...')
		status.clear_audio_mute()
		status.toggle_waiting()
		stage = PSTNReleaseHoldBackToConnectedStage(_('End second dialing'))
		runtime.manager.stack_stage(stage)

	# eicho add 06.02.10
	def end_call_by_onhook(self):
		status.set_modem_audio_state(status.SPK)
		runtime.dspg.change_to_spk()
		self.end_second_dialing()

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

class PSTNCallTransferNotifyStage(Stage):
	name = 'PSTNCallTransferNotify'

	def __init__(self):
		icon = uiconfig.connected_icon
		message = _('Call transferred')
		runtime.manager.handle_second_call_log()
		status.reset_call_status()
		status.toggle_active_call()
		status.set_current_call_status()
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		status.set_modem_audio_state(status.IDLE)
		runtime.dspg.set_state(runtime.dspg.ST_IDLE)
		runtime.manager.stop_call(IdleStage)

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class OptionsPSTNStage(ListStage):
	name = 'OptionsPSTN'

	def __init__(self):
		self.title = _('OPTIONS')
		self.tag_invite = 0
		status.save_current_call_status()
		if status.business_call_status == status.TwoCallOneHold:
			choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Alternate call'), _('Conference'), _('End connected call'), _('Show hw/sw version'), _('Telephone number')
		elif status.business_call_status == status.TwoCallConnected:
			#choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Release conference'), _('End both calls'), _('Show hw/sw version'), _('Telephone number')
			# eicho modify 06.06.21
			choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Release conference'), _('Show hw/sw version'), _('Telephone number')
		else:
			choice = _('Accept call'), _('Reject call'),  _('Phonebook'), _('Mute'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')

		self.choice = choice
		ListStage.__init__(self, choice)

		status.phonebook_in_calling = True

	def activate(self, index):
		if self.choice[index] == _('Show hw/sw version'):
			import phonesetting
			runtime.manager.stack_stage(phonesetting.ShowVersionStage)
			return
		elif self.choice[index] == _('Telephone number'):
			runtime.manager.stack_stage(ShowTelnumStage)
			return
		self.index = index
		if status.business_call_status == status.TwoCallOneHold:
			if index > 2:
				index -= 3
				option_status = (status.CallAlternateOption, status.CallConferenceOption, status.NotSelected)[index]
				status.business_option_status = option_status
				runtime.manager.back_stage()
				if option_status == status.CallAlternateOption:
					runtime.manager.stage.alternate_call()
				elif option_status == status.CallConferenceOption:
					runtime.manager.stage.conference_call()
				else:
					runtime.manager.stage.end_connected_call()
			else:
				stage = _analog_stages[index]
				runtime.manager.stack_stage(stage)

		elif status.business_call_status == status.TwoCallConnected:
			# eicho modify 06.06.21
			# choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Release conference') 만 check 하면 됨.
			if index == 1: # Mute
				runtime.manager.back_stage()
				runtime.manager.stage.mute()
				
			elif index == 3: # Release conference vpark 12.18
				status.business_call_status = status.TwoCallOneHold
				# eicho add 'release audio mute before releasing call conference' 06.02.07
				status.clear_audio_mute()
				runtime.dspg.audio_mute(0)
				# eicho end.
				runtime.manager.back_stage('PSTNTwoCallOneHold')
				runtime.manager.stage.alternate_call()

			# eicho remove 06.06.21
				''' 	
			elif index == 4: # End both calls
				runtime.manager.back_stage()
				# eicho modify. 06.02.16
				# HS 에서 menu로 disconnect -> offhook
				if status.modem_audio_state == status.HS:
					runtime.manager.stage.end_both_calls(status.HS)
				# SPK에서 menu로 disconnect -> idle
				else:
					runtime.manager.stage.end_both_calls(status.IDLE)
				'''
				
			else:     		# index = 0 or 2.
				stage = _analog_stages[index]
				runtime.manager.stack_stage(stage)

		else:
			if index < 2: # Accept call & reject call
				runtime.manager.back_stage()
				runtime.manager.stage.invite_request()
			else:
				index -= 2
				stage = _analog_stages[index]
				runtime.manager.stack_stage(stage)

	def release_conference(self):
		status.business_call_status = status.TwoCallOneHold
		status.clear_audio_mute()
		runtime.dspg.audio_mute(0)
		runtime.manager.back_stage('PSTNTwoCallOneHold')
		runtime.manager.stage.alternate_call()


	def show(self):

		ListStage.show(self)
		if status.business_call_status == status.TwoCallOneHold:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))

		elif status.business_call_status == status.TwoCallConnected:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))

		else:
			if status.audio_mute:
				self.ui.set_text(3, _('Enable microphone'))
			else:
				self.ui.set_text(3, _('Mute'))

	def destroy(self):
		status.phonebook_in_calling = False
		status.waiting = 0
		ListStage.destroy(self)

class PSTNTwoCallOneHoldStage(Stage):
	name = 'PSTNTwoCallOneHold'
	def __init__(self):
		# eicho add 06.01.31
		if status.waiting == 1:	# waiting is enabled before connecting new call
			roxia_trace('PSTNTwoCallOneHoldStage : release waiting setting.')
			status.toggle_waiting()
		# eicho end.

		# eicho add 06.02.20
		if runtime.manager.check_call_barring(status.dial_number, False):
			roxia_trace('PSTNTwoCallOneHoldStage::  check call barring returns true.')
			self.held_number= status.display_caller_number(1-status.active_call_index)
			self.held_name = status.display_caller_name(1-status.active_call_index)
			self.connected_number = status.display_caller_number(status.active_call_index)
			self.connected_name = status.display_caller_name(status.active_call_index)

			# eicho modify it to display callee's name 06.02.13
 			self.ui = ui.TwoCallOneHoldUI(self.connected_name, self.held_name, _('OPTIONS'), _('ALTERNATE'))
			self.cb_callbarring = utils.Timer(13, self.end_call_barring)
		# eicho end.
			return

		status.clear_audio_mute()
		if status.modem_audio_state == status.HS:
			runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)

		else:
			runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV)


		import time
		runtime.dspg.send_dtmf('R', False)
		time.sleep(config.PSTN_after_R_interval)
		# eicho add Prefix options. 06.02.13
		if setting.set_supplement_tde_prefix == 1:
			rr_number = config.FAC_TELEFONICA_PREFIX_CODE + status.dial_number
		else:
			rr_number = status.dial_number

		runtime.dspg.send_dtmf(rr_number, False)
		status.set_call_time()
		#runtime.dspg.send_dtmf(status.dial_number, False)
		# eicho end.
		status.set_video_mode(status.AudioConnected)
		# eicho add 06.02.13
		# to save a time of calling
		status.set_current_call_status()
		status.business_call_status = status.TwoCallOneHold

		self.held_number= status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)

		# eicho modify it to display callee's name 06.02.13
 		self.ui = ui.TwoCallOneHoldUI(self.connected_name, self.held_name, _('OPTIONS'), _('ALTERNATE'))
		# eicho end.
		self.on_disconnecting = False


	def handle_key(self, key):
		if key in '0123456789#*':
			runtime.dspg.send_dtmf(key, True)
			status.dial_number = status.dial_number + key
			self.ui.change_caller_number(status.dial_number)
			self.ui.show()
			return True

		if key == config.Menu1:
			stage = OptionsPSTNStage
			runtime.manager.stack_stage(stage)
			return True

		elif key == config.Menu2:
			self.alternate_call()
			return True

		elif key == config.Red:
			# eicho add for warning 83.BB 06.10.26
			#if status.modem_audio_state == status.SPK:
			if status.modem_audio_state == status.SPK or status.modem_audio_state == status.HS:
				self.end_connected_call()
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				return False
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.SPK)
			self.end_connected_call()
			return True

		elif key == config.OffHook:
			if self.on_disconnecting == True:
				return True

			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				if status.audio_mute == 1:	# mute 상태 유지.
					runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV_MUTE)
				else:
					runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)
				self.ui.show()
				return True
			else:
				if status.audio_mute == 1:	# mute 상태 유지.
					runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV_MUTE)
					self.ui.show()
				return True

		elif key == 'Up':
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)

		elif key == 'Down':
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
		return True


	def alternate_call(self):
		# swap and refresh show
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)
		status.save_current_call_status()

		runtime.dspg.send_dtmf('R', False)
		import time
		time.sleep(config.PSTN_after_R_interval)
		runtime.dspg.send_dtmf(config.PSTN_alternate_dtmf, False)
		status.toggle_active_call()
		status.set_current_call_status()
		if status.audio_mute == 1: 	# mute enabled
			if status.modem_audio_state == status.SPK:
				runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV_MUTE)
			else:
				runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV_MUTE)
		else:
			if status.modem_audio_state == status.SPK:
				runtime.dspg.set_state(runtime.dspg.ST_SPK_OFFHK_CONV)
			else:
				runtime.dspg.set_state(runtime.dspg.ST_HS_OFFHK_CONV)
		self.held_number= status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)
		self.ui.change_hold_number(self.held_name)
		self.ui.change_caller_number(self.connected_name)
		self.ui.set_right(_('ALTERNATE'))
		self.ui.show()

	def transfer_call(self):
		stage = PSTNCallTransferNotifyStage
		runtime.manager.stack_stage(stage)

	def conference_call(self):
		runtime.dspg.send_dtmf('R', False)
		import time
		time.sleep(config.PSTN_after_R_interval)
		runtime.dspg.send_dtmf(config.PSTN_conference_dtmf, False)
		# eicho add to release_audio_mute before making a conference. 06.02.07
		status.clear_audio_mute()
		runtime.dspg.audio_mute(0)
		# eicho end.
		stage = PSTNCallConferenceStage
		runtime.manager.stack_stage(stage)

	def end_connected_call(self):
		runtime.dspg.send_dtmf('R', False)
		import time
		time.sleep(config.PSTN_after_R_interval)
		runtime.dspg.send_dtmf(config.PSTN_end_connected_call_dtmf, False)
		runtime.manager.handle_second_call_log()
		status.clear_audio_mute()
		stage = PSTNReleaseHoldBackToConnectedStage('\'' + status.display_caller_name(status.active_call_index) + '\' ' + _('disconnected.'))
		runtime.manager.stack_stage(stage)

	# eicho add 06.02.10
	def end_call_by_onhook(self):
		# eicho add 06.02.02
		if status.modem_audio_state == status.HS:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.change_to_spk()
		# eicho end.
		self.end_connected_call()

	def end_call_barring(self):
		self.cb_callbarring = None
		status.clear_audio_mute()
		stage = PSTNReleaseHoldBackToConnectedStage(_('Number blocked.'))
		runtime.manager.stack_stage(stage)

	def destroy(self):
		self.cb_callbarring = None
		Stage.destroy(self)



class CallConferenceStage(Stage):
	name = 'CallConference'
	def __init__(self):
		status.business_call_status = status.TwoCallConnected
		self.held_number= status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)

		self.ui = ui.ConferenceUI(self.connected_name, self.held_name)
		self.ui.show_bg = True

	# hcryoo : [20070515_2]
	def set_callee_held(self, number=None):
		status.heldline = 1
		# hcryoo : [20070525_2]
		if config.roxia_event:
			print 'self.held_number = ', self.held_number
			print 'self.connected_number = ', self.connected_number
			print 'number = ', number
			
		if number == self.held_number:
			self.ui.show_held_name(self.held_name + '(' + _('Held') + ')')
		elif number == self.connected_number:
			self.ui.show_connected_name(self.connected_name + '(' + _('Held') + ')')
		else:
			self.ui.set_connectedHeld_icon()
		# hcryoo : [20070525_2]==

		runtime.evas.render_now()
		
	def cancel_callee_held(self, number=None):
		if config.roxia_event:
			print 'self.held_number = ', self.held_number
			print 'self.connected_number = ', self.connected_number
			print 'number = ', number
			
		status.heldline = 0
		# hcryoo : [20070525_2]
		if number == self.held_number:
			self.ui.show_held_name(self.held_name)
		elif number == self.connected_number:
			self.ui.show_connected_name(self.connected_name)
		else:
			self.ui.cancel_connectedHeld_icon()
		# hcryoo : [20070525_2]==
	# hcryoo : [20070515_2]==
		
	def handle_key(self, key):

		if key in '0123456789#*':
			runtime.dspg.send_dtmf(key, True)
			return True

		elif key == config.Menu1:
			stage = OptionsIPStage
			runtime.manager.stack_stage(stage)
			return True

		elif key == config.Menu2:
			if status.audio_mute:
				self.mute()
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.IDLE)
				runtime.dspg.set_state(runtime.dspg.ST_IDLE)
				self.end_both_calls()
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				return False
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.IDLE)
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
			self.end_both_calls()
			return True

		elif key == config.OffHook:
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				runtime.dspg.change_to_handset() # vpark 06.02.08
				self.ui.show()
				return True
			else:
				return True

		elif key == 'Up':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume up

		elif key == 'Down':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume down

		return True

	# hcryoo : [20070502_1]
	def make_conference(self):
		runtime.vdci_send_mesg(code1=config.MESG_CALL_CONFERENCE, \
			code2=config.MESG_CALL_JOIN,mesg1='1')
	# hcryoo : [20070502_1]==
	
	def end_both_calls(self):
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		status.toggle_active_call()
		status.set_current_call_status()
		stage = HangupStage(_('Audio call terminated.'))
		runtime.manager.stack_stage(stage)

	def mute(self):
		status.audio_mute = 1- status.audio_mute
		status.first_audio_mute = 1 - status.first_audio_mute
		status.second_audio_mute = 1 - status.second_audio_mute

		# vpark begin 06.02.08
		runtime.dspg.audio_mute(status.audio_mute)
		#runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
		#				code2=config.MESG_SET_AUDIO_MUTE, \
		#				mesg1=status.audio_mute)
		#status.toggle_active_call()
		#runtime.vdciapp.send_mesg(code1=config.MESG_SET_PARAMS, \
		#				code2=config.MESG_SET_AUDIO_MUTE, \
		#				mesg1=status.audio_mute)
		#status.toggle_active_call()
		# vpark end 06.02.08
		self.ui.show()

class ErrorResultNotifyStage(Stage):
	name = 'ErrorResultNotify'
	def __init__(self, message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		status.set_current_audio_mute()
		# hcryoo : [20070518_2]
		status.reset_hold_flag(status.active_call_index)
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
					code2=config.MESG_CALL_HOLD_DEACTIVATE)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		runtime.manager.back_stage()

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class IncomingDisconnectedStage(Stage):
	name = 'IncomingDisconnected'
	def __init__(self,message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

		# hcryoo : [20070521_3]
		status.reset_hold_flag(status.active_call_index)
#ka...slim 2007.05.25 delete TEST
#		status.reset_held_flag(status.active_call_index)			
		# hcryoo : [20070521_3]
#ka...slim 2007.05.27 069 call중에 SecondIncomingCall/ 069종료
#		status.dialed_TdESupplementary = False
		
	def next(self):
		self.tag_invite = 0
		runtime.manager.back_stage()
		runtime.manager.stage.disconnected_next()

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class SecondIncomingCallStage(Stage):
	name = 'SecondIncomingCall'
	in_progress = 0
	incoming = 0
	hold_progress = 0
	active_invite_progress = 0
	incoming_invite_progress = 0
	release_hold_progress = 0
	wait_for_release_hold = 0
	wait_for_disconnect_hold = 0
	reinvite_request = 0
	notify_message = ''
	current_tone_channel = 0

	cwi_tone_timer = None
	
	def __init__(self):
		status.business_call_status = status.TwoCallOneIncoming
		self.active_line_number = status.display_caller_number(status.active_call_index)
		self.active_line_name = status.display_caller_name(status.active_call_index)
		self.active_video_mode = status.get_video_mode(status.active_call_index)

		self.incoming_number = status.display_caller_number(1-status.active_call_index)
		self.incoming_name = status.display_caller_name(1-status.active_call_index)

		if self.active_video_mode == status.AudioIncoming:
			self.ui = ui.TwoIncomingUI(self.active_line_name, self.incoming_name)
		elif self.active_video_mode == status.AudioRequesting:
			self.ui = ui.FirstConnectingSecondIncomingUI(self.active_line_name, self.incoming_name)
		elif self.active_video_mode == status.AudioConnected:
			if status.business_option_status == status.CallHoldOption: # acitve line on hold
				self.ui = ui.FirstHeldSecondIncomingUI(self.active_line_name, self.incoming_name)
			else:
				self.ui = ui.FirstConnectedSecondIncomingUI(self.active_line_name, self.incoming_name)

##### answer delay version.
# 06.06.26 (eicho)
		self.current_tone_channel = 0
		#self.start_cwi_tone()
# 06.07.07 eicho. change cwi tone.
		# every 4025 msec, try to send msg playing CWI TONE to VDCI.
		self.cwi_tone_timer = utils.Timer(config.TdE_CWI_TONE_TERM, self.start_cwi_tone)

	# hcryoo : [20070525_3]
	def set_callee_held(self):
		self.ui.show()
		runtime.evas.render_now()
		
	def cancel_callee_held(self):
		self.ui.show()
	# hcryoo : [20070525_3]==

	def start_cwi_tone(self):
		self.current_tone_channel = status.get_current_channel()
		runtime.vdci_send_mesg(code1=config.MESG_CALL_WAITING_CODE1, \
					code2=config.MESG_CALL_WAITING_START, \
					chan1=self.current_tone_channel, \
					mesg1=config.MESG_CALL_WAITING_MESG1, \
					mesg2=config.MESG_CALL_WAITING_MESG2)
		return True

	def stop_cwi_tone(self):
		if self.cwi_tone_timer != None :
			del(self.cwi_tone_timer)
		self.cwi_tone_timer = None
		
# 06.07.07 change cwi tone.
		if self.current_tone_channel == 0 :
			return
			
		runtime.vdci_send_mesg(code1=config.MESG_CALL_WAITING_CODE1, \
					code2=config.MESG_CALL_WAITING_STOP, \
					chan1=self.current_tone_channel)
		self.current_tone_channel = 0

	def handle_key(self, key):
		if self.in_progress == 0:
			if key in '0123456789#*':
				if self.active_video_mode == status.AudioConnected and \
					status.business_option_status == status.NotSelected:
					runtime.vdci_send_dtmf(key)
				return True

			elif key == config.Menu1: # accept
				# 06.06.26
				self.stop_cwi_tone()
				runtime.manager.kill_ringer()
				if status.modem_audio_state == status.IDLE:
					status.set_modem_audio_state(status.SPK)
					runtime.dspg.set_state(runtime.dspg.ST_V_SPK_OFFHK)

				if self.active_video_mode == status.AudioConnected and \
					status.business_option_status != status.CallHoldOption:
					# hold the connected one first before accept the call
					self.hold_call()
				else:
					self.incoming_invite_progress = 1
					# accept the call (Hold, incoming or requesting)
					# switch to second incoming call and initialize
					status.toggle_active_call()
					self.invite_request()
				return True

			elif key == config.Menu2: # reject
				# 06.06.26
				self.stop_cwi_tone()
				runtime.manager.kill_ringer()
				status.toggle_active_call()
				self.call_reject()
				return True

			elif key == config.Red:
				if self.active_video_mode == status.AudioIncoming:
					# 06.06.26
					self.stop_cwi_tone()
					runtime.manager.kill_ringer()
					if status.modem_audio_state == status.SPK:
						status.set_modem_audio_state(status.IDLE)
						runtime.dspg.set_state(runtime.dspg.ST_IDLE)
					self.call_reject()
				else:
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					self.connected_disconnected()
				return True

			elif key == config.Green:
				if self.active_video_mode == status.AudioIncoming:
					# 06.06.26
					self.stop_cwi_tone()
					runtime.manager.kill_ringer()
					if status.modem_audio_state == status.IDLE:
						status.set_modem_audio_state(status.SPK)
						runtime.dspg.set_state(runtime.dspg.ST_V_SPK_OFFHK)
					self.active_invite_progress = 1
					self.invite_request()
					return True
				else:
					return False

			elif key == config.OnHook:
				# 06.06.26
				self.stop_cwi_tone()
				runtime.manager.kill_ringer()
				status.set_modem_audio_state(status.IDLE)
				runtime.dspg.set_state(runtime.dspg.ST_IDLE)
				if self.active_video_mode == status.AudioIncoming:
					self.call_reject()
				else:
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					self.connected_disconnected()
				return True

			elif key == config.OffHook:
				status.set_modem_audio_state(status.HS)
				runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
				if self.active_video_mode == status.AudioIncoming:
					# 06.06.26
					self.stop_cwi_tone()
					runtime.manager.kill_ringer()
					self.active_invite_progress = 1
					self.invite_request()
				else:
					self.ui.show()
				return True

			elif key == 'Up':
				if self.active_video_mode != status.AudioIncoming:
					stage = AudioVolumeStage
					runtime.manager.stack_stage(stage)

			elif key == 'Down':
				if self.active_video_mode != status.AudioIncoming:
					stage = AudioVolumeStage
					runtime.manager.stack_stage(stage)
		else:
			if key == config.Red:
				if status.modem_audio_state == status.SPK:
					if self.incoming_invite_progress == 1:
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						self.incoming_disconnected()
					elif self.active_invite_progress == 1:
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						self.connected_disconnected()
					elif self.hold_progress == 1:
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						self.connected_disconnected()
					elif self.release_hold_progress == 1:
						self.release_hold_error()
					else:
						return True
				else:
					return True

			elif key == config.OnHook:
				
				if self.incoming_invite_progress == 1:
					if self.active_video_mode == status.AudioIncoming:
						status.set_modem_audio_state(status.IDLE)
						runtime.dspg.set_state(runtime.dspg.ST_IDLE)
					else:
						status.set_modem_audio_state(status.SPK)
						runtime.dspg.change_to_spk() # vpark 06.02.08
						#runtime.dspg.set_state(runtime.dspg.ST_V_SPK_OFFHK)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					self.incoming_disconnected()
				elif self.active_invite_progress == 1:
					status.set_modem_audio_state(status.IDLE)
					runtime.dspg.set_state(runtime.dspg.ST_IDLE)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					self.connected_disconnected()
				elif self.hold_progress == 1:
					status.set_modem_audio_state(status.IDLE)
					runtime.dspg.set_state(runtime.dspg.ST_IDLE)
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					self.connected_disconnected()
				elif self.release_hold_progress == 1:
					status.set_modem_audio_state(status.IDLE)
					runtime.dspg.set_state(runtime.dspg.ST_IDLE)
					self.release_hold_error()
				else:
					return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == config.Green:
				return False


		return True

	def call_reject(self):
		status.set_current_call_status()
		status.set_call_time()
		runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
						code2=config.MESG_CALL_REJECT, \
						mesg1=config.REASON_LINE_BUSY)
		self.incoming_disconnected()


	def invite_request(self):
		self.in_progress = 1
		status.set_current_call_status()
		self.tag_invite = utils.Timer(config.timeoutInvite, self.invite_error)
		runtime.vdci_send_mesg(code1=config.MESG_INCOMING_CALL, \
						code2=config.MESG_CALL_ACCEPT, mesg1=config.NOT_SUPERVISION_CALL)

	def invite_sucessed(self):

		status.clear_audio_mute()
		status.set_current_audio_mute()

		if self.in_progress == 0:
			# AudioRequesting answered by remote
			status.set_video_mode(status.AudioConnected)
			status.set_call_time()
			status.save_current_call_status()
			stage = SecondIncomingCallStage
			runtime.manager.change_stage(stage)
		else:
			self.in_progress = 0
			self.tag_invite = 0
			if self.active_invite_progress == 1:
				self.active_invite_progress = 0
			elif self.incoming_invite_progress == 1:
				self.incoming_invite_progress = 0

			# change the video mode to AudioConnected
			status.set_video_mode(status.AudioConnected)
			status.set_call_time()
			status.save_current_call_status()

			if self.wait_for_disconnect_hold == 1:
				self.wait_for_disconnect_hold = 0
				runtime.manager.change_stage(AudioCallConnectedStage, True)

			elif self.active_video_mode == status.AudioIncoming:
				import time
				time.sleep(1)
				stage = SecondIncomingCallStage
				runtime.manager.change_stage(stage)

			elif self.active_video_mode == status.AudioRequesting:
				# disconnect audio requesting one.
				status.toggle_active_call()
				status.set_current_call_status()
				runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
				runtime.manager.handle_second_call_log()
				status.release_channel()
				status.reset_call_status()
				status.toggle_active_call()
				status.set_current_call_status()
				runtime.manager.change_stage(AudioCallConnectedStage, True)

			else:
				stage = TwoCallOneHoldStage
				runtime.manager.change_stage(stage)

	def hold_call(self):
		self.in_progress = 1
		self.hold_progress = 1
		self.tag_invite = utils.Timer(config.timeoutReinvite, self.hold_call_error)
		# hcryoo : [20070518_2]
		status.set_hold_flag(status.active_call_index)
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
						code2=config.MESG_CALL_HOLD_ACTIVATE)

	def hold_call_sucessed(self):
		self.tag_invite = 0
		self.hold_progress = 0
		status.business_option_status = status.CallHoldOption

		if self.wait_for_release_hold == 1:
			self.wait_for_release_hold = 0
			self.in_progress = 1
			self.release_hold_progress = 1
			self.tag_invite = utils.Timer(config.timeoutReinvite, self.release_hold_error)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
							code2=config.MESG_CALL_HOLD_DEACTIVATE)
			runtime.manager.stack_stage(DisconnectNotifyStage(self.notify_message+'\n'+_('disconnected.')))
		else:
			# switch to second incoming call and initialize
			status.toggle_active_call()
			self.invite_request()

	def hold_call_error(self):
		self.in_progress = 0
		self.tag_invite = 0
		self.hold_progress = 0
		# hang up the active one
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		runtime.vdciapp.end_call_by_active_remote()

	def invite_error(self):

		self.in_progress = 0
		self.tag_invite = 0
		self.invite_progress = 0
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		self.incoming_disconnected()

	def incoming_disconnected(self):
		# 06.06.26
		self.stop_cwi_tone()
		
		self.in_progress = 0
		self.tag_invite = 0
		self.incoming = 1
		if status.get_video_mode(status.active_call_index) == status.AudioIncoming:
			if self.active_invite_progress == 1:
				self.active_invite_progress = 0
				self.tag_invite = 0
			elif self.incoming_invite_progress == 1:
				self.incoming_invite_progress = 0
				self.tag_invite = 0
		elif self.active_line_number == status.display_caller_number(status.active_call_index):
			if self.hold_progress == 1:
				self.hold_progress = 0
				self.tag_invite = 0
				self.reinvite_request = 1

		self.notify_message = status.display_caller_name(status.active_call_index)
		# release current line
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		# switch back to active line
		status.toggle_active_call()
		status.set_current_call_status()
		self.active_video_mode = status.get_video_mode(status.active_call_index)

		# intialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected

		if self.hold_progress == 1:
			self.wait_for_release_hold = 1
		elif self.active_invite_progress == 1 or self.incoming_invite_progress == 1:
			self.wait_for_disconnect_hold = 1
		elif self.active_video_mode == status.AudioConnected and \
			status.business_option_status == status.CallHoldOption:
			self.in_progress = 1
			self.release_hold_progress = 1
			self.tag_invite = utils.Timer(config.timeoutReinvite, self.release_hold_error)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
							code2=config.MESG_CALL_HOLD_DEACTIVATE)

			runtime.manager.stack_stage(DisconnectNotifyStage(self.notify_message+'\n'+_('disconnected.')))
		else:

			runtime.manager.stack_stage(IncomingDisconnectedStage(self.notify_message+'\n'+_('disconnected.')))



	def connected_disconnected(self):
		# 06.06.26
		self.stop_cwi_tone()
		
		self.in_progress = 0
		self.tag_invite = 0
		self.incoming = 0
		if status.get_video_mode(status.active_call_index) == status.AudioIncoming:
			#Roxia Begin yhcho 06.02.01
			runtime.manager.kill_ringer()
			fstage = runtime.manager.find_stage('incomingcall')
			if fstage:
				fstage.stop_after_ring()
			#Roxia End yhcho

			if self.active_invite_progress == 1:
				self.active_invite_progress = 0
			elif self.incoming_invite_progress == 1:
				self.incoming_invite_progress = 0
		elif self.active_line_number == status.display_caller_number(status.active_call_index):
			if self.hold_progress == 1:
				self.hold_progress = 0
				self.tag_invite = 0
				self.reinvite_request = 1
		self.notify_message = status.display_caller_name(status.active_call_index)
		# release current line
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		# switch back to active line
		status.toggle_active_call()
		status.set_current_call_status()

		self.active_video_mode = status.get_video_mode(status.active_call_index)

		# intialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected

		#ka...slim 2007.05.27 069 call중에 SecondIncomingCall/ 069종료
		status.dialed_TdESupplementary = False

		if self.hold_progress == 1:
			self.wait_for_release_hold = 1
		elif self.active_invite_progress == 1 or self.incoming_invite_progress == 1:
			self.wait_for_disconnect_hold = 1

		elif self.active_video_mode == status.AudioConnected and \
			status.business_option_status == status.CallHoldOption:
			self.in_progress = 1
			self.release_hold_progress = 1
			self.tag_invite = utils.Timer(config.timeoutReinvite, self.release_hold_error)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
							code2=config.MESG_CALL_HOLD_DEACTIVATE)
			runtime.manager.stack_stage(DisconnectNotifyStage(self.notify_message+'\n'+_('disconnected.')))
		else:

			runtime.manager.stack_stage(IncomingDisconnectedStage(self.notify_message+'\n'+_('disconnected.')))

	def release_hold_successed(self):
		# 06.06.26
		self.stop_cwi_tone()
		
		self.in_progress = 0
		self.tag_invite = 0
		self.release_hold_progress = 0
		status.business_option_status = status.NotSelected

		if self.active_video_mode == status.AudioIncoming:
			status.phone_status = status.Disconnected
			status.reset_call_status()
			status.set_service_name(status.service_name)
			status.set_caller_number(status.caller_number)
			status.set_video_mode(status.AudioIncoming)
			status.set_current_call_status()
			status.set_current_audio_mute()
			runtime.manager.change_stage(IncomingCallStage(0, status.service_name, status.caller_number, 0, ''), True)
		elif self.active_video_mode == status.AudioRequesting:
			status.reset_call_status()
			status.set_service_name(status.service_name)
			status.set_dial_number(status.dial_number)
			status.set_video_mode(status.AudioRequesting)
			status.set_current_call_status()
			status.set_current_audio_mute()
			runtime.manager.back_stage('directaudiocalling')
		else:
			runtime.manager.change_stage(AudioCallConnectedStage, True)

	def release_hold_error(self):
		# 06.06.26
		self.stop_cwi_tone()
		
		self.in_progress = 0
		self.tag_invite = 0
		self.release_hold_progress = 0
		runtime.manager.stack_stage(HangupStage)

	def disconnected_next(self):
		# 06.11.28	
		self.stop_cwi_tone()
		if self.active_video_mode == status.AudioIncoming:
			status.phone_status = status.Disconnected
			status.reset_call_status()
			status.set_service_name(status.service_name)
			status.set_caller_number(status.caller_number)
			status.set_video_mode(status.AudioIncoming)
			status.set_current_call_status()
			status.set_current_audio_mute()
			runtime.manager.change_stage(IncomingCallStage(0, status.service_name, status.caller_number, 0, ''), True)
			if self.reinvite_request == 1:
				runtime.manager.stage.handle_key(key=config.Green)
		elif self.active_video_mode == status.AudioRequesting:
			status.reset_call_status()
			status.set_service_name(status.service_name)
			status.set_dial_number(status.dial_number)
			status.set_video_mode(status.AudioRequesting)
			status.set_current_call_status()
			status.set_current_audio_mute()
			runtime.manager.back_stage('directaudiocalling')
		else:
			runtime.manager.change_stage(AudioCallConnectedStage, True)

	def destroy(self):
		# 06.11.28	
		self.stop_cwi_tone()

		self.in_progress = 0
		self.incoming = 0
		self.hold_progress = 0
		self.active_invite_progress = 0
		self.incoming_invite_progress = 0
		self.wait_for_release_hold = 0
		self.wait_for_disconnect_hold = 0
		self.reinvite_progress = 0
		Stage.destroy(self)

class DisconnectNotifyStage(Stage):
	name = 'DisconnectNotify'
	def __init__(self,message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)

	def next(self):
		runtime.manager.back_stage()

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class CallTransferNotifyStage(Stage):
	name = 'CallTransferNotify'

	def __init__(self):
		icon = uiconfig.connected_icon
		message = _('Call transferred')
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		status.toggle_active_call()
		status.set_current_call_status()
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		#runtime.dspg.set_state(runtime.dspg.ST_IDLE)
		#status.set_modem_audio_state(status.IDLE)
		runtime.manager.stop_audio_call(False)

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class TwoCallOneHoldStage(Stage):
	name = 'TwoCallOneHold'
	in_progress = 0
	def __init__(self):
		status.business_call_status = status.TwoCallOneHold
		status.set_video_mode(status.AudioConnected)

		self.held_number= status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)

 		if status.business_option_status == status.CallTransferOption:
			right = _('TRANSFER')
		elif status.business_option_status == status.CallConferenceOption:
			right = _('CONFERENCE')
		else: # CallHoldOption
			right = _('ALTERNATE')

		self.ui = ui.TwoCallOneHoldUI(self.connected_name, self.held_name, _('OPTIONS'), right)

	# hcryoo : [20070521_3]
	def set_callee_held(self):
		self.ui.show()
		runtime.evas.render_now()
		
	def cancel_callee_held(self):
		self.ui.show()
	# hcryoo : [20070521_3]==

	def handle_key(self, key):
		if self.in_progress == 0:
			if key in '0123456789#*':
				runtime.vdciapp.send_dtmf(key)
				return True

			if key == config.Menu1:
				stage = OptionsIPStage
				runtime.manager.stack_stage(stage)
				return True

			elif key == config.Menu2:
				# hcryoo : [20070522_1]
				if self.ui.right != _('END'): 
					if status.business_option_status == status.CallConferenceOption:
						self.invite_request()
					elif status.business_option_status == status.CallHoldOption:
						status.business_option_status = status.CallAlternateOption
						self.invite_request()
					elif status.business_option_status == status.CallTransferOption:
						self.invite_request()
					return True
				else:
					if status.modem_audio_state == status.SPK or status.modem_audio_state == status.HS:
						if status.business_option_status == status.CallTransferOption:
							self.invite_request()
						else:
							status.reset_held_flag(status.active_call_index)
							runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
							stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
							runtime.manager.stack_stage(stage)
						return True
					else:
						return True
				# hcryoo : [20070522_1]==

			elif key == config.Red:
				# eicho add for warning 83.BB 06.10.26
				#if status.modem_audio_state == status.SPK:
				if status.modem_audio_state == status.SPK or status.modem_audio_state == status.HS:
					if status.business_option_status == status.CallTransferOption:
						self.invite_request()
					else:
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
						runtime.manager.stack_stage(stage)
					return True
				else:
					return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

			elif key == config.OnHook:
				if status.business_option_status == status.CallTransferOption:
					self.invite_request()
				else:
					status.set_modem_audio_state(status.SPK)
					runtime.dspg.change_to_spk()
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
					runtime.manager.stack_stage(stage)
				return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == 'Up':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume up

			elif key == 'Down':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume down

		else:
			if key == config.OnHook:
				if status.business_option_status == status.CallTransferOption:
					self.transfer_call()
				else:
					status.set_modem_audio_state(status.SPK)
					runtime.dspg.change_to_spk()
					status.clear_audio_mute()
					runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
					stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
					runtime.manager.stack_stage(stage)
				return True

			elif key == config.Red:
				if status.modem_audio_state == status.SPK:
					if status.business_option_status == status.CallTransferOption:
						self.invite_request()
					else:
						status.clear_audio_mute()
						runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
						stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
						runtime.manager.stack_stage(stage)
					return True
				else:
					return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

		return True


	def invite_request(self):
		self.in_progress = 1

		if status.business_option_status == status.NotSelected: # Hang up the current and go back to previous
			status.clear_audio_mute()
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
			runtime.manager.stack_stage(stage)

		elif status.business_option_status == status.CallConferenceOption: # Call conference
			self.conference_call()

		elif status.business_option_status != status.CallHoldOption: # Alternate, Call transfer
    			self.tag_invite = utils.Timer(config.timeoutReinvite, self.invite_error)
			# hcryoo : [20070518_2]
			status.set_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
						code2=config.MESG_CALL_HOLD_ACTIVATE)

	def invite_sucessed(self):
		self.tag_invite = 0
		if status.business_option_status == status.CallTransferOption:
			self.remoteID = self.held_number
			status.business_option_request_status = 1
			import time
			time.sleep(2)
			self.tag_invite = utils.Timer(config.timeoutReinvite, self.invite_error)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_TRANSFER, \
							code2=config.MESG_CALL_TRANSFER_CONSULTATION, \
							mesg1 = self.remoteID)

		elif status.business_option_status == status.CallAlternateOption:
			status.business_option_status = status.CallHoldOption
			status.toggle_active_call()
			status.set_current_call_status()
			status.set_current_audio_mute()
			self.tag_invite = utils.Timer(config.timeoutReinvite, self.invite_error)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, \
							code2=config.MESG_CALL_HOLD_DEACTIVATE)


	def transfer_fail(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.business_option_request_status = 0
		# eicho 06.06.26: 603 decline.
		#status.business_option_status = status.CallTransferOption
		#self.ui.set_right(_('TRANSFER'))
		status.business_option_status = status.CallAlternateOption
		self.ui.set_right(_('ALTERNATE'))
		
               	self.ui.show()
		stage = ErrorResultNotifyStage(_('Transfer failed.') + '\n' + _('Please try again.'))
		runtime.manager.stack_stage(stage)

	def invite_error(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.business_option_request_status = 0
		# error after call hold
		status.clear_audio_mute()
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
		runtime.manager.stack_stage(stage)

	def alternate_call(self):
		self.tag_invite = 0
		self.in_progress = 0
		# swap and refresh show
		temp_num = self.connected_number
               	temp_name = self.connected_name
               	self.connected_number = self.held_number
              	self.connected_name = self.held_name
		self.held_number = temp_num
		self.held_name = temp_name
               	self.ui.change_hold_number(self.held_name)
               	self.ui.change_caller_number(self.connected_name)
               	self.ui.set_right(_('ALTERNATE'))
               	self.ui.show()

	def transfer_call(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.business_option_request_status = 0
		stage = CallTransferNotifyStage
		runtime.manager.stack_stage(stage)

	def conference_call(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.clear_audio_mute()
		status.set_current_audio_mute()
		# hcryoo : [20070518_2]
		status.reset_all_hold_flag()
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_CONFERENCE)
		stage = CallConferenceStage
		runtime.manager.stack_stage(stage)

	def end_call_by_onhook(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.set_modem_audio_state(status.SPK)
		runtime.dspg.change_to_spk()
		status.clear_audio_mute()
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
		runtime.manager.stack_stage(stage)


	def end_call_by_red(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.clear_audio_mute()
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
		runtime.manager.stack_stage(stage)

	def destroy(self):
		self.tag_invite = 0
		self.in_progress = 0
		Stage.destroy(self)

class SecondCallConnectingStage(Stage):
	name = 'SecondCallConnecting'
	in_progress = 0
	def __init__(self):
		status.business_call_status = status.TwoCallOneDialing
		status.toggle_active_call()
		# here we skip set_current_call_status since we received new values for the second call
		status.set_video_mode(status.AudioRequesting)
		status.set_call_time()
		status.save_current_call_status()
		self.held_number = status.display_caller_number(1-status.active_call_index)
		self.held_name = status.display_caller_name(1-status.active_call_index)
		self.connected_number = status.display_caller_number(status.active_call_index)
		self.connected_name = status.display_caller_name(status.active_call_index)
		# eicho add 06.06.23
		self.tmr_softkey2 = False
		# hcryoo : [20070522_2]
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		# hcryoo : [20070522_2]==
		if status.business_option_status == status.CallTransferOption:
			status.business_option_status = status.BlindTransferOption
			self.ui = ui.TwoCallOneConnectingUI(self.connected_name, self.held_name,_('END CALL'),_('TRANSFER'))
			#self.ui = ui.TwoCallOneConnectingUI(self.connected_name, self.held_name,_('END CALL'),'')
			#self.tmr_softkey2 = utils.Timer(1000, self.change_softkey2)
		else:
			self.ui = ui.TwoCallOneConnectingUI(self.connected_name, self.held_name,_('END CALL'),'')
		self.invite_request()

	# eicho remove 06.06.27
	'''
	def change_softkey2(self):
		self.ui.set_right(_('TRANSFER'))
		self.ui.show()
		self.tmr_softkey2 = False
		return False
	'''
	
	def show(self):
		Stage.show(self)
		runtime.evas.render_now()

	def handle_key(self, key):
		if self.in_progress == 0:
			if key == config.Red:
				if status.modem_audio_state == status.SPK:
					#runtime.vdci_stop_tone()
					runtime.SP_context.stopTonePlay()
					if status.business_option_status == status.CallTransferOption:
						self.transfer_request()
					elif status.business_option_status == status.BlindTransferOption:
						self.transfer_request()
					else:
						self.end_connected_call()
					return True
				else:
					return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

			elif key == config.OnHook:
				status.set_modem_audio_state(status.SPK)
				runtime.dspg.change_to_spk()
				#runtime.vdci_stop_tone()
				runtime.SP_context.stopTonePlay()
				if status.business_option_status == status.CallTransferOption:
					self.transfer_request()
				elif status.business_option_status == status.BlindTransferOption:
					self.transfer_request()
					
				else:
					self.end_connected_call()
				return True
			elif key == config.Menu1:
				#runtime.vdci_stop_tone()
				runtime.SP_context.stopTonePlay()
				self.end_connected_call()
				return True
			elif key == config.Menu2:
				#runtime.vdci_stop_tone()
				runtime.SP_context.stopTonePlay()
				if status.business_option_status == status.CallTransferOption:
					self.transfer_request()
					return True
				elif status.business_option_status == status.BlindTransferOption:
					self.transfer_request()
					return True
				else:
					return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True


			elif key == 'Up':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume up

			elif key == 'Down':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume down

			return True

		else:

			if key == config.Red:
				if status.modem_audio_state == status.SPK:
					if status.business_option_status == status.BlindTransferOption or \
						status.business_option_status == status.CallTransferOption:
						self.transfer_call()
					else:
						self.end_connected_call()
					return True
				else:
					return True

			elif key == config.OnHook:
					status.set_modem_audio_state(status.SPK)
					runtime.dspg.change_to_spk()
					if status.business_option_status == status.BlindTransferOption or \
						status.business_option_status == status.CallTransferOption:
						self.transfer_call()
					else:
						self.end_connected_call()
					return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == config.Menu1:
				self.end_connected_call()
				return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

			else:
				return True


		return True

	def invite_request(self):
		import utils
		self.tag_invite = utils.Timer(config.timeoutInvite, self.invite_error)
		uriPolicy, number = utils.checkUrlPolicy(self.remoteID)
		runtime.vdci_send_mesg(code1=config.MESG_OUTGOING_CALL, \
								code2=config.MESG_CALL_AUDIO, \
								mesg1=number, mesg9=uriPolicy)

	def invite_sucessed(self):
		self.tag_invite = 0
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		if status.business_option_status == status.BlindTransferOption:
			self.transfer_call()
		else:
			stage = TwoCallOneHoldStage
			runtime.manager.stack_stage(stage)

	def invite_error(self):
		self.tag_invite = 0
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		if status.business_option_status == status.BlindTransferOption or \
			status.business_option_status == status.CallTransferOption:
			self.transfer_call()
		else:
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			stage = ReleaseHoldBackToConnectedStage(_('Server not responding.')+'\n'+_('Try again.'))
			runtime.manager.stack_stage(stage)

	def transfer_request(self):
		self.in_progress = 1

		if status.business_option_status == status.BlindTransferOption:			
			self.tag_invite = utils.Timer(3000, self.transfer_call)
			self.remoteID = self.connected_number
			runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
			status.toggle_active_call()
			status.set_current_call_status()
			import time
			time.sleep(2)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_TRANSFER, \
						code2=config.MESG_CALL_TRANSFER_BLIND, \
						mesg1=self.remoteID)

		else: # CallTransferOption
			self.tag_invite = utils.Timer(3000, self.transfer_call)
			self.remoteID = self.connected_number
			status.toggle_active_call()
			status.set_current_call_status()
			import time
			time.sleep(2)
			# hcryoo : [20070518_2]
			status.reset_hold_flag(status.active_call_index)
			# hcryoo : [20070518_2]==
			runtime.vdci_send_mesg(code1=config.MESG_CALL_TRANSFER, \
						code2=config.MESG_CALL_TRANSFER_CONSULTATION, \
						mesg1=self.remoteID)

	def transfer_call(self):
		self.tag_invite = 0
		self.in_progress = 0
		stage = CallTransferNotifyStage
		runtime.manager.stack_stage(stage)

	def end_connected_call(self):
		self.tag_invite = 0
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
#ka...3800 2007.06.15 Temporary END Call하면서 윙거리는 소리 문제
		dspg = runtime.dspg
		if status.modem_audio_state == status.HS:
			dspg.set_state(dspg.ST_V_HS_OFFHK)
		else: #status.modem_audio_state == status.SPK:
			dspg.set_state(dspg.ST_V_SPK_OFFHK)
		
		stage = ReleaseHoldBackToConnectedStage(status.display_caller_name(status.active_call_index)+'\n'+_('disconnected.'))
		runtime.manager.stack_stage(stage)

	def destroy(self):
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		self.in_progress = 0
		self.tag_invite = 0
		Stage.destroy(self)

class NotifyMessageBackToOneCallStage(Stage):
	name = 'NotifyMessageBackToOneCall'
	def __init__(self, message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		runtime.manager.back_stage()

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class NotifyMessageBackToTwoCallStage(Stage):
	name = 'NotifyMessageBackToTwoCall'
	def __init__(self, message):
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		runtime.manager.back_stage()

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class SecondCallEnblockEditStage(Stage):
	name = 'SecondCallEnblockEdit'

	def __init__(self):
		#runtime.vdci_play_tone()
		status.business_call_status = status.TwoCallOneDialing
		self.held_number = status.display_caller_number(status.active_call_index)
		self.held_name = status.display_caller_name(status.active_call_index)
		self.ui = ui.TwoCallOneDialingUI(status.dial_number, self.held_name, _('DIAL'), _('DELETE'))
		self.ui.show_bg = True
		self.ui.show_cursor(True)
		self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)

	def remove_dtmf_timer(self):
		if self.dtmf_timer:
			del(self.dtmf_timer)
			self.dtmf_timer = None

	def auto_dial(self):
		from vdcisetting import vdci_setting
		tel_num = status.telnum or vdci_setting.tel_num

# eicho add 06.05.27
		if status.dial_number  == self.held_number:
			runtime.manager.stack_stage(NotifyMessageBackToOneCallStage(_('Cannot dial connected number.')))
			self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
# eicho end.
		elif status.dial_number == tel_num:
			runtime.manager.stack_stage(NotifyMessageBackToOneCallStage(_('Cannot dial yourself.')))
			status.dial_number = ''
			self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
		elif status.dial_number ==  '':
			runtime.manager.stack_stage(NotifyMessageBackToOneCallStage(_('No dialed number')))
			self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
		else:
			if runtime.manager.check_call_barring(status.dial_number, False):
				runtime.manager.stack_stage(NotifyMessageBackToOneCallStage(_('Number blocked.')))
				self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)
			else:
				self.remove_dtmf_timer()
				stage = SecondCallConnectingStage
				runtime.manager.stack_stage(stage)

	def end_second_dialing(self):
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		# change back to previous values before edit
		status.toggle_active_call()
		status.set_current_call_status()
		stage = ReleaseHoldBackToConnectedStage(_('End second dialing'))
		runtime.manager.stack_stage(stage)

	def handle_key(self, key):

		# dtmf key가 입력되고 5000ms 이 자동으로 call을 시도한다
		def do_auto_call():
			self.remove_dtmf_timer()
			if runtime.manager.stage.name != 'SecondCallEnblockEdit':
				return False
			self.auto_dial()
			return False

		self.remove_dtmf_timer()

		if key == '#':
			if status.dial_number:
				self.auto_dial()
			return True

		elif key in '0123456789*':
			#runtime.vdci_stop_tone()
			runtime.SP_context.stopTonePlay()
			self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
			status.dial_number = status.dial_number + key
			self.ui.change_caller_number(status.dial_number)
			self.ui.set_left(_('DIAL'))
			self.ui.set_right(_('DELETE'))
			return True

		elif key == config.Menu1:
			runtime.vdci_stop_tone()
			if not status.dial_number:
				stage = PhoneBookStage
				runtime.manager.stack_stage(stage)
			else:
				self.remove_dtmf_timer()
				self.auto_dial()
			return True

		elif key == config.Menu2:
			if not status.dial_number:
				self.end_second_dialing()
			else:
				self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
				status.dial_number = status.dial_number[:-1]
				self.ui.change_caller_number(status.dial_number)
				if status.dial_number:
					self.ui.set_left(_('DIAL'))
					self.ui.set_right(_('DELETE'))
				else:
					self.ui.set_left(_('PHONEBOOK'))
					self.ui.set_right(_('BACK'))
			return True

		elif key == config.LongMenu2:
			self.remove_dtmf_timer()
			self.dtmf_timer = utils.Timer(config.dtmf_call_time, do_auto_call)
			status.dial_number = ''
			self.ui.change_caller_number(status.dial_number)
			self.ui.set_left(_('PHONEBOOK'))
			self.ui.set_right(_('BACK'))
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				self.end_second_dialing()
				return True
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.change_to_spk()
			self.end_second_dialing()
			return True

		elif key == config.OffHook:
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				runtime.dspg.change_to_handset() # vpark 06.02.08
				#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
				self.ui.show()
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				return False
			else:
				return True

		elif key == 'Up':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume up

		elif key == 'Down':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume down

		return True

	def show(self):
		self.ui.change_caller_number(status.dial_number)
		if status.dial_number:
			self.ui.set_left(_('DIAL'))
			self.ui.set_right(_('DELETE'))
		else:
			self.ui.set_left(_('PHONEBOOK'))
			self.ui.set_right(_('BACK'))

		self.ui.show()

	def end_call_by_onhook(self):
		status.set_modem_audio_state(status.SPK)
		runtime.dspg.change_to_spk()
		self.end_second_dialing()

	def end_call_by_red(self):
		self.end_second_dialing()

	def destroy(self):
		self.tag_invite = 0
		self.remove_dtmf_timer()
		Stage.destroy(self)

class DialSecondCallStage(Stage):
	name = 'DialSecondCall'

	def __init__(self):
#ka...slim Call중에는 image / melody assign할 수 없도록 
		status.phonebook_in_calling = True
#ka...3800 2007.06.15 SecondDialing dial tone play
		dspg = runtime.dspg
		if status.modem_audio_state == status.HS:
			dspg.set_state(dspg.ST_V_HS_OFFHK_LPLAY)
		elif status.modem_audio_state == status.SPK:
			dspg.set_state(dspg.ST_V_SPK_OFFHK_LPLAY)
		
		#runtime.vdci_play_tone(config.PLAY_DIAL_TONE)
		status.business_call_status = status.TwoCallOneDialing
		status.clear_current_call_status()
		self.held_number = status.display_caller_number(status.active_call_index)
		self.held_name = status.display_caller_name(status.active_call_index)
		self.ui = ui.TwoCallOneDialingUI(status.dial_number, self.held_name, _('PHONEBOOK'), _('BACK'))

		self.dtmf_timer = utils.Timer(config.dtmf_first_interdigit_time, self.end_second_dialing)

	def handle_key(self, key):
		self.remove_dtmf_timer()
		if key in '0123456789*#':
			runtime.manager.stack_stage(SecondCallEnblockEditStage)
			runtime.manager.handle_key(True, key)
			return True

		elif key == config.Menu1:
			stage = PhoneBookStage
			runtime.manager.stack_stage(stage)
			return True

		elif key == config.Menu2:
			#runtime.vdci_stop_tone()
			runtime.SP_context.stopTonePlay()
			self.end_second_dialing()
			return True

		elif key == config.Red:
			if status.modem_audio_state == status.SPK:
				self.end_second_dialing()
				return True
			else:
				return True

		elif key == config.OnHook:
			status.set_modem_audio_state(status.SPK)
			runtime.dspg.change_to_spk()
			self.end_second_dialing()
			return True

		elif key == config.OffHook:
			if status.modem_audio_state == status.SPK:
				status.set_modem_audio_state(status.HS)
				runtime.dspg.change_to_handset() # vpark 06.02.08
				#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
				self.ui.show()
				return True
			else:
				return True

		elif key == config.Green:
			if status.modem_audio_state == status.HS:
				return False
			else:
				return True

		elif key == 'Up':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume up

		elif key == 'Down':
			# audio volume
			stage = AudioVolumeStage
			runtime.manager.stack_stage(stage)
			# volume down

		return True

	def remove_dtmf_timer(self):
		if self.dtmf_timer:
			del(self.dtmf_timer)
			self.dtmf_timer = None


	def end_second_dialing(self):
		self.remove_dtmf_timer()
		#runtime.vdci_stop_tone()
		runtime.SP_context.stopTonePlay()
		# change back to previous values before edit
		status.toggle_active_call()
		status.set_current_call_status()
#ka...3800 2007.06.15 Temporary END Call하면서 윙거리는 소리 문제
		if status.modem_audio_state == status.HS:
			runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
		else: #status.modem_audio_state == status.SPK:
			runtime.dspg.set_state(runtime.dspg.ST_V_SPK_OFFHK)
			
		stage = ReleaseHoldBackToConnectedStage(_('End second dialing'))
		runtime.manager.stack_stage(stage)
		
#ka...slim 2007.05.19 options-phonebook list진입해서 OnHook시에 manager.handle_onhook에서 Call
	def end_call_by_onhook(self):
		status.set_modem_audio_state(status.SPK)
		runtime.dspg.change_to_spk()
		self.end_second_dialing()

	def destroy(self):
		status.phonebook_in_calling = False
		self.remove_dtmf_timer()
		Stage.destroy(self)

class CallHoldStage(Stage):
	name = 'CallHold'
	in_progress = 0

	def __init__(self):

		status.phonebook_in_calling = True
		status.waiting = 1
		status.business_call_status = status.OneCallConnected
		self.held_number = status.display_caller_number(status.active_call_index)
		self.held_name = status.display_caller_name(status.active_call_index)
		self.ui = ui.CallHoldUI(self.held_name)

	def handle_key(self, key):
		if self.in_progress == 0:
			if key == config.Menu1:
				self.invite_request()
				return True

			elif key == config.Menu2:
				stage = DialSecondCallStage
				runtime.manager.stack_stage(stage)
				return True

			elif key == config.Red:
				if status.modem_audio_state == status.SPK:
					self.invite_request()
					return True
				else:
					return True

			elif key == config.OnHook:
				status.set_modem_audio_state(status.SPK)
				runtime.dspg.change_to_spk()
				self.invite_request()
				return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

			elif key == 'Up':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume up

			elif key == 'Down':
				# audio volume
				stage = AudioVolumeStage
				runtime.manager.stack_stage(stage)
				# volume down

		else:
			if key == config.OnHook:
				status.set_modem_audio_state(status.SPK)
				runtime.dspg.change_to_spk()
				return True

			elif key == config.OffHook:
				if status.modem_audio_state == status.SPK:
					status.set_modem_audio_state(status.HS)
					runtime.dspg.change_to_handset() # vpark 06.02.08
					#runtime.dspg.set_state(runtime.dspg.ST_V_HS_OFFHK)
					self.ui.show()
					return True
				else:
					return True

			elif key == config.Green:
				if status.modem_audio_state == status.HS:
					return False
				else:
					return True

			elif key == config.Red:
				if status.modem_audio_state == status.SPK:
					self.invite_error()
					return True
				else:
					return True


		return True

	def invite_request(self):
		self.in_progress = 1
		status.set_current_audio_mute()
		self.tag_invite = utils.Timer(config.timeoutReinvite, self.invite_error)
		# hcryoo : [20070518_2]
		status.reset_hold_flag(status.active_call_index)
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, code2=config.MESG_CALL_HOLD_DEACTIVATE)

	def invite_sucessed(self):

		self.tag_invite = 0
		self.in_progress = 0
		status.waiting = 0
		status.business_option_status = status.NotSelected
		status.business_call_status = status.OneCallConnected
		runtime.manager.back_stage('AudioCallConnected')

	def invite_error(self):
		self.tag_invite = 0
		self.in_progress = 0
		# hang up
		stage = HangupStage(_('Server not responding.')+'\n'+_('Audio call terminated.'))
		runtime.manager.stack_stage(stage)

	def destroy(self):
		status.phonebook_in_calling = False
		self.tag_invite = 0
		self.in_progress = 0
		status.waiting = 0
		Stage.destroy(self)


class PreDialingOptionsIPStage(ListStage):
	name = 'PreDialingOptionIP'
	def __init__(self):
		self.title = _('OPTIONS')
		choice = _('Save in phonebook'), _('Show hw/sw version'), _('Telephone number')
		ListStage.__init__(self, choice)

	def activate(self, index):
		number = status.dial_number
		if index == 0: # save in PhoneBook

			# phonedb max size check
			import phonebook, phonedb
			if not status.dial_number:
				stage = NotifyStage(_('No data'), uiconfig.baloon_phonebook_icon)
				runtime.manager.change_stage(stage)
				return
			elif phonedb.phonedb.count() >= config.phone_db_size:
				stage = phonebook.PhonebookNotifyStage(_('Memory full'))
			else:
				stage = SaveStage
			runtime.manager.stack_stage(stage)
			return

		elif index == 1: # show hw/sw version
			runtime.manager.stack_stage(ShowVersionStage)

		elif index == 2:
			runtime.manager.stack_stage(ShowTelnumStage)

	def destroy(self):
		status.waiting = 0
		Stage.destroy(self)

class OptionsIPStage(ListStage):
	name = 'OptionsIP'

	in_progress = 0
	def __init__(self):

		self.title = _('OPTIONS')
		self.tag_invite = 0
		status.save_current_call_status()
		if status.business_call_status == status.OneCallConnected:
			#choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Call hold'), _('Call transfer'), _('Conference'), _('Show hw/sw version'), _('Telephone number') # add tel number
			# KA: [20071105] TI IMS call options
			#choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Call hold'), _('Blind transfer'), _('Consultation transfer'), _('Conference'), _('Show hw/sw version'), _('Telephone number') 
			if status.get_held_flag(status.active_call_index) == True:
				choice = _('Phonebook'),  _('Mute'), _('Audio volume')
			else:
				choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Call hold')
		elif status.business_call_status == status.TwoCallOneDialing:
			choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Call resume'), _('Show hw/sw version'), _('Telephone number')
		elif status.business_call_status == status.TwoCallOneHold:
			#choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Alternate call'), _('Call transfer'), _('Conference'), _('End connected call'), _('Show hw/sw version'), _('Telephone number')
			#choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('Alternate call'), _('Consultation transfer'), _('Conference'), _('End connected call'), _('Show hw/sw version'), _('Telephone number')
			# KA: [20071105] TI IMS call options
			choice = _('Phonebook'),  _('Mute'), _('Audio volume')
		elif status.business_call_status == status.TwoCallConnected:
			choice = _('Phonebook'),  _('Mute'), _('Audio volume'), _('End both calls'), _('Show hw/sw version'), _('Telephone number')
		else:
			choice = _('Accept call'), _('Reject call'),  _('Phonebook'), _('Mute'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')

		self.choice = choice
		ListStage.__init__(self, choice)

		status.phonebook_in_calling = True

	def activate(self, index):
		if self.in_progress == 1:
			return
		elif self.choice[index] == _('Show hw/sw version'):
			runtime.manager.stack_stage(ShowVersionStage)
			return
		elif self.choice[index] == _('Telephone number'):
			runtime.manager.stack_stage(ShowTelnumStage)
			return
		self.index = index
		if status.business_call_status == status.OneCallConnected:
			# KA: [20071105] TI IMS call options
			if index == 3:
				status.business_option_status = status.CallHoldOption
				self.invite_request()
			# KA: [20071105] TI IMS call options ==
			elif index > 2:
				index -= 3
				status.waiting = 0
				option_status = (status.CallHoldOption, status.CallTransferOption, status.CallConferenceOption)[index]
				status.business_option_status = option_status
				self.invite_request() # Backstage does not have invite_request.
			else:
				stage = _ip_stages[index]
				runtime.manager.stack_stage(stage)

		elif status.business_call_status == status.TwoCallOneDialing:
			if index == 3: # Call resume
				runtime.manager.back_stage()
				runtime.manager.stage.invite_request()
			else:
				stage = _ip_stages[index]
				runtime.manager.stack_stage(stage)

		elif status.business_call_status == status.TwoCallOneHold:
			if index > 2:
				index -= 3
				option_status = (status.CallAlternateOption, status.CallTransferOption, status.CallConferenceOption, status.NotSelected)[index]
				status.business_option_status = option_status
				runtime.manager.back_stage()
				runtime.manager.stage.invite_request()
			else:
				stage = _ip_stages[index]
				runtime.manager.stack_stage(stage)

		elif status.business_call_status == status.TwoCallConnected:
			if index == 3: # End both calls
				runtime.manager.back_stage()
				runtime.manager.stage.end_both_calls()
			elif index == 1: # Mute
				runtime.manager.back_stage()
				runtime.manager.stage.mute()
			else:
				stage = _ip_stages[index]
				runtime.manager.stack_stage(stage)

		else: # status.business_call_status == status.TwoCallOneIncoming
			if index < 2: # Accept call & reject call
				runtime.manager.back_stage()
				runtime.manager.stage.invite_request()
			else:
				index -= 2
				stage = _ip_stages[index]
				runtime.manager.stack_stage(stage)

	def invite_request(self):
		#ka...slim 2007.05.22 CallHeld당하면 NewCall을 할 수 없다. 
		if status.get_held_flag(status.active_call_index) == True:
			stage = NotifyStage(_('Service not available.'), icon = uiconfig.baloon_terminated_icon)
			runtime.manager.stack_stage(stage)
			return

		self.in_progress = 1
		self.tag_invite = utils.Timer(config.timeoutReinvite, self.invite_error)
		# Call hold, Call transfer, Call conference when OneCallConnected
		status.release_audio_mute()
		# hcryoo : [20070518_2]
		status.set_hold_flag(status.active_call_index)
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, code2=config.MESG_CALL_HOLD_ACTIVATE)

	def invite_sucessed(self):
		self.tag_invite = 0
		self.in_progress = 0
		# Call hold, Call transfer, Call conference when OneCallConnected
		if status.business_option_status == status.CallHoldOption:
			runtime.manager.back_stage()
			runtime.manager.stack_stage(CallHoldStage)
		else:
			runtime.manager.back_stage()
			runtime.manager.stack_stage(DialSecondCallStage)

	def invite_error(self):
		self.tag_invite = 0
		self.in_progress = 0
		# hang up
		stage = HangupStage(_('Server not responding.')+'\n'+_('Audio call terminated.'))
		runtime.manager.stack_stage(stage)

	def show(self):

		ListStage.show(self)
#		if status.business_call_status == status.OneCallConnected:
			# hcryoo : [20070521_1]
			# KA: [20071105] TI IMS call options
#			'''
		if status.heldline:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))
		else:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))
			if status.waiting:
				self.ui.set_text(3, _('Resume'))
			else:
				self.ui.set_text(3, _('Call hold'))
#			'''
#			if status.waiting:
#				self.ui.set_text(0, _('Resume'))
#			else:
#				self.ui.set_text(0, _('Call hold'))
			# KA: [20071105] TI IMS call options
		'''
		elif status.business_call_status == status.TwoCallOneHold:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))

		elif status.business_call_status == status.TwoCallOneDialing:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))

		elif status.business_call_status == status.TwoCallConnected:
			if status.audio_mute:
				self.ui.set_text(1, _('Enable microphone'))
			else:
				self.ui.set_text(1, _('Mute'))

		else:
			if status.audio_mute:
				self.ui.set_text(3, _('Enable microphone'))
			else:
				self.ui.set_text(3, _('Mute'))
		'''

	def destroy(self):
		self.tag_invite = 0
		self.in_progress = 0
		status.phonebook_in_calling = False
		status.waiting = 0
		ListStage.destroy(self)

class BackToConnectedStage(Stage):
	name = 'BackToConnected'
	def __init__(self,message):
		# release current line
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		# switch to held line
		status.toggle_active_call()
		status.set_current_call_status()
		status.set_current_audio_mute()

		# initialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.business_option_status = status.NotSelected
		status.business_option_request_status = 0

		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)
	def next(self):
		self.tag_invite = 0
		runtime.manager.change_stage(AudioCallConnectedStage, True)

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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

class BackToHoldStage(Stage):
	name = 'BackToHold'
	def __init__(self,message):
		# release current line
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		# switch to held line
		status.toggle_active_call()
		status.set_current_call_status()
		status.set_current_audio_mute()

		# initialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.business_option_status = status.CallHoldOption
		status.business_option_request_status = 0

		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		runtime.manager.change_stage(AudioCallConnectedStage, True)
		runtime.manager.stack_stage(CallHoldStage)

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

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


class ReleaseHoldBackToConnectedStage(Stage):
	name = 'ReleaseHoldBackToConnected'
	def __init__(self,message):
		# release current line
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		# switch to held line
		status.toggle_active_call()
		status.set_current_call_status()

		# initialize business option
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.business_option_status = status.NotSelected
		status.business_option_request_status = 0
		# release hold
		status.set_current_audio_mute()
		# hcryoo : [20070518_2]
		status.reset_hold_flag(status.active_call_index)
		# hcryoo : [20070518_2]==
		runtime.vdci_send_mesg(code1=config.MESG_CALL_HOLD, code2=config.MESG_CALL_HOLD_DEACTIVATE)
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def show(self):
		Stage.show(self)
		runtime.evas.render_now()

	# eicho add 06.02.02
	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True
	# eicho end.

	def next(self):
		self.tag_invite = 0
		runtime.manager.change_stage(AudioCallConnectedStage, True)

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

class HangupStage(Stage):
	name = 'HangUp'
	def __init__(self,message):
		status.waiting = 0
		status.business_call_status = status.OneCallConnected
		status.videocall_mode = status.VideoCallDisconnected
		status.business_option_status = status.NotSelected
		status.phone_status = status.Disconnected
		runtime.vdci_send_mesg(code1=config.MESG_HANGUP)
		runtime.manager.handle_second_call_log()
		status.release_channel()
		status.reset_call_status()
		status.clear_current_call_status()
		icon = uiconfig.connected_icon
		self.ui = baseui.NotifyUI(message, icon)
		self.tag_invite = utils.Timer(3000, self.next)

	def next(self):
		self.tag_invite = 0
		if status.modem_audio_state == status.SPK:
			status.set_modem_audio_state(status.IDLE)
			runtime.dspg.set_state(runtime.dspg.ST_IDLE)
		runtime.manager.change_stage(IdleStage, True)

	def handle_key(self, key):
		self.next()
		runtime.manager.stage.handle_key(key)
		return True

def PhoneBookStage():
	import phonebook
	return phonebook.get_phonebook_stage()

def MuteStage():
	status.toggle_audio_mute()
	import profile
	if profile.ip_mode == 1:
		pass
	else: # PSTN
		if status.videocall_mode == status.VideoCallConnected:
			pass
		else:
			if status.audio_mute and status.waiting:
				status.toggle_waiting()
	def cb():
		runtime.manager.queue_backward(2)
	return TempStage(cb)

def AudioVolumeStage():
	from phonesetting import AudioVolumeStage
	return AudioVolumeStage()

def WaitingStage():
	status.toggle_waiting()
	if status.waiting and status.audio_mute:
		status.toggle_audio_mute()
	def cb():
		runtime.manager.queue_backward(2)
	return TempStage(cb)

def VideoFluencyStage():
	import videosetting
	return videosetting.VideoFluencyStage()

class SaveStage(EntryStage):
	# Page 18
	def __init__(self):
		EntryStage.__init__(self, _('Name'), _('SAVE IN PHONEBOOK'))
		self.ui.set_max(config.max_pb_name)
		self.ui.set_left('')
		# KA: [20070831] hangul lvp-2000
		# vpark 2006.08.28 automata		
		#self.ui.set_automata('multitap', 'lower')
		#self.ui.automata_idx = 3
		self.ui.set_fixed_automata(None, False)

	def handle_key(self, key):
		if key == config.Red:
			self.activate_menu2()
			return True
		ret = EntryStage.handle_key(self, key)
		if ret and self.is_active():
			if self.ui.get_text() == '':
				self.ui.set_left('')
				return True
			else:
				self.ui.set_left(_('SAVE'))
		return ret

	def activate_menu1(self):
		if self.ui.get_text() == '':
			return
		import phonedb, phonebook
		icon = uiconfig.baloon_phonebook_icon
		name = self.ui.get_text()
		if not (name or status.dial_number):
			stage = NotifyStage(_('No data'), icon)
			runtime.manager.change_stage(stage)
			return
		status.phone_item = phonedb.PhoneItem()
		status.phone_item.name = name
		if len(status.dial_number) > config.max_phone_number:
			number = status.dial_number[:config.max_phone_number]
		else:
			number = status.dial_number
		status.phone_item.number = number
		status.phonebook_save_stage_name = 'predial options'
		if phonedb.phonedb.has_name(name):
			# name complict
			stage = phonebook.NameConflictStage()
			runtime.manager.stack_stage(stage)
			return
		phonebook.phone_item_save()

class OptionsPreDialStage(ListStage):
	name = 'predial options'
	def __init__(self):
		self.title = _('OPTIONS')

		import profile
		if profile.ip_mode == 0:
			self.choice = _('Save in phonebook'), _('Hide number'), _('Insert pause'), _('Flash R'), _('Show hw/sw version'), _('Telephone number')
		else:
			self.choice = _('Save in phonebook'), _('Show hw/sw version'), _('Telephone number')
		ListStage.__init__(self, choice=self.choice)

	def activate(self, index):
		choice = self.choice[index]
		number = status.dial_number
		if choice == _('Save in phonebook'):
			# phonedb max size check
			import phonebook, phonedb
			if not status.dial_number:
				stage = NotifyStage(_('No data'), uiconfig.baloon_phonebook_icon)
				runtime.manager.change_stage(stage)
				return
			elif phonedb.phonedb.count() >= config.phone_db_size:
				stage = phonebook.PhonebookNotifyStage(_('Memory full'))
			else:
				stage = SaveStage
			runtime.manager.stack_stage(stage)
			return
		elif choice == _('Hide number'):
			# Insert Hide Number
			status.set_dial_number(config.FAC_HIDE_ID_CODE + status.dial_number)
			runtime.manager.back_stage()
		elif choice == _('Insert pause'):
			# insert Pause
			status.set_dial_number(status.dial_number + 'P')
			runtime.manager.back_stage()
		elif choice == _('Flash R'):
			# insert Flash
			status.set_dial_number(status.dial_number + 'R')
			runtime.manager.back_stage()
		elif choice == _('Show hw/sw version'):
			runtime.manager.stack_stage(ShowVersionStage)
		elif choice == _('Telephone number'):
			runtime.manager.stack_stage(ShowTelnumStage)


class ShowTelnumUI(baseui.SmallWindowUI):
	def __init__(self):
		# eicho add subtitle 'Telephone num.' 06.02.06
		# baseui.SmallWindowUI.__init__(self, '', _('BACK'), _('TELEPHONE NUMBER') )
		baseui.SmallWindowUI.__init__(self, '', _('BACK'), _('TELEPHONE NUMBER'), _('Telephone num.'))
		# eicho end
		t, font = utils.resize_text(status.telnum, 280, font=uiconfig.notify_font)
		self.tel = runtime.evas.text(text=t, pos = (20, 110), font=uiconfig.notify_font, color = uiconfig.list_text_color)
		self.add(self.tel)

class ShowTelnumStage(Stage):
	def __init__(self):
		self.ui = ShowTelnumUI()

	def handle_key(self, key):
		if key == config.Menu2:
			runtime.manager.back_stage()
		return False

class OptionsAnalogStage(ListStage):
	""" Page 19 """
	def __init__(self):
		self.title = _('OPTIONS')
		self.choice = _('Phonebook'), _('Mute'), _('Audio volume'), _('Waiting'), _('Flash R'), _('New call'), _('Show hw/sw version'), _('Telephone number')

		ListStage.__init__(self)
		status.phonebook_in_calling = True

	def destroy(self):
		status.phonebook_in_calling = False
		ListStage.destroy(self)

	def activate(self, index):
		if index == 4: # Flash R
			# Flash
			# eicho add 06.02.01
			if status.waiting == 1:	# waiting is enabled.
				status.toggle_waiting()
			# eicho end.
			runtime.dspg.send_dtmf('R', False)
			if status.dial_number:
				status.set_dial_number(status.dial_number + 'R')
			runtime.manager.back_stage('connected')
			if status.dial_number:
				runtime.manager.stage.update_number()
			return
		elif index == 5: # new call
			status.audio_mute = 0 # vpark 12.17 release mute
			runtime.manager.stack_stage(PSTNDialSecondCallStage)
			return
		stage = _analog_stages[index]
		runtime.manager.stack_stage(stage)

	def show(self):
		ListStage.show(self)
		if status.audio_mute:
			self.ui.set_text(1, _('Enable microphone'))
		else:
			self.ui.set_text(1, _('Mute'))
		if status.waiting:
			self.ui.set_text(3, _('Disable wait'))
		else:
			self.ui.set_text(3, _('Waiting'))

class OptionsVideoStage(ListStage):
	""" Page 19 """
	name = 'OptionsVideo'
	def __init__(self):
		self.title = _('OPTIONS')

		os.system('fb0top 1')

		# hcryoo : [20070426_1]
		if status.heldline == 1:
			if status.supervision_remote == 1:
				self.choice = _('Phonebook'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')
			else:
				self.choice = _('Phonebook'), _('Mute'),  _('Audio volume'), _('Show hw/sw version'), _('Telephone number')	
		elif status.videocall_show_details == status.VideoDetailsShow:
		# hcryoo : [20070426_1]==
			if status.supervision_remote == 1:
				self.choice = _('Hide details'), _('Video Quality'), _('Phonebook'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')
			else:
				self.choice = _('Hide details'), _('Video Quality'), _('Phonebook'), _('Mute'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')
		else:
			if status.supervision_remote == 1:
				self.choice = _('Show details'), _('Video Quality'), _('Phonebook'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')
			else:
				self.choice = _('Show details'), _('Video Quality'), _('Phonebook'), _('Mute'), _('Audio volume'), _('Show hw/sw version'), _('Telephone number')

		status.phonebook_in_calling = True
		ListStage.__init__(self)

	def destroy(self):
		status.phonebook_in_calling = False
		ListStage.destroy(self)

	def activate(self, index):
		# hcryoo : [20070426_1]
		if status.heldline == 1:
			index += 2
		# hcryoo : [20070426_1]==
		if index == 0:
			runtime.manager.back_stage('VideoCallConnected')
			if status.videocall_show_details == status.VideoDetailsShow:
				runtime.manager.stage.hide_detail_info()
			else:
				runtime.manager.stage.show_detail_info()
		else:
			if status.supervision_remote == 1 and index > 2:
				index += 1

			stage = _video_stages[index]
			runtime.manager.stack_stage(stage)

	def change_details_text_to_hide(self):
		status.videocall_show_details = status.VideoDetailsHide
		self.show()
		runtime.evas.render_now()

	def show(self):
		ListStage.show(self)

		# hcryoo : [20070426_1]
		if status.heldline == 1:
			if status.supervision_remote != 1:
				if status.audio_mute:
					self.ui.set_text(1, _('Enable microphone'))
				else:
					self.ui.set_text(1, _('Mute'))
		else:
			if status.supervision_remote != 1:
				if status.audio_mute:
					self.ui.set_text(3, _('Enable microphone'))
				else:
					self.ui.set_text(3, _('Mute'))
			if status.videocall_show_details == status.VideoDetailsShow:
				self.ui.set_text(0, _('Hide details'))
			else:
				self.ui.set_text(0, _('Show details'))
		# hcryoo : [20070426_1]==

_ip_stages = PhoneBookStage, MuteStage, AudioVolumeStage
_analog_stages = PhoneBookStage, MuteStage, AudioVolumeStage, WaitingStage, None, None, ShowVersionStage, ShowTelnumStage
_video_stages = None, VideoFluencyStage, PhoneBookStage, MuteStage,  AudioVolumeStage, ShowVersionStage, ShowTelnumStage