# A "virtual" thermometer for your S60 phone
# Your gps coordinates are retrieved from the internal (or external bt) gps. 
# A list of nearby temperatures are retrieved from www.temperatur.nu
# A mean value is calculated and reported back to you. 
# ONLY FOR USE IN SWEDEN 

# @todo add more error handling.. 

# v 0.4 Minor updates regarding language and layout
# v 0.3 Added support for both internal and external (bluetooth) gps 
# v 0.2 Now using appuifw instead of just printing to std.out
# v 0.1 Initial version for testing

# 2009-04-12 Mikael Trieb, mikael@trieb.se (www.triebconsulting.se)

import e32
import appuifw
import graphics
import random
import key_codes
import positioning
import urllib
import socket

VERSION = "0.4"

coords = {}
theTitle = u"S60 Virtual Thermometor"
copyright  = u"www.triebconsulting.se\n\u00a92009 Mikael Trieb"
labels = ['annotation', 'title', 'legend', 'symbol', 'dense', 'normal', 'digital']
fonts = None
canvas = None
img = None
t = None
g_style = 0

# Get GPS co-ordinates from internal GPS #
def getCoordinates():
	init_log_text()
	positioning.select_module(positioning.default_module())
	positioning.set_requestors([{'type':'service', 'format':'application','data':'position'}])
	try:
		#sys.stdout.write('Retrieving GPS co-ordinates ...\n')
		set_log_text(u'Hämtar koordinater...\n')
		data = positioning.position(course=1, satellites=1)
	except:
		errMsg = u'Kunde inte hämta GPS koordinater!\n' 
		appuifw.note(errMsg, "info")
		cb_quit()
	else:
		set_log_text(u'GPS koordinater hämtade!\n')
		set_log_text(u'Hämtar temperatur...\n')
		getTemperature(data['position']['latitude'], data['position']['longitude'])

def getBTCoordinates():
	lat = 'n/a'
	lon = 'n/a'
	address, services = socket.bt_discover()
	target = (address, services.values()[0])
	conn = socket.socket(socket.AF_BT, socket.SOCK_STREAM)
	conn.connect(target)
	to_gps = conn.makefile("r", 0)
	while True:
		msg = to_gps.readline()
		if msg.startswith("$GPGGA"):
			gps_data = msg.split(",")
			lat = gps_data[2]
			lon = gps_data[4]
			if(lat != ''):
				break
	to_gps.close()
	conn.close()
	try:
		set_log_text(u'Hämtar koordinater...\n')
		lat = str(float(lat)/100)
		lon = str(float(lon)/100)
	except:
		errMsg = u'Kunde inte hämta GPS koordinater!\n' 
		appuifw.note(errMsg, "info")
		cb_quit()
	else:
		#coords = (lat,lon)	
		set_log_text(u'Hämtar temperatur...\n')
		getTemperature(lat, long)
		
	
def getTemperature(llat, llong):
	init_log_text()
	# Compose the web address
	address = u'http://www.temperatur.nu/narmaste_temp.php?lat=%s&lon=%s' % (llat,llong)
	f = urllib.urlopen(address)
	# Read from the object, storing the page's contents in 's'.
	s = f.read()
	t1 = parse_string(s)
	f.close()
	note = u'Temperatur: ca %0.2f grader!\nLat: %s\nLong: %s' % (t1,llat,llong)
	appuifw.query(note, "query")
	#return t1

def parse_string(s):
	set_log_text(u'Orter nära dig:\n')
	t2 = 0
	i = 0
	lineList = s.split('<br>')
	for line in lineList:
		w = line.split(' ')
		if(w[-1]):
			i = i + 1
			t2 += float(w[-1])
			note = w[5] + u' ' + w[4] + u': ' + w[-1] + u'\n'
			set_log_text(note)
	t2 = t2 / i
	return t2
	
def get_color():
	''' Generate random RGB color '''
	return (random.choice(range(0,255)), random.choice(range(0,255)), random.choice(range(0,255)))	

def show_start_text(a_list):
	''' Main draw routine - for Text '''
	global g_list
	g_list = a_list
	t.clear()
	# Add the title
	t.font = a_list[1]#i
	t.style = g_style 
	t.add(theTitle + u'\n')
	# Add copyright text
	t.font = a_list[2]#i
	t.style = g_style 
	t.add(u'VERSION ' + VERSION + u'\n' +copyright)
	

	# Use random text color, show something happened
	t.color = (get_color())
	appuifw.app.body = t
	
def init_log_text():
	t.clear()
	t.font = 'legend'
	t.color = (100,100,25)
	
def set_log_text(text):
	t.add(text)

def menu_about():
	''' Callback for menu item About '''
	appuifw.note(u'Virtual Thermometer v'+VERSION + u'\n' +\
		u'www.triebconsulting.se\n\u00a92009 Mikael Trieb')

def cb_quit():
	''' Cleanup before exit '''
	app_lock.signal()

# Initialize application
appuifw.app.screen = 'full'
appuifw.app.title = u"Virtual Thermometer"
appuifw.app.exit_key_handler = cb_quit
appuifw.app.menu = [
	(u"GPS type",
		((u"Use internal gps", lambda:getCoordinates()),
		(u"Use bluetooth gps", lambda:getBTCoordinates()))),
	(u"About", menu_about),
	(u"Exit", cb_quit)]

# Must set canvas to body, else canvas.size wrong
# Do not define redraw_callback, else problems with text mode
canvas = appuifw.Canvas()
appuifw.app.body = canvas
img = graphics.Image.new(canvas.size)

# Want to start with text mode
t = appuifw.Text()
appuifw.app.body = t

# Initialize application UI
fonts = appuifw.available_fonts()
show_start_text(labels)

# Wait for user to do anything
app_lock = e32.Ao_lock()
app_lock.wait()	