# -*- coding: euc-kr -*-

#-------------------------------------------------------------------------------
# Name:		trafficHandler
# Purpose:	 MMI¿Í ±³ÅëÁ¤º¸°£¿¡ »ç¿ëµÇ´Â ÇÔ¼ö¸¦ Á¤ÀÇÇÑ´Ù.
#
# Author:	  ·ùÈ£Ã¢
#
# Created:	 05-04-2008
# Copyright:   (c) LG-Nortel 2007
# Licence:	 <Ryoo Ho Chang GGU!>
#-------------------------------------------------------------------------------
import os
import socket

import runtime
from runtime import mmiDebug as MD 
import config
import status
import utils
import struct
from setting import setting 

class TrafficHandler:
	SOCKET_BUF_SIZE			= 512

	GET_IMAGE_STREAM	= 0x0102
	STOP_IMAGE_STREAM	= 0x0103

	H263 = 'H263'
	H263_CODE = '34'
	H264 = 'H264'
	H264_CODE = '98'

	QCIF 	= '0' # 176x144
	CIF 		= '1' # 352x288
	QVGA	= '2' # 320x240
	SQCIF	= '3' # 128x96
	VGA		= '4' # 640x480

	REMOTESMALL_LOCALSMALL 						= '0'
	REMOTEBIG_LOCALTINY_RIGHTBOTTOM 				= '1'
	REMOTEBIGONLY 									= '2'
	REMOTESMALL_CENTER 							= '3'
	REMOTEBIG_LOCALSMALL 							= '4'
	REMOTESMALLONLY								= '5'
	REMOTESMALL_LEFTTOP_LOCALSMALL_RIGHTBOTTOM 	= '6'
	LOCALSMALL_CENTER 								= '7'
	WQVGA_REMOTEBIGONLY_WQVGA 					= '8' # 480x272
	WQVGA_REMOTEBIGONLY_CIF 						= '9' # 352x272
	WQVGA_REMOTEBIG_LOCALSMALL_RIGHTTOP 			= '10'
	WQVGA_REMOTEBIG_LOCALSMALL_RIGHTBOTTOM 		= '11'
	
	def __init__(self, cid, x, y, screenWidth, screenHeight):
		self.trafficHandler_pid = None
		self.trafficClientSocket = None
		self.trafficReceveHandler = None

		self.with_error = False

		#self.trafficHost = '210.183.241.147'
		#self.trafficPort = '8888'
		
		self.trafficHost = config.TRAFFICHOST
		self.trafficPort = int(config.TRAFFICPORT)

		self.cid = int(cid[6:])
		self.x = x
		self.y = y
		self.screenWidth = screenWidth
		self.screenHeight = screenHeight

		self.runTrafficHandler()

	def destroy(self):
		import signal
		if self.trafficReceveHandler != None:
			runtime.evas.input_remove(self.trafficReceveHandler)
			self.trafficReceveHandler = None
			
		self.trafficClientSocket.close()
		self.stopTrafficStream()

	def runTrafficHandler(self):
		MD.mmiTrace('TrafficHandler.runTrafficHandler()')

		self.trafficClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.trafficClientSocket.setblocking(False)
		self.trafficClientSocket.settimeout(5)
		
		import time
		try_connect = 0
		while try_connect < 5:
			try_connect += 1
			connected = True
			try:
				self.trafficClientSocket.connect((self.trafficHost, self.trafficPort))
			except:
				connected = False

			if connected:
				MD.mmiTrace('**  traffic server socket connected! **')
				import evas
				self.trafficReceveHandler=runtime.evas.input_add(self.trafficClientSocket.fileno(), evas.INPUT_READ, self.messageHandlerFromTraffic)
				break
			else: # sock connect error, retry..
				MD.mmiTrace('** traffic server socket  connect failed, retry', try_connect, '**')
				time.sleep(1)

	def messageHandlerFromTraffic(self,trafficClientSocket,type):
		import status
		try:
			socketMessage = self.trafficClientSocket.recv( self.SOCKET_BUF_SIZE )
		except:
			self.with_error = True
			MD.mmiException('messageHandlerFromVm')
			return
			
		if len( socketMessage ) == 0:	# Disconnected from unix socket
			if self.trafficReceveHandler != None:
				runtime.evas.input_remove(self.trafficReceveHandler)
				self.trafficReceveHandler = None
			return

		msgLen = len(socketMessage)
		MD.mmiTrace('RECEIVE Traffic Server ==> BASE')
		#print 'ka..................received msg=', socketMessage
		#print 'ka..................received msg len=', msgLen
		# ¸Þ½ÃÁö ÇÑ°³ÀÇ max length 76
		messages = []
		numOfMsg = msgLen / 76
		for i in range(numOfMsg):
			messages.append(socketMessage[:76])
			socketMessage = socketMessage[77:]
			if len(socketMessage) < 76:
				break
		MD.mmiTrace('Messages form Traffic server=', messages)		

		for item in messages:
			#for i in range(76):
			#	MD.mmiTrace(i, '=', ord(item[i]))		
			signalingHeader = struct.unpack('II16sI8s16sI8sIII', item)
			MD.mmiTrace('Response form Traffic server')
			self.T2B_response(signalingHeader)
				
		return True


	def B2T_sendMessage(self, B2T_message):
		msgLen = len(B2T_message)
		
		MD.mmiTrace('SEND BASE ==> Traffic Server')
		for i in range(msgLen):
			MD.mmiTrace(i, '=', ord(B2T_message[i]))
			
		if self.trafficClientSocket != None:
			try:
				self.trafficClientSocket.send(B2T_message)
			except:
				pass

	def B2T_GetImageStream(self):
		MD.mmiTrace('==> B2T_sendMessage : GET_IMAGE_STREAM')
		
		command = self.GET_IMAGE_STREAM

		uiCommand = struct.pack('I', command)
		uiCid = struct.pack('>I', self.cid)
		
		#from profile import profile, lan_profile, wifi_profile, dns_profile
		
		#print 'lan_profile = ', lan_profile.show_items()
		#print 'cur_profile = ', cur_profile
		import phonesetting
		terminalIp = '0.0.0.0'
		terminalIpInfo = phonesetting.getIpAddress()
		if terminalIpInfo:
			terminalIp = terminalIpInfo[0]

		#print '=+++++++++++++++> ', terminalIp
		szVideoIp = struct.pack('16s', terminalIp)

		uiVideoPort = struct.pack('I', 50000)
		uiVideoCodec = struct.pack('8s', self.H263)

		szAudioIp = struct.pack('16s', '')
		uiAudioPort = struct.pack('I', 0)
		szAudioCodec = struct.pack('8s', '')
		

		uiWidth = struct.pack('I', 352)
		uiHeight = struct.pack('I', 288)
		uiReturnCode = struct.pack('I', 0)

		B2T_message = [uiCommand, uiCid, szVideoIp, uiVideoPort, uiVideoCodec, szAudioIp, uiAudioPort, szAudioCodec, uiWidth, uiHeight, uiReturnCode]		
		#B2T_message = [uiCommand, uiCid, szVideoIp, uiVideoPort, uiVideoCodec, uiWidth, uiHeight, uiReturnCode]		

		B2T_messageString = ''.join(B2T_message)

		self.B2T_sendMessage(B2T_messageString)

	def B2T_StopImageStream(self):
		MD.mmiTrace('==> B2T_sendMessage : STOP_IMAGE_STREAM')
		
		command = self.STOP_IMAGE_STREAM

		uiCommand = struct.pack('I', command)
		uiCid = struct.pack('>I', self.cid)

		from profile import profile, lan_profile, wifi_profile, dns_profile
		
		#cur_profile = profile.get_profile()
		#if cur_profile == 1: # LAN
		#	terminalIp = lan_profile.ipaddress
		#else:
		#	terminalIp = wifi_profile.ipaddress
		import phonesetting
		terminalIp = '0.0.0.0'
		terminalIpInfo = phonesetting.getIpAddress()
		if terminalIpInfo:
			terminalIp = terminalIpInfo[0]
			
		szVideoIp = struct.pack('16s', terminalIp)

		uiVideoPort = struct.pack('I', 50000)
		uiVideoCodec = struct.pack('8s', self.H263)

		szAudioIp = struct.pack('16s', '')
		uiAudioPort = struct.pack('I', 0)
		szAudioCodec = struct.pack('8s', '')
		
		uiWidth = struct.pack('I', 352)
		uiHeight = struct.pack('I', 288)
		uiReturnCode = struct.pack('I', 0)

		B2T_message = [uiCommand, uiCid, szVideoIp, uiVideoPort, uiVideoCodec, szAudioIp, uiAudioPort, szAudioCodec, uiWidth, uiHeight, uiReturnCode]		
		#B2T_message = [uiCommand, uiCid, szVideoIp, uiVideoPort, uiVideoCodec, uiWidth, uiHeight, uiReturnCode]		

		B2T_messageString = ''.join(B2T_message)

		self.B2T_sendMessage(B2T_messageString)
		# ka...for test stop to VDCI 2008.06.16
		self.stopTrafficStream()

	def startTrafficStream(self, localPort, serverIp, serverPort, videoCodec, videoSize, x, y, width, height, top):
		self.stopTrafficStream()
		runtime.vdciapp.send_mesg( \
			code1=config.MESG_TRAFFIC_INFO, \
			code2=config.MESG_TRAFFIC_INFO_PLAY, \
			mesg1=localPort, \
			mesg2=serverIp, \
			mesg3=serverPort, \
			mesg4=videoCodec, \
			mesg5=videoSize, \
			mesg6=x, \
			mesg7=y, \
			mesg8=width, \
			mesg9=height, \
			mesg10=top)

	def stopTrafficStream(self):
		runtime.vdciapp.send_mesg(code1=config.MESG_TRAFFIC_INFO, code2=config.MESG_TRAFFIC_INFO_STOP)
		
	def T2B_response(self, T2B_message):
		uiCommand, uiCid, szVideoIp, uiVideoPort, szVideoCodec, szAudioIp, uiAudioPort, szAudioCodec, uiWidth, uiHeight, uiReturnCode = T2B_message
		#uiCommand, uiCid, szVideoIp, uiVideoPort, szVideoCodec, uiWidth, uiHeight, uiReturnCode = T2B_message
		#print 'ka............uiReturnCode / uiCommand =', uiReturnCode, uiCommand
		if uiReturnCode == 0:
			MD.mmiTrace('Á¤»ó')
			if uiCommand == self.GET_IMAGE_STREAM:
				videoCodec = self.getVideoCodec(szAudioCodec)
				videoSize = self.getVideoSize(uiWidth, uiHeight)
				top = '0' # VC02 ³»ºÎÀÇ z order ex. PnP
				#self.startTrafficStream(uiVideoPort, self.trafficHost, str(self.trafficPort), videoCodec, videoSize, self.x, self.y, self.screenWidth, self.screenHeight, top)
				# use arbitrary value for server ip and port because there is no information from server.
				self.startTrafficStream(uiVideoPort, '10.10.10.10', '50000', self.H263_CODE, self.CIF, self.x, self.y, self.screenWidth, self.screenHeight, top)
				runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Á¤»ó')
				return
			elif uiCommand == self.STOP_IMAGE_STREAM:
				self.stopTrafficStream()
				self.destroy()
				#runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Á¤»ó')			
			else:
				MD.mmiTrace('Error in T2B_response command')
		elif uiReturnCode == 100:
			MD.mmiTrace('¿µ»ó ¼ö½Å ºÒ°¡')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, '¿µ»ó ¼ö½Å ºÒ°¡')
		elif uiReturnCode == 101:
			MD.mmiTrace('unknown cid')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'unknown cid')
		elif uiReturnCode == 102:
			MD.mmiTrace('¾ÆÀÌÇÇ ¾îµå·¹½º ¿¡·¯ - ¿µ»ó')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, '¾ÆÀÌÇÇ ¾îµå·¹½º ¿¡·¯ - ¿µ»ó')
		elif uiReturnCode == 103:
			MD.mmiTrace('Æ÷Æ® ¿¡·¯ - ¿µ»ó')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Æ÷Æ® ¿¡·¯ - ¿µ»ó')
		elif uiReturnCode == 104:
			MD.mmiTrace('¾ÆÀÌÇÇ ¾îµå·¹½º ¿¡·¯ -À½¼º')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, '¾ÆÀÌÇÇ ¾îµå·¹½º ¿¡·¯ -À½¼º')
		elif uiReturnCode == 105:
			MD.mmiTrace('Æ÷Æ® ¿¡·¯ - À½¼º')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Æ÷Æ® ¿¡·¯ - À½¼º')
		elif uiReturnCode == 106:
			MD.mmiTrace('Àü¼Û ½ÇÆÐ(sending port »ý¼º ½ÇÆÐ )')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Àü¼Û ½ÇÆÐ(sending port »ý¼º ½ÇÆÐ )')
		elif uiReturnCode == 107:
			MD.mmiTrace('Áö¿øÇÏÁö ¾Ê´Â ¿µ»ó ÄÚµ¦')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Áö¿øÇÏÁö ¾Ê´Â ¿µ»ó ÄÚµ¦')
		elif uiReturnCode == 108:
			MD.mmiTrace('Áö¿øÇÏÁö ¾Ê´Â ÇØ»óµµ')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Áö¿øÇÏÁö ¾Ê´Â ÇØ»óµµ')
		elif uiReturnCode == 109:
			MD.mmiTrace('Áö¿øÇÏÁö ¾Ê´Â ¿µ»ó ÄÚµ¦')
			runtime.myannapp.send_videostream_start_result(uiReturnCode, 'Áö¿øÇÏÁö ¾Ê´Â ¿µ»ó ÄÚµ¦')
		self.stopTrafficStream()
		
	def getVideoCodec(self, szVideoCodec):
		if szVideoCodec == 'H263':
			return self.H263_CODE
		elif szVideoCodec == 'H264':
			return self.H264_CODE

	def getVideoSize(self, screenWidth, screenHeight):
		if screenWidth == 176:
			if screenHeight == 144:
				return self.QCIF
		elif screenWidth == 352:
			if screenHeight == 288:
				return self.CIF
		elif screenWidth == 320:
			if screenHeight == 240:
				return self.QVGA
		elif screenWidth == 128:
			if screenHeight == 96:
				return self.SQCIF
		elif screenWidth == 640:
			if screenHeight == 480:
				return self.VGA

		MD.mmiTrace('Error in Return Size')

