#!/usr/bin/python2.5

#
# mSideShow
# Created by Pete Foster (xMob)
#
# THIS SOFTWARE IS NOT FOR GENERAL RELEASE
# Distribution in any form is not permitted without
# express permission.
#
# Contributors
# David Clark - Multiline text rendering (http://www.pygame.org/pcr/text_rect/index.php)
#
# Expect
# Bugs
# Crashes
# Lockups
# Typos
# Bad weather


import time
import pygame
import bluetooth
import dbus
import logging
import uuid
import platform

from cStringIO import StringIO

import ss_multiline as multiline

VERSION = "0.0.1"

#if platform.machine() == "armv6l":
#	PLATFORM = "n800"
#else:
#	PLATFORM = "other"
# Hard coding this while beta testing is taking place.
PLATFORM = "n800"

if PLATFORM == "n800":
	import osso
	osso_c = osso.Context("osso_test_device_on", "0.0.1", False)
	device = osso.DeviceState(osso_c)

logging.basicConfig(level=logging.DEBUG,)
log = logging.getLogger("mSideShow")

class SideShowApp():
	def __init__(self):
		log.debug("Starting up")
		log.debug(platform.machine())
		
		self.CONNECTED = False
		self.packet_count = 0

		self.sid = "S-1-5-4"
		self.user = ""
		
		self.on_ac = False
		self.bat_level = 0
		
		self.apps_guid = []
		self.apps_name = []
		self.apps_icon = []
		self.apps_glance = []
		
		self.msg = ""
		self.msg_time = time.time()
	
		pygame.init()
	
		if PLATFORM == "n800":
			device.display_state_on()
			device.display_blanking_pause()
			self.screen = pygame.display.set_mode((800, 480), pygame.FULLSCREEN)
			pygame.mouse.set_visible(False)
		else:
			self.screen = pygame.display.set_mode((800, 480))
			
		self.bg = pygame.image.load("/usr/share/pixmaps/ss_bg.png")
		self.bar_bg = pygame.image.load("/usr/share/pixmaps/ss_bar.png")
		self.box_bg = pygame.image.load("/usr/share/pixmaps/ss_front_box.png")
		self.msg_box_bg = pygame.image.load("/usr/share/pixmaps/ss_msg_box.png")
		self.icon_exit = pygame.image.load("/usr/share/pixmaps/ss_icon_exit.png")
		self.icon_bt = pygame.image.load("/usr/share/pixmaps/ss_icon_bt.png")
		self.icon_bat_charging = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_charging.png")
		self.icon_bat_0 = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_0.png")
		self.icon_bat_25 = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_25.png")
		self.icon_bat_50 = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_50.png")
		self.icon_bat_75 = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_75.png")
		self.icon_bat_100 = pygame.image.load("/usr/share/pixmaps/ss_icon_bat_100.png")
		
		self.version_f = pygame.font.Font(None, 12)
		self.def_f = pygame.font.Font(None, 18)
		self.user_f = pygame.font.Font(None, 20)
		self.clock_f = pygame.font.Font("/usr/share/fonts/DigitalDream.ttf", 24)
		
		self.drawFront()
		
		self.newMsg("Starting Bluetooth services", time.time())
		
		self.initBT()
		
	def run(self):
		self.drawFront()
		last_redraw = time.time()
		last_packet = time.time()
		# Just a temp loop while we get things set up
		self.RUNNING = True
		while self.RUNNING:
			if (time.time() - last_redraw) >= 5:
				last_redraw = time.time()
				self.drawFront()
				if not self.CONNECTED:
					self.newMsg("Retrying connection to SideShow server", time.time())
					self.BTclient()
			
			event = pygame.event.poll()
			if event.type == pygame.QUIT:
				self.byebye()
			elif event.type == pygame.MOUSEBUTTONDOWN:
				if self.icon_exit_r.collidepoint(event.pos):
					self.byebye()
				else:
					pygame.image.save(self.screen, "screenshot.tga")
			elif event.type == pygame.KEYUP:
				if (event.key == 287):
					pygame.display.toggle_fullscreen()
			if self.CONNECTED:
				# Are we still connected?
				if (time.time() - last_packet) >= 30:
					self.newMsg("Checking connection", time.time())
					self.send_PING()
				try:
					self.data = self.client_sock.recv(32768)
				except:
					self.data = ""
				if len(self.data) != 0:
					last_packet = time.time()
					if PLATFORM == "n800":
						device.display_state_on()
						device.display_blanking_pause()
					self.listener()
				
			# Let's see if we can check the battery here
			if PLATFORM == "n800":
				bus = dbus.SystemBus()
				hal_obj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
				hal = dbus.Interface(hal_obj, 'org.freedesktop.Hal.Manager')
				dev_obj = bus.get_object("org.freedesktop.Hal", hal.FindDeviceByCapability("battery")[0])
				dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
				#props = dev.GetAllProperties()
				#log.debug(props)
				self.bat_level = dev.GetProperty('battery.charge_level.percentage')
				if dev.GetProperty('battery.rechargeable.is_charging'):
					self.on_ac = True
				else:
					self.on_ac = False
			else:
				bus = dbus.SystemBus()
				hal_obj = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
				hal = dbus.Interface(hal_obj, 'org.freedesktop.Hal.Manager')
				dev_obj = bus.get_object("org.freedesktop.Hal", hal.FindDeviceByCapability("ac_adapter")[0])
				dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
				if dev.GetProperty('ac_adapter.present'):
					self.on_ac = True
				else:
					self.on_ac = False
					dev_obj = bus.get_object("org.freedesktop.Hal", hal.FindDeviceByCapability("battery")[0])
					dev = dbus.Interface(dev_obj, "org.freedesktop.Hal.Device")
					self.bat_level = dev.GetProperty('battery.charge_level.percentage')
		
	def newMsg(self, msg, when):
		self.msg = msg
		self.msg_time = when
		self.drawFront()
						
	def byebye(self):
		self.newMsg("Quitting", time.time())
		log.debug("Shutting down")
		self.endBT()
		self.RUNNING = False
					
	def drawFront(self):
		self.bg_r = self.bg.get_rect()
		self.screen.blit(self.bg, self.bg_r)
		
		self.drawBar()
		
		self.drawGadgets()
		
		self.drawMsg()
		
		pygame.display.flip()
		
		if PLATFORM == "n800":
			device.display_state_on()
			device.display_blanking_pause()
		
	def drawBar(self):
		self.bar_bg_r = self.bar_bg.get_rect()
		self.bar_bg_r.left = 0
		self.bar_bg_r.top = (self.screen.get_height() - self.bar_bg_r.height)
		self.screen.blit(self.bar_bg, self.bar_bg_r)
		
		self.icon_exit_r = self.icon_exit.get_rect()
		self.icon_exit_r.left = 10
		self.icon_exit_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.icon_exit_r.height / 2)
		self.screen.blit(self.icon_exit, self.icon_exit_r)
		
		self.drawClock()
		
		self.drawBattery()
		
		if self.CONNECTED:
			self.icon_bt_r = self.icon_bt.get_rect()
			self.icon_bt_r.right = self.icon_bat_r.left - 3
			self.icon_bt_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.icon_bt_r.height / 2)
			self.screen.blit(self.icon_bt, self.icon_bt_r)
		
		if self.user != "":
			self.user_t = self.user_f.render(self.user, 1, (255, 255, 255))
			self.user_t_r = self.user_t.get_rect()
			self.user_t_r.left = self.icon_exit_r.right + 10
			self.user_t_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.user_t_r.height / 2)
			self.screen.blit(self.user_t, self.user_t_r)
			
		self.version_t = self.version_f.render(VERSION, 1, (255, 255, 255))
		self.version_t_r = self.version_t.get_rect()
		self.version_t_r.right = self.screen.get_width() - 2
		self.version_t_r.bottom = self.bar_bg_r.top - 2
		self.screen.blit(self.version_t, self.version_t_r)

	def drawBattery(self):
		if self.on_ac == True:
			self.icon_bat_r = self.icon_bat_charging.get_rect()
			self.icon_bat_r.right = self.clock_t_r.left - 10
			self.icon_bat_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.icon_bat_r.height / 2)
			self.screen.blit(self.icon_bat_charging, self.icon_bat_r)
		else:
			if self.bat_level >= 75:
				self.icon_bat_r = self.icon_bat_100.get_rect()
				bat_icon = self.icon_bat_100
			if self.bat_level <= 75:
				self.icon_bat_r = self.icon_bat_75.get_rect()
				bat_icon = self.icon_bat_75
			if self.bat_level <= 50:
				self.icon_bat_r = self.icon_bat_50.get_rect()
				bat_icon = self.icon_bat_50
			if self.bat_level <= 25:
				self.icon_bat_r = self.icon_bat_25.get_rect()
				bat_icon = self.icon_bat_25
			if self.bat_level <= 10:
				self.icon_bat_r = self.icon_bat_0.get_rect()
				bat_icon = self.icon_bat_0
			
			self.icon_bat_r.right = self.clock_t_r.left - 10
			self.icon_bat_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.icon_bat_r.height / 2)
			self.screen.blit(bat_icon, self.icon_bat_r)
		
	def drawClock(self):
		time_t = time.strftime("%H:%M", time.localtime())
		self.clock_t = self.clock_f.render(time_t, 1, (255, 255, 255))
		self.clock_t_r = self.clock_t.get_rect()
		self.clock_t_r.right = (self.screen.get_width() - 10)
		self.clock_t_r.top = (self.bar_bg_r.top + (self.bar_bg_r.height / 2)) - (self.clock_t_r.height / 2)
		self.screen.blit(self.clock_t, self.clock_t_r)
	
	def drawMsg(self):
		if self.msg != "":
			if (time.time() - self.msg_time) <= 5:
				self.msg_box_bg_r = self.msg_box_bg.get_rect()
				self.msg_box_bg_r.left = 10
				self.msg_box_bg_r.bottom = self.bar_bg_r.top - 5
				self.screen.blit(self.msg_box_bg, self.msg_box_bg_r)
				
				self.msg_t = self.def_f.render(self.msg, 1, (255, 255, 255))
				self.msg_t_r = self.msg_t.get_rect()
				self.msg_t_r.left = 20
				self.msg_t_r.top = (self.msg_box_bg_r.top + (self.msg_box_bg_r.height / 2)) - (self.msg_t_r.height / 2)
				self.screen.blit(self.msg_t, self.msg_t_r)
		
	def drawGadgets(self):
		ypos = 10
		for i, guid in enumerate(self.apps_guid):
			# We can only display 5 gadgets on screen at a time
			# Eventually, multiple pages/auto scrolling will be added
			# But, for now, we're only going to display the first five
			if i >= 5:
				self.newMsg("Only 5 gadgets supported at present", time.time())
				break
			# Background box
			self.box_bg_r = self.box_bg.get_rect()
			self.gadget_s = pygame.Surface(self.box_bg_r.size, pygame.SRCALPHA, 32)
			self.gadget_s.blit(self.box_bg, self.box_bg_r)
			text = self.apps_glance[i]
			# Glance text
			my_rect = self.gadget_s.get_rect()
			my_rect.width = my_rect.width - 72
			my_rect.left = my_rect.left + 72
			my_rect.right = my_rect.right - 10
			my_rect.height = my_rect.height - 10
			my_rect.top = my_rect.top + 5
			rendered_text, text_height = multiline.render_textrect(text, self.def_f, my_rect, (255, 255, 255), None, 0)
			my_rect.top = (my_rect.top + (my_rect.height/2)) - (text_height/2)
			self.gadget_s.blit(rendered_text, my_rect)
			# Icon
			f = StringIO(self.apps_icon[i])
			icon = pygame.image.load(f, "icon.bmp")
			f.close()
			icon.set_colorkey((0, 0, 0))
			icon_r = icon.get_rect()
			icon_r.left = 10
			icon_r.top = (self.box_bg_r.top + (self.box_bg_r.height/2)) - (icon_r.height/2)
			self.gadget_s.blit(icon, icon_r)
			# Place gadget on screen
			self.screen.blit(self.gadget_s, (10, ypos))
			ypos = ypos + (self.box_bg_r.height + 10)
		
	def initBT(self):
		self.BTserver()
		self.BTclient()
			
	def BTserver(self):
		self.server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
		
		if PLATFORM == "n800":
			port = bluetooth.get_available_port( bluetooth.RFCOMM )
			self.server_sock.bind(("",port))
		else:
			self.server_sock.bind(("", bluetooth.PORT_ANY))
			(addr, port) = self.server_sock.getsockname();

		log.debug("Opening BT server")
		self.server_sock.listen(1)
		
		# Announce SideShow support
		log.debug("Advertising SideShow sevice")
		uuid = "5d9dda39-1e82-49c7-a0d6-6507ba9287ef"
		bluetooth.advertise_service( self.server_sock, "SideShow", service_id = uuid, service_classes = [ uuid ], profiles = [bluetooth.SERIAL_PORT_PROFILE] )
		
	def BTclient(self):
		# Get MAC address of BT adapter.  This is needed because SideShow creates a service ID based on it.
		log.debug("Getting local BT adapter MAC address")
		bus = dbus.SystemBus();
		obj = bus.get_object('org.bluez','/org/bluez')
		manager = dbus.Interface(obj,'org.bluez.Manager')
		obj = bus.get_object('org.bluez',manager.DefaultAdapter())
		adapter = dbus.Interface(obj,'org.bluez.Adapter')
		lmac_f = adapter.GetAddress()
		log.debug("Local address - " + lmac_f)
		
		self.newMsg("Looking for SideShow server", time.time())
		
		# I don't like getting a list of paired devices like this.
		# There MUST be a way to do it in dbus.
		f = open ("/var/lib/bluetooth/" + lmac_f + "/trusts","r")
		while 1:
			rmac = f.readline()
			if not rmac:
				break
			#server_mac="00:02:72:B0:BD:77"
			server_mac=rmac[:17]
			log.debug("Finding SideShow service: " + server_mac)
			self.newMsg("Finding SideShow service: " + server_mac, time.time())
			lmac = lmac_f.split(':')
			ss_sdp = "5d9dda39-1e82-49c7-" + lmac[5] + lmac [4] + "-" + lmac[3] + lmac[2] + lmac[1] + lmac[0] + "87ef"
			services = bluetooth.find_service(uuid=ss_sdp, address=server_mac)
			if services:
				for i in range(len(services)):
					match=services[i]
					port=match["port"]
					name=match["name"]
					host=match["host"]		
					log.debug("Found " + name + " at " + host)
		
				log.debug("Connecting client to BT server")
				self.newMsg("Connecting to SideShow server", time.time())
				self.client_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
				try:
					self.client_sock.connect((host,port))
					self.client_sock.setblocking(False)
					self.CONNECTED = True
				except:
					log.debug("Some went wrong during connection")
		
		f.close()
		if self.CONNECTED == False:
			self.newMsg("Couldn't find SideShow service", time.time())
			log.debug("Couldn't find SideShow service")
			
	def endBT(self):
		log.debug("Closing BT client")
		self.client_sock.close()
		log.debug("Closing BT server")
		self.server_sock.close()
		
	def listener(self):
		#log.debug("Got " + str(len(self.data)) + " bytes")
		packet_size = len(self.data)
		header_size = ord(self.data[0]) + (ord(self.data[1]) * 0x100) + (ord(self.data[2]) * 0x10000) + (ord(self.data[3]) * 0x1000000)
		while packet_size != header_size:
			try:
				self.data = self.data + self.client_sock.recv(32768)
				packet_size = len(self.data)
			except:
				self.data = self.data
			
		if packet_size == header_size:
			packet_type = ord(self.data[4]) + (ord(self.data[5]) * 0x100) + (ord(self.data[6]) * 0x10000) + (ord(self.data[7]) * 0x1000000)
			packet_num = ord(self.data[8]) + (ord(self.data[9]) * 0x100)
			self.packet_count = packet_num
			packet_data = ""
			for msgb in range(10, header_size):
				packet_data = packet_data + self.data[msgb]
			
			if hex(packet_type) == "0x50":
				log.debug("SETUSERSTATE")
				self.resp_SETUSERSTATE(packet_type, packet_num, packet_data)
				self.drawFront()
				return

			if hex(packet_type) == "0x100":
				log.debug("SETCURRENTUSER")
				self.resp_SETCURRENTUSER(packet_type, packet_num, packet_data)
				return

			if hex(packet_type) == "0x101":
				log.debug("GETCURRENTUSER")
				self.resp_GETCURRENTUSER(packet_type, packet_num, packet_data)
				return

			if hex(packet_type) == "0x104":
				log.debug("GETAPPLICATIONORDER")
				self.resp_GETAPPLICATIONORDER(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x108":
				log.debug("SETTIME")
				self.resp_SETTIME(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x109":
				log.debug("SETSHORTDATEFORMAT")
				self.resp_SETSHORTDATEFORMAT(packet_type, packet_num, packet_data)
				return

			if hex(packet_type) == "0x10a":
				log.debug("SETLONGDATEFORMAT")
				self.resp_SETLONGDATEFORMAT(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x10b":
				log.debug("SETSHORTTIMEFORMAT")
				self.resp_SETSHORTTIMEFORMAT(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x10d":
				log.debug("ADDAPPLICATION")
				self.resp_ADDAPPLICATION(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x10e":
				log.debug("DELETEAPPLICATION")
				self.resp_DELETEAPPLICATION(packet_type, packet_num, packet_data)
				return
							
			if hex(packet_type) == "0x114":
				log.debug("ADDCONTENTITEM")
				self.resp_ADDCONTENTITEM(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x115":
				log.debug("DELETECONTENTITEM")
				self.resp_DELETECONTENTITEM(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x116":
				log.debug("DELETEALLCONTENTITEMS")
				self.resp_DELETEALLCONTENTITEMS(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x117":
				log.debug("GETSUPPORTEDENDPOINTS")
				self.resp_GETSUPPORTEDENDPOINTS(packet_type, packet_num, packet_data)
				return

			if hex(packet_type) == "0x118":
				log.debug("SETTIMEZONE")
				self.resp_SETTIMEZONE(packet_type, packet_num, packet_data)
				return
				
			if hex(packet_type) == "0x502":
				log.debug("SYNC")
				self.resp_SYNC(packet_type, packet_num, packet_data)
				return
				
			log.debug("Got an unknown packet type: " + hex(packet_type))
	
	
	# 0x1 Send
	def send_PING(self):
		ping = ""
		ping = chr(0x1 % 0x100) + chr((0x1 >> 8) % 0x100) + chr((0x1 >> 16) % 0x100) + chr(((0x1 >> 24) % 0x100))
		ping = ping + self.pack_num(self.packet_count + 1)
		ping_len = len(ping) + 4
		ping = self.pack_len(ping_len) + ping
		try:
			self.client_sock.send(ping)
		except:
			self.CONNECTED = False
			
	# 0x50
	def resp_SETUSERSTATE(self, packet_type, packet_num, packet_data):
		sid_size = ord(packet_data[0]) + (ord(packet_data[1]) * 0x100) + (ord(packet_data[2]) * 0x10000) + (ord(packet_data[3]) * 0x1000000)
		bytepos = 4
		sid = ""
		# This is REALLY dirty.  I can't quite get my head around sending 2 byte unicode
		for uni in range(sid_size * 2):
			bytepos+=1
			if ord(packet_data[4 + uni]) != 0:
				sid = sid + packet_data[4+uni]
		#
		log.debug(sid)
		
		user_size = ord(packet_data[bytepos + 0]) + (ord(packet_data[bytepos + 1]) * 0x100) + (ord(packet_data[bytepos + 2]) * 0x10000) + (ord(packet_data[bytepos + 3]) * 0x1000000)
		bytepos+=4
		self.user = ""
		# This is REALLY dirty.  I can't quite get my head around sending 2 byte unicode
		for uni in range(bytepos, (bytepos + user_size * 2)):
			bytepos+=1
			if ord(packet_data[uni]) != 0:
				self.user = self.user + packet_data[uni]
		#
		log.debug(self.user)
		user_state = ord(packet_data[bytepos + 0]) + (ord(packet_data[bytepos + 1]) * 0x100) + (ord(packet_data[bytepos + 2]) * 0x10000) + (ord(packet_data[bytepos + 3]) * 0x1000000)
				
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)

	# 0x100
	def resp_SETCURRENTUSER(self, packet_type, packet_num, packet_data):
		sid_size = ord(packet_data[0]) + (ord(packet_data[1]) * 0x100) + (ord(packet_data[2]) * 0x10000) + (ord(packet_data[3]) * 0x1000000)
		bytepos = 4
		sid = ""
		# This is REALLY dirty.  I can't quite get my head around sending 2 byte unicode
		for uni in range(sid_size * 2):
			bytepos+=1
			if ord(packet_data[4 + uni]) != 0:
				sid = sid + packet_data[4+uni]
		#
		log.debug(sid)
		self.sid = sid
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
			
	# 0x101	
	def resp_GETCURRENTUSER(self, packet_type, packet_num, packet_data):
		sid = self.sid
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp = resp + self.pack_len(len(sid))
		#resp = resp + sid
		# This is REALLY dirty.  I can't quite get my head around sending 2 byte unicode
		for uni in range(len(sid)):
				resp = resp + sid[uni]
				resp = resp + chr(0)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)

	# 0x104
	def resp_GETAPPLICATIONORDER(self, packet_type, packet_num, packet_data):
		applications = self.apps_guid
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp = resp + self.pack_len(len(applications))
		for app in applications:
			resp = resp + app.bytes_le
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
	# 0x108 - Needs handling
	def resp_SETTIME(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
	# 0x109 - Needs handling
	def resp_SETSHORTDATEFORMAT(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)

	# 0x10a - Needs handling
	def resp_SETLONGDATEFORMAT(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)

	# 0x10b - Needs handling
	def resp_SETSHORTTIMEFORMAT(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
	
	# 0x10d
	def resp_ADDAPPLICATION(self, packet_type, packet_num, packet_data):
		guid = uuid.UUID(bytes_le=packet_data[:16])
		if self.apps_guid.count(guid) == 0:
			ep = uuid.UUID(bytes_le=packet_data[16:32])
			name_size=ord(packet_data[32]) + (ord(packet_data[33]) * 0x100) + (ord(packet_data[34]) * 0x10000) + (ord(packet_data[35]) * 0x1000000)
			name_size=name_size*2
			app_name=packet_data[36:36+name_size]
			log.debug(app_name)
			bp = 36+name_size+8
			lg_icon_size=ord(packet_data[bp]) + (ord(packet_data[bp+1]) * 0x100) + (ord(packet_data[bp+2]) * 0x10000) + (ord(packet_data[bp+3]) * 0x1000000)
			bp = bp+4
			lg_icon = packet_data[bp:bp+lg_icon_size]
			# We'll ignore the rest of the data for now.
			self.apps_guid.append(guid)
			self.apps_name.append(app_name)
			self.apps_icon.append(lg_icon)
			self.apps_glance.append("Waiting for data...")

		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
		self.drawFront()
		
	# 0x10e
	def resp_DELETEAPPLICATION(self, packet_type, packet_num, packet_data):
		guid = uuid.UUID(bytes_le=packet_data)
		log.debug(str(guid))
		try:
			i = self.apps_guid.index(guid)
			del self.apps_guid[i]
			del self.apps_name[i]
			del self.apps_icon[i]
			del self.apps_glance[i]
		except ValueError:
			log.debug("Application not found")		
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
		self.drawFront()
		
	# 0x114
	def resp_ADDCONTENTITEM(self, packet_type, packet_num, packet_data):
		# We're only getting it for now (except glance), not doing anything with it.
		guid = uuid.UUID(bytes_le=packet_data[:16])
		ep = uuid.UUID(bytes_le=packet_data[16:32])
		cont_id = ord(packet_data[32]) + (ord(packet_data[33]) * 0x100) + (ord(packet_data[34]) * 0x10000) + (ord(packet_data[35]) * 0x1000000)
		cont_sz = ord(packet_data[36]) + (ord(packet_data[37]) * 0x100) + (ord(packet_data[38]) * 0x10000) + (ord(packet_data[39]) * 0x1000000)
		cont = packet_data[-cont_sz:]
		if cont_id == 0:
			try:
				i = self.apps_guid.index(guid)
				self.apps_glance[i] = cont.strip(chr(0))
				log.debug(cont.strip(chr(0)))
			except:
				log.debug("Got data for unknown application")
				log.debug(str(guid))
			
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
		self.drawFront()
		
	# 0x115
	def resp_DELETECONTENTITEM(self, packet_type, packet_num, packet_data):
		# We've got what needs deleting.  But since we're not storing content
		# yet, there's nothing to delete.
		guid = uuid.UUID(bytes_le=packet_data[:16])
		ep = uuid.UUID(bytes_le=packet_data[16:32])
		cont_id = ord(packet_data[32]) + (ord(packet_data[33]) * 0x100) + (ord(packet_data[34]) * 0x10000) + (ord(packet_data[35]) * 0x1000000)
		
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
		self.drawFront()
		
	# 0x116
	def resp_DELETEALLCONTENTITEMS(self, packet_type, packet_num, packet_data):
		# We've got what needs deleting.  But since we're not storing content
		# yet, there's nothing to delete.
		guid = uuid.UUID(bytes_le=packet_data[:16])
		ep = uuid.UUID(bytes_le=packet_data[16:32])
		
		# But we DO have the glance item, so we'll reset that.
		try:
			i = self.apps_guid.index(guid)
			self.apps_glance[i] = "Waiting for data..."
		except:
			log.debug("Asked to remove all data for unknown application")
			log.debug(str(guid))
				
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
		self.drawFront()
		
	# 0x117
	def resp_GETSUPPORTEDENDPOINTS(self, packet_type, packet_num, packet_data):
		scf = uuid.UUID('{A9A5353F-2D4B-47ce-93EE-759F3A7DDA4F}') #scf
		ical = uuid.UUID('{4DFF36B5-9DDE-4F76-9A2A-96435047063D}') #ical
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp = resp + self.pack_len(1)
		resp = resp + scf.bytes_le
		#resp = resp + ical.bytes_le
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
	# 0x118 - Needs handling
	def resp_SETTIMEZONE(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
	
	# 0x502
	def resp_SYNC(self, packet_type, packet_num, packet_data):
		resp = ""
		resp = self.pack_type(packet_type)
		resp = resp + self.pack_num(packet_num)
		resp = resp + packet_data
		resp_len = len(resp) + 4
		resp = self.pack_len(resp_len) + resp
		self.client_sock.send(resp)
		
	def pack_type(self, packet_type):
		resp = ""
		resp = chr(packet_type % 0x100) + chr((packet_type >> 8) % 0x100) + chr((packet_type >> 16) % 0x100) + chr(((packet_type >> 24) % 0x100) | 128)
		return resp
		
	def pack_num(self, packet_num):
		resp = ""
		resp = chr(packet_num % 0x100) + chr(packet_num / 256)
		return resp
		
	def pack_len(self, pack_len):
		resp = ""
		resp = chr(pack_len % 0x100) + chr((pack_len >> 8) % 0x100) + chr((pack_len >> 16) % 0x100) + chr((pack_len >> 24) % 0x100)
		return resp
				
app = SideShowApp()
app.run()
