#!/usr/bin/env python
# -*- coding: utf-8 -*-

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

#  EMHI Ilmajaamade Screenlet / Copyright 2010 Guido Tabbernuk under GPL3
#  Code base: Freemeteo Weather Screenlet by Nikiforakis Manos
#  Drawing code : Based on the Default Weather Screenlet
#  UI : Based on Widescape's Weather Konfabulator Widget
#
# TODO:
#
# 1) Prognooside lugemise akna tekst korralikult vormindada.
# 2) Igasugu asjade paigutused loogilisemaks/paremaks/dünaamilisemaks.
# 3) Uued teemad ja PNG asemel SVG.
#

import screenlets
from screenlets.options import ColorOption, FontOption, BoolOption, StringOption, IntOption
import cairo
import string
import math
import time
from datetime import datetime
import pango
import gtk
import gobject
import threading
import traceback
import urllib
from xml.etree import ElementTree
import re
from pytz import timezone

class EMHIScreenlet(screenlets.Screenlet):
	"""Eesti meteroloogia ja hüdroloogia instituudi tasuta infovool põhinev
	töölauavidin, mis kirjaldab ja ennustab ilma paikades üle kogu Eesti"""
	p_layout = None 
	# default meta-info for Screenlets
	__name__ = 'EMHIScreenlet'
	__version__ = '0.2.5'
	__author__ = 'Guido Tabbernuk <boamaod@gmail.com>'
	__desc__ = 'Eesti meteroloogia ja hüdroloogia instituudi tasuta infovool põhinev ilmavidin'

	__timeout = None
	__notifier = None

	__lock = threading.Lock()

	update_interval = 3000
	updated_recently = 0
	updated_last_time = 0
	latest = {}
	yhendus = False
	yhenduse_viimane_olek = False
	nimekirjad_uuendatud = False
	windowpop = None

	# editable options
	vaatluse_url = 'http://www.emhi.ee/ilma_andmed/xml/observations.php'
	prognoosi_url = 'http://www.emhi.ee/ilma_andmed/xml/forecast.php?lang=%s'

	bgColor = (0.1,0.1,0.1,0.8)
	iconColor = (1,1,1,1)
	textColor = (1,1,1,1)
	roundCorner = True

	bigfont = 'Dejavu Sans Condensed Bold 10'
	smallfont = 'Dejavu Sans Condensed Bold 7'
	verysmallfont = 'Dejavu Sans Condensed 4'
	hypersmallfont = 'Dejavu Sans Condensed 3'

	showTrayIcon = False
	showForecast = True

	# yhe prognoosi laius
	prognosis_width = 45

	screenlet_width = prognosis_width
	screenlet_height = 33
	minmaincellwidth = screenlet_width*2+screenlet_width/4

	predictionstoshow_max = 5
	predictionstoshow_night = True
	predictionstoshow_day = True

	ilmajaam='Tallinn (Harku)'
	asukoht='Harku'

	# "Üldine" on suvaline string, mida kunagi ennustusest ei leita, ja selle valimisel näidatakse üleestilist ennustust
	asukohad = ["Üldine", "Harku", "Jõhvi", "Tartu", "Pärnu", "Kuressaare", "Türi"]

	ilmajaamad = ["Tallinn (Harku)", "Pakri", "Kunda", "Jõhvi", "Narva-Jõesuu", "Väike-Maarja", "Tiirikoja", "Jõgeva", "Tartu (Tõravere)", "Võru", "Valga", "Viljandi", "Türi", "Kuusiku", "Lääne-Nigula", "Virtsu", "Pärnu (Sauga)", "Kihnu", "Ruhnu", "Vilsandi", "Sõrve", "Ristna", "Haapsalu", "Tooma", "Rohuküla", "Heltermaa", "Roomassaare"]

	language=u'Eesti'
	languageid=None
	
	language_sel = [u'Eesti', u'English', u'Русский']

#	day_translation = {
#			'est':{0:u'E', 1:u'T', 2:u'K', 3:u'N', 4:u'R', 5:u'L', 6:u'P'},
#			'eng':{0:u'Monday',1:u'Tuesday',2:u'Wednesday',3:u'Thursday',4:u'Friday',5:u'Saturday',6:u'Sunday'},
#			'rus':{0:u'понедельник', 1:u'вторник', 2:u'среда', 3:u'четверг', 4:u'пятница', 5:u'суббота', 6:u'воскресенье'}
#					}

	ootamine_translation = {
			'est': "Vastuse ootamine...",
			'rus': "Ожидание ответа...",
			'eng': "Waiting for reply..."
					}

#	today_translation = {
#			'est':u'täna',
#			'eng':u'Today',
#			'rus':u'Сегодня'
#					}

#	now_translation = {
#			'est':u'praegu',
#			'eng':u'Now',
#			'rus':u'в настоящее'
#					}

	yhendus_translation = {
			'est': "Probleem ühendusega!",
			'rus': "Ошибка соединения!",
			'eng': "Connection problem!"
					}

	jaamapole_translation = {
			'est': "Jaama ei leitud!",
			'rus': "Станция не найдена!",
			'eng': "Station not found!"
					}

	# constructor
	def __init__(self, **keyword_args):
		#call super
		screenlets.Screenlet.__init__(self, height=self.screenlet_height, 
			**keyword_args)
		self.enable_buttons = False
		self.draw_buttons = False

		# set theme
		self.theme_name = "default"

		self.scale = 1.5

		# init the timeout function
		self.update_interval = self.update_interval

		# add option group
		self.add_options_group('Välimus', 'Vidina välimuse muutmine')
		self.add_options_group('Esitus', 'Ilmajaamadaandmete esituse sätestamine')
		self.add_options_group('Ilmajaamad', 'Vaatlus- ja ennustuspunktide paikapanek')
		self.add_option(ColorOption('Välimus', 'bgColor',
			self.bgColor, 'Taustavärv',
			'Vidina taustavärv'))
		self.add_option(ColorOption('Välimus', 'iconColor',
			self.iconColor, 'Ikooni värv',
			'Ilmastikunähtust kirjeldava ikooni värv'))
		self.add_option(ColorOption('Välimus', 'textColor',
			self.textColor, 'Tekstivärv',
			'Kirjeldava teksti värv'))
		self.add_option(FontOption('Välimus', 'bigfont',
			self.bigfont, 'Suur kiri',
			'Tänase temperatuuri esitamiseks jaoks kasutatav kirjatüüp'))
		self.add_option(FontOption('Välimus', 'smallfont',
			self.smallfont, 'Keskmine kiri',
			'Ennustuse temperatuuride esitamiseks kasutatav kirjatüüp'))
		self.add_option(FontOption('Välimus', 'verysmallfont',
			self.verysmallfont, 'Väike kiri',
			'Öise temperatuuri ja nädalapäevade jms jaoks kasutatav kirjatüüp'))
		self.add_option(FontOption('Välimus', 'hypersmallfont',
			self.hypersmallfont, 'Kirbukiri',
			'Vähetähtsate asjade esitamise kirjatüüp'))
		self.add_option(BoolOption('Välimus', 'roundCorner',
			self.roundCorner, 'Tausta nurkade ümardamine','Kui meeldib ümardatud nurkadega taust'))
		self.add_option(BoolOption('Esitus', 'predictionstoshow_day', 
			self.predictionstoshow_day, 'Päevased ennustused',
			'Kui tahad näha ilmaennustusi päevase aja kohta'))
		self.add_option(BoolOption('Esitus', 'predictionstoshow_night', 
			self.predictionstoshow_night, 'Öised ennustused',
			'Kui tahad näha ilmaennustusi öö kohta'))
		self.add_option(IntOption('Esitus','predictionstoshow_max', 
			self.predictionstoshow_max, 'Ennustuste arv', 
			'Maksimaalne arv, mitut saadaolevat ennustust näidata', 
			min=0, max=20))
		self.add_option(BoolOption('Esitus', 'showTrayIcon',
			self.showTrayIcon, 'Lülitusikooni näitamine',
			'Kas näidata ennustuste sisse- ja väljalülitamist märkivat +/- märgiga ikooni'))

		self.add_option(StringOption('Ilmajaamad', 'language', 
			self.language, 'Ennustuste keel',
			'EMHI pakub ennustusi eri keeltes, vali endale sobiv!',
			choices = self.language_sel), realtime=False)

		self.add_option(StringOption('Ilmajaamad', 'ilmajaam', 
			self.ilmajaam, "Ilmajaama nimi",
			'Vaatluste jaoks kasutatava EMHI ilmajaama nimi',
			choices = self.ilmajaamad), realtime=False)
		self.add_option(StringOption('Ilmajaamad', 'asukoht', 
			self.asukoht, "Ennustuse asukoht", 
			'Asukoht, mille EMHI prognoosi näidata ',
			choices = self.asukohad), realtime=False)

		self.__notifier = screenlets.utils.Notifier(self)

		self.updatelanguage(self.language)
		gobject.idle_add(self.update_weather_data)
		self.screenlet_width=self.minmaincellwidth


	def __setattr__(self, name, value):
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
		screenlets.Screenlet.__setattr__(self, name, value)

		if name in ('bgColor', 'iconColor', 'textColor', 'roundCorner'):
			self.redraw_canvas()
		elif name in ('bigfont', 'smallfont', 'verysmallfont', 'hypersmallfont',
			'showTrayIcon', 'predictionstoshow_day', 'predictionstoshow_night', 'predictionstoshow_max'):
			self.update_shape()
			self.redraw_canvas()

		if name in ('ilmajaam', 'asukoht'):
			self.__dict__[name] = value
			gobject.idle_add(self.update_weather_data)

		if name == "update_interval":
			if value > 0:
				self.__dict__['update_interval'] = value
				if self.__timeout:
					gobject.source_remove(self.__timeout)
				self.__timeout = gobject.timeout_add(value * 1000, self.update)
			else:
				pass

		if name == 'language':
			self.updatelanguage(self.language)
			print "Uus keel:", self.language, self.languageid
			self.update()

	def on_init(self):
		# add zip code menu item
		self.add_menuitem("ilmajaam", "Määra ilmajaam")
		self.add_menuitem("uuenda", "Uuenda andmeid")
		self.add_menuitem("ennustuse_tekst", u"Loe prognoosi")
		# add default menu items
		self.add_default_menuitems()

	def updatelanguage(self, language):
		if language == u'Русский': self.languageid = 'rus'
		elif language == u'Eesti': self.languageid = 'est'
		elif language == u'English': self.languageid = 'eng'
		else: self.languageid = 'est'

	def if_else(self, condition, this, that):
		if condition:
			return this
		else:
			return that

	def on_draw(self, ctx):
		print 'On draw'

		# if theme is loaded
		if self.theme:
			ilm = self.latest
			#self.window.set_keep_below(True)

			# set scale rel. to scale-attribute
			ctx.scale(self.scale, self.scale)

			if ilm == {}:
				asukohastring = "" # was: "Choose a Zip Code"
			else:
				if '(' in self.ilmajaam and ')' in self.ilmajaam:
					koopia = self.ilmajaam
					asukohastring = re.sub(r"([^\(]*)\((([^\)]*))\)", r"\2", koopia)
				else:
					asukohastring = self.ilmajaam

			print "Asukoht: %s" % asukohastring

			maincellx = 0
			citytimewidth = 0
			maincellwidth = 48
			citywidth = 0
			timewidth = 0
			cityheight = 0

			obstime = datetime.now()

			if ilm != {}:
				obstime = datetime.fromtimestamp(float(ilm['vaatlus']['timestamp']), timezone('Europe/Tallinn'))
				obstimestring = obstime.strftime("%H:%M")
#				obsdatetimestring = self.mt(str(obstime.day) + ". " + obstime.strftime("%b") + " " + obstimestring)
				obsdatetimestring = self.mt(str(obstime.day) + "." + str(obstime.month) + " " + obstimestring)
			else:
				obstimestring = ""
				obsdatetimestring = ""
			
			cx, cy, citywidth, cityheight = self.get_text_extents(ctx, asukohastring, self.smallfont);
			timewidth = self.get_text_width(ctx, obstimestring, self.verysmallfont)
			if citywidth > timewidth: citytimewidth = citywidth + 6
			else: citytimewidth = timewidth + 6
			maincellwidth += citytimewidth 

			maincellwidth = max(self.minmaincellwidth, maincellwidth)
			self.screenlet_width = maincellwidth

			kordaja = real_pred = 0
			if ilm != {}:
				if self.predictionstoshow_night: kordaja += 1
				if self.predictionstoshow_day: kordaja += 1
				real_pred = min(self.predictionstoshow_max, len(ilm['prognoos'])*kordaja)

			print "PROGNOOSE TULEB: ", real_pred

			prognosis_added_width = real_pred*self.prognosis_width
			self.screenlet_width += prognosis_added_width

			self.draw_background(ctx, maincellx, maincellwidth, self.showForecast, prognosis_added_width)

			print 'Taust joonistatud'

			# show Current and Today/Tonight's data
			if ilm != {} and len(ilm['vaatlus'])>1:
				temperatuur = self.if_else(ilm['vaatlus']['airtemperature'] is not None, ilm['vaatlus']['airtemperature'], "")
				winddir = self.if_else(ilm['vaatlus']['airpressure'] is not None, ilm['vaatlus']['winddirection'], "") # sest see teisendatakse
				windspeed = self.if_else(ilm['vaatlus']['windspeed'] is not None, ilm['vaatlus']['windspeed'], "?")
				windspeedmax = self.if_else(ilm['vaatlus']['windspeedmax'] is not None, ilm['vaatlus']['windspeedmax'], "?")
				airpressure = self.if_else(ilm['vaatlus']['airpressure'] is not None, ilm['vaatlus']['airpressure'], "?") + " hPa"

				sademed = self.if_else(ilm['vaatlus']['precipitations'] is not None, ilm['vaatlus']['precipitations'], "?") + " mm"
				niiskus = self.if_else(ilm['vaatlus']['relativehumidity'] is not None, ilm['vaatlus']['relativehumidity'], "?")  + " %"
				naehtavus = self.if_else(ilm['vaatlus']['visibility'] is not None, ilm['vaatlus']['visibility'], "?")  + " km"

				esimenerida = self.mt(airpressure + ", " + sademed)
				teinerida = self.mt(niiskus + ", " + naehtavus)
				kolmasrida = self.mt(windspeed + ", max " + windspeedmax + " m⁄s")

				self.draw_text(ctx, asukohastring, 1, 1, self.smallfont, self.textColor)
				hei = self.get_text_height(ctx, kolmasrida, self.verysmallfont)
				print "Hei: ", hei

				self.draw_text(ctx, esimenerida, 3, 12, self.verysmallfont, self.textColor)
				self.draw_text(ctx, teinerida, 3, 18, self.verysmallfont, self.textColor)

				if winddir != "":
					self.draw_an_arrow(ctx, math.pi*2*(float(winddir)/360), 1, 24, hei+3)
				else:
					self.draw_an_arrow(ctx, math.pi/4, 1, 24, hei+3, True)
					self.draw_an_arrow(ctx, 5*math.pi/4, 1, 24, hei+3, True)
					self.draw_an_arrow(ctx, 3*math.pi/4, 1, 24, hei+3, True)
					self.draw_an_arrow(ctx, 7*math.pi/4, 1, 24, hei+3, True)

				self.draw_text(ctx, kolmasrida, hei+5, 25, self.verysmallfont, self.textColor)

				if obstime.hour >= 21 or obstime.hour < 7: dayornight='night'
				else: dayornight='day'

				print "Eestis on praegu: ", dayornight

				# kas öelda "praegu" või ütelda vaatluse täpne aeg??????????????????+
#				self.draw_weather_icon(ctx, ilm['vaatlus']['phenomenon'], dayornight, self.now_translation[self.languageid], re.sub("\.\d*", "", ilm['vaatlus']['airtemperature']),'', maincellwidth, 1)
#				self.draw_weather_icon(ctx, ilm['vaatlus']['phenomenon'], dayornight, obsdatetimestring, re.sub("\.\d*", "", ilm['vaatlus']['airtemperature']),'', maincellwidth, 1)
				self.draw_weather_icon(ctx, ilm['vaatlus']['phenomenon'], dayornight, obstimestring, re.sub("\.\d*", "", temperatuur),'', maincellwidth, 1)

				self.yhenduse_viimane_olek = self.yhendus

			else:
				if not self.yhendus and self.yhendus != self.yhenduse_viimane_olek:
					mida8elda = self.yhendus_translation[self.languageid]
				elif ilm != {} and len(ilm['vaatlus'])<=1:
					mida8elda = self.jaamapole_translation[self.languageid]
				else:
					mida8elda = self.ootamine_translation[self.languageid]
				self.draw_text(ctx, mida8elda, 4, 22, self.hypersmallfont, self.textColor)
				self.draw_weather_icon(ctx, "EMHI", '', '', '','', maincellwidth, 1)

			print 'Täna joonistatud'

			if self.showForecast and ilm != {} and real_pred > 0:

				print "KOKKU ON: ", len(ilm['prognoos'])

				prognoose = 0
				for prognoos in ilm['prognoos']:
#					print prognoose, prognoos
					for nothing in 0, 1:
						if nothing == 0 and datetime.strptime(prognoos['date'], "%Y-%m-%d").date == obstime.date and self.predictionstoshow_night and obstime.hour > 7:
							continue # et ei näidataks hommikul ja päeval ennustus juba möödunud öö kohta, aga seda trikitamist OLEKS siis vaja, kui EMHI edastaks ka prognoosi kestva päeva kohta, mida ta aga ei tee
						elif nothing == 0 and self.predictionstoshow_night:
							nightorday='night'
							dispchar = u"☾"
						elif nothing == 1 and self.predictionstoshow_day:
							nightorday='day'
							if self.predictionstoshow_night:
								dispchar = u"☀"
							else:
								dispchar = u""
						else:
							continue
						print "MIS PROGNOOS TEOKSIL", prognoose, nightorday
						if prognoos[nightorday]['tempmax']=='':
							prognoos[nightorday]['tempmax']=prognoos[nightorday]['tempmin'] #to show the only available temperature on top with bigfont!
							prognoos[nightorday]['tempmin']=''
						daystring = self.mt(datetime.strptime(prognoos['date'], "%Y-%m-%d").strftime("%a ") + dispchar) # 2010-06-20
						print daystring
						self.draw_weather_icon(ctx, prognoos[nightorday]['phenomenon'], nightorday, 
							daystring, prognoos[nightorday]['tempmax'], prognoos[nightorday]['tempmin'], maincellwidth, prognoose+2)
						prognoose += 1
						if prognoose == real_pred: break

				print 'prognoosid joonistatud'

			if self.width != self.screenlet_width:
				self.width = self.screenlet_width

	def mt(self, str):
		'''muuda tühikud väiksemaks'''
		str=re.sub(r"\s", "<span size=\"xx-small\"> </span>", str)
		return str

	def draw_an_arrow(self, ctx, angle, x, y, s, reducetail = False):
		"""joonistab noole, mis näitab tuule suunda"""

		print "Noole param: ", x, y, s

		ctx.save()

		print ctx.get_matrix()

		ctx.translate(x, y)

#		ctx.scale(self.height, self.height)
		
		print ctx.get_matrix()

		length = 0.48*s
		headlen= 0.27*s
		thickness = 0.09*s

		ctx.translate(0.5*s, 0.5*s)
		ctx.rotate(angle)
		ctx.set_source_rgba(self.textColor[0],self.textColor[1],self.textColor[2],self.textColor[3])
		ctx.set_line_width(thickness)
		
		secure = headlen - headlen/8 # ilu nimel
		ctx.move_to(0, length-secure)
		if reducetail:
			ctx.line_to(0, -length+secure)
		else:
			ctx.line_to(0, -length)
			
		ctx.stroke()

		# Arrowhead
		ctx.move_to(0, length)
		ctx.line_to(-headlen/2, length-headlen)
		ctx.line_to(headlen/2, length-headlen)
		ctx.close_path()
		ctx.fill()

		ctx.restore()

	def on_draw_shape(self, ctx):
		#self.on_draw(ctx)
		print self.screenlet_width
		print self.screenlet_height
		ctx.scale(self.scale, self.scale)
		ctx.set_source_rgba(1,1,1,1)
		ctx.rectangle(0,0,self.screenlet_width,self.screenlet_height)
		ctx.paint()

	def on_mouse_down(self, event):
		if event.type == gtk.gdk._2BUTTON_PRESS: 
			self.showForecast = not self.showForecast
			if self.window:
				self.redraw_canvas()
				return True
		return False
	
	def draw_weather_icon(self, ctx, iconcode, millal, dayname, hightemp, lowtemp, w, index):
		print 'Draw weather icon'
		# Draw the weather icon
		ikooninimi = self.get_iconfilename(iconcode, millal)+'.png'
		print "IKOONI NIMI: %s" % ikooninimi
		self.draw_scaled_colorized_pixmap(ctx, ikooninimi, w + 45*(index-2), 0, 44, 33, self.iconColor)
		# Display the Day
		if dayname != "":
			self.draw_text(ctx, dayname, w + 45*(index-2)+5, 26, self.verysmallfont, self.textColor)

		# Display the Temperature
		if hightemp != "": 
			hightemp = hightemp+u"° "
			if index == 1:
				width = self.get_text_width(ctx, hightemp, self.bigfont)
				self.draw_text(ctx, hightemp, w + 45*(index-1)-22-width, 1, self.bigfont, self.textColor)
			else:
				width = self.get_text_width(ctx, hightemp, self.smallfont)
				self.draw_text(ctx, hightemp, w + 45*(index-1)-22-width, 2, self.smallfont, self.textColor)
		if lowtemp != "": 
			lowtemp = lowtemp+u"° "
			if index == 1:
				width = self.get_text_width(ctx, lowtemp, self.smallfont)
				self.draw_text(ctx, lowtemp, w + 45*(index-2)+5, 13, self.smallfont, self.textColor)
			else:
				width = self.get_text_width(ctx, lowtemp, self.verysmallfont)
				self.draw_text(ctx, lowtemp, w + 45*(index-2)+5, 14, self.verysmallfont, self.textColor)



	def draw_background(self, ctx, x, w, isOpen, realWidth):

		if isOpen and self.latest != {} and realWidth > 0:
			add = realWidth
		else:
			add = 0

		# draw the normal background
#		ctx.set_source_rgba(self.bg_rgba_color[0], self.bg_rgba_color[1], self.bg_rgba_color[2], self.bg_rgba_color[3])
		ctx.set_source_rgba(self.bgColor[0],self.bgColor[1],self.bgColor[2],self.bgColor[3]) 
		if self.roundCorner:
			self.draw_rounded_rectangle(ctx,x,0, self.scale,w+add, 33)
		else:
			self.draw_rectangle(ctx,x,0, w+add, 33)

		# draw Tray Open/Close Button
		if self.showTrayIcon:
			self.draw_tray_button(ctx, w, isOpen)

	def draw_tray_button(self, ctx, w, isOpen):
		status = "closed"
		if isOpen: status = "open"
		if self.latest != {}:
			self.draw_scaled_colorized_pixmap(ctx,'trayButton-'+status+'.png', w - 10, 22, 9, 9, self.iconColor)
	
	def draw_colorized_pixmap(self, ctx, pixmap, x, y, color):
		#ctx.move_to(x,y);
		#ctx.set_source_surface(self.theme[pixmap], 0, 0)
		#ctx.paint()
		ctx.move_to(x,y)
		ctx.set_source_rgba(color[0], color[1], color[2], color[3])
		ctx.mask_surface(self.theme[pixmap], 0, 0)
		ctx.stroke()

	def draw_scaled_colorized_pixmap(self, ctx, pixmap, x, y, w, h, color):
		# Scale the pixmap
		iw = float(self.theme[pixmap].get_width())
		ih = float(self.theme[pixmap].get_height())
		matrix = cairo.Matrix(xx=iw/w, yy=ih/h)
		matrix.translate(-x, -y)
		pattern = cairo.SurfacePattern(self.theme[pixmap])
		pattern.set_matrix(matrix)
		# Make the pixmap a mask
		ctx.move_to(x,y)
		ctx.set_source_rgba(color[0], color[1], color[2], color[3])
		ctx.mask(pattern)
		ctx.stroke()
	
	def get_text_width(self, ctx, text, font):
		ctx.move_to(0,0)
		if self.p_layout == None :
	
			self.p_layout = ctx.create_layout()
		else:
		
			ctx.update_layout(self.p_layout)
		p_fdesc = pango.FontDescription(font)
		self.p_layout.set_font_description(p_fdesc)
		self.p_layout.set_text(text)
		extents, lextents = self.p_layout.get_pixel_extents()
		return extents[2]

	def get_text_height(self, ctx, text, font):
		ctx.move_to(0,0)
		if self.p_layout == None :
	
			self.p_layout = ctx.create_layout()
		else:
		
			ctx.update_layout(self.p_layout)
		p_fdesc = pango.FontDescription(font)
		self.p_layout.set_font_description(p_fdesc)
		self.p_layout.set_text(text)
		extents, lextents = self.p_layout.get_pixel_extents()
		return extents[3]

	def get_text_extents(self, ctx, text, font):
		ctx.move_to(0,0)
		if self.p_layout == None :
	
			self.p_layout = ctx.create_layout()
		else:
		
			ctx.update_layout(self.p_layout)
		p_fdesc = pango.FontDescription(font)
		self.p_layout.set_font_description(p_fdesc)
		self.p_layout.set_text(text)
		extents, lextents = self.p_layout.get_pixel_extents()
		return extents

	def draw_text(self, ctx, text, x, y, font, color):

		width = self.width

		ctx.save()
		ctx.move_to(x,y)
		if self.p_layout == None :
	
			self.p_layout = ctx.create_layout()
		else:
			
			ctx.update_layout(self.p_layout)

		ctx.set_source_rgba(color[0], color[1], color[2], color[3])
		self.p_fdesc = pango.FontDescription(font)
		self.p_layout.set_font_description(self.p_fdesc)
		self.p_layout.set_width(width * pango.SCALE)
		self.p_layout.set_alignment(pango.ALIGN_LEFT)
		self.p_layout.set_ellipsize(pango.ELLIPSIZE_NONE)
		self.p_layout.set_markup(text)

		ctx.show_layout(self.p_layout)
		ctx.restore()

		return


	def update(self):
		gobject.idle_add(self.update_weather_data)
		self.update_shape()
		return True


	def osis(self, f, kuna, koht):
		ennustus={}
		if not self.nimekirjad_uuendatud:
			self.asukohad = ["Üldine"]
		for e in f.find(kuna):
			# loogika on selline, et kui on asukoha ennustus, siis seda eelistatakse üldisele
			# õigemini: see täpsustab üldist
			if e.tag == 'place':
				if not self.nimekirjad_uuendatud:
#					try:
#						self.asukohad.index(e.find('name').text)
#					except ValueError, ve:
					self.asukohad.append(e.find('name').text)
				if e.find('name').text == koht:
					for p in e:
						ennustus[p.tag] = p.text
			else:
				ennustus[e.tag] = e.text
		if not self.nimekirjad_uuendatud:
			print "UUENDATUD NIMEKIRJAD:"
			print self.asukohad
			print self.ilmajaamad
			self.nimekirjad_uuendatud = True
		return ennustus

	def update_weather_data(self):
	        threading.Thread(target=self.__update_weather_data).start()

	def __update_weather_data(self):

		try:
			self.__lock.acquire()
			print 'Update weather data'

			if time.time() - self.updated_last_time < self.update_interval:
				return

			ilm = {}

			try:
				vaatluse_puu = ElementTree.parse(urllib.urlopen(self.vaatluse_url))
				ennustuse_puu = ElementTree.parse(urllib.urlopen(self.prognoosi_url % self.languageid))
			except IOError, e:
				if hasattr(e, 'reason'):
					print 'We failed to reach a server.'
					print 'Reason: ', e.reason
					self.__notifier.notify("Serveriga ühendumine ebaõnnestus.")
				elif hasattr(e, 'code'):
					print 'The server couldn\'t fulfill the request.'
					print 'Error code: ', e.code
					self.__notifier.notify("Server keeldus päringule vastamast.")
				self.yhendus = False
			else:
				self.yhendus = True

			# asukohtade ja ilmajaamade uuendamine!!!!

			if self.yhendus:

				os = vaatluse_puu.getroot()
				vaatlus={}
				vaatlus['timestamp'] = os.get('timestamp')
				if not self.nimekirjad_uuendatud:
					self.ilmajaamad = []
				for s in os:
					if not self.nimekirjad_uuendatud:
						self.ilmajaamad.append(s.find('name').text)
					if s.find('name').text == self.ilmajaam:
						for p in s:
							vaatlus[p.tag] = p.text # None # DEBUG: TODO: must be: p.text
				ilm['vaatlus'] = vaatlus

				fs = ennustuse_puu.getroot()
				prognoos=[]
				for f in fs:
					yhik={}
					yhik['date'] = f.get('date')
					yhik['night'] = self.osis(f, 'night', self.asukoht)
					yhik['day'] = self.osis(f, 'day', self.asukoht)
					prognoos.append(yhik)
				ilm['prognoos'] = prognoos

			else:

				print "NO CONNECTION", time.asctime(time.localtime())
				gobject.timeout_add(10000, self.update_weather_data)

			if ilm != {}:

				self.updated_last_time = time.time()
				self.latest = ilm
				self.updated_recently = 1

		except:
			traceback.print_exc()
		finally:
			self.__lock.release()

		self.redraw_canvas()


	def get_iconfilename(self, code, millal): 

		print "KOOD: %s (%s)" % (code, millal)

		weather = "unknown"

		if code == "Clear":
			if millal == "day": weather = "clearday"
			elif millal == "night": weather = "clearnight"
		elif code == "Few clouds":
			if millal == "day": weather = "partiallycloudyday"
			elif millal == "night": weather = "partiallycloudynight"
		elif code == "Variable clouds": weather = "windycloudy"
		elif code == "Cloudy with clear spells":
			if millal == "day": weather = "mostlycloudyday"
			elif millal == "night": weather = "mostlycloudynight"
		elif code == "Cloudy": weather = "cloudy"
		elif code == "Overcast": weather = "cloudy"
		elif code == "Light snow shower": weather = "lightsnowshowers"
		elif code == "Moderate snow shower": weather = "snowshowers"
		elif code == "Heavy snow shower": weather = "heavysnowshowers"
		elif code == "Light shower": weather = "sunnyshowers"
		elif code == "Moderate shower": weather = "showers"
		elif code == "Heavy shower": weather = "windyshowers"
		elif code == "Light rain": weather = "drizzle"
		elif code == "Moderate rain":
			if millal == "day": weather = "rain"
			elif millal == "night": weather = "nightrain"
		elif code == "Heavy rain": weather = "heavyrain"
		elif code == "Risk of glaze": weather = "fridged"
		elif code == "Glaze": weather = "fridged"
		elif code == "Light sleet": weather = "lightsleet"
		elif code == "Moderate sleet": weather = "sleet"
		elif code == "Light snowfall": weather = "lightsnowflurries"
		elif code == "Moderate snowfall":
			if millal == "day": weather = "medsnow"
			elif millal == "night": weather = "nightsnow"
		elif code == "Heavy snowfall": weather = "heavysnow"
		elif code == "Snowstorm": weather = "windyheavysnow"
		elif code == "Blowing snow": weather = "windyheavysnow"
		elif code == "Drifting snow": weather = "windysnow"
		elif code == "Hail": weather = "icyrain"
		elif code == "Mist": weather = "hazy"
		elif code == "Fog": weather = "fog"
		elif code == "Thunder": weather = "sunnythunderstorm"
		elif code == "Thunderstorm": weather = "thunderstorms"
		# sisemine
		elif code == "EMHI": weather = "EMHI"
		elif code == "Waiting": weather = "waiting"

		print weather

		return weather


	def on_menuitem_select (self, id):
			"""Called when a menuitem is selected."""
			print "menuitem selected", id
			if id == "ilmajaam":
				self.show_edit_dialog()
				print "UUS ILMAJAAM: ", self.ilmajaam
				print "UUS PROGNOOSIPAIK: ", self.asukoht
			if id == "uuenda":
				self.updated_last_time = 0
				self.update()
#			if id == "ennustuse_koht":
#				self.show_edit_dialog("Prognoosi asukoha valik", "Vali prognoosi asukoht", self.asukoht, self.asukohad)
#				print "UUS PROGNOOSIPAIK: ", self.asukoht
			if id == "ennustuse_tekst":
				self.show_info_dialog()
			pass
		
	def show_edit_dialog(self):
		# create dialog
		dialog = gtk.Dialog('Ilmajaamaa ja ennustuse asukoha valik', self.window)
#		dialog.resize(300, 100)
		dialog.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK, 
			gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
		entrybox_ilmajaamad = gtk.combo_box_new_text()
		print self.ilmajaamad
		for x in self.ilmajaamad:
			entrybox_ilmajaamad.append_text(x)
			print x
		try:
			entrybox_ilmajaamad.set_active(self.ilmajaamad.index(self.ilmajaam))
		except:
			entrybox_ilmajaamad.append_text(self.ilmajaam)
			entrybox_ilmajaamad.set_active(len(clist))

		entrybox_asukohad = gtk.combo_box_new_text()
		print self.asukohad
		for x in self.asukohad:
			entrybox_asukohad.append_text(x)
			print x
		try:
			entrybox_asukohad.set_active(self.asukohad.index(self.asukoht))
		except:
			entrybox_asukohad.append_text(self.asukoht)
			entrybox_asukohad.set_active(len(clist))
			
		label_ilmajaam = gtk.Label('''Vali ilmajaam''')
		dialog.vbox.add(label_ilmajaam)
		dialog.vbox.add(entrybox_ilmajaamad)
		label_asukoht = gtk.Label('''Vali ennustuse asukoht''')
		dialog.vbox.add(label_asukoht)
		dialog.vbox.add(entrybox_asukohad)
		#entrybox.show()	
		dialog.show_all()
		# run dialog
		response = dialog.run()
		if response == gtk.RESPONSE_OK:
			self.asukoht = entrybox_asukohad.get_active_text()
			self.ilmajaam = entrybox_ilmajaamad.get_active_text()
			self.updated_recently = 1
		dialog.hide()

	def callback(self, widget, data=None):
		self.windowpop.destroy()

	def show_info_dialog(self):
        
		self.windowpop = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.windowpop.set_default_size(400, 400)
		self.windowpop.set_title("EMHI prognoosid teksti kujul")
		prognoos_scroller = gtk.ScrolledWindow()
		prognoos_scroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
		prognoos_textarea = gtk.TextView()
		prognoos_scroller.add(prognoos_textarea)

		ilm = self.latest
		text = ""
		for prognoos in ilm['prognoos']:
			text += "*** " + prognoos['date'] + ' ***\n'
			text += "\n---ÖÖ---\n"
			text += self.lisa_jupp(prognoos['night'])
			text += "\n---PÄEV---\n"
			text += self.lisa_jupp(prognoos['day'])
			text += "\n\n"
#		print text


		prognoos_textarea.get_buffer().insert_at_cursor(text)

		prognoos_textarea.set_editable(False)
		prognoos_textarea.set_cursor_visible(False)
		prognoos_textarea.set_wrap_mode(gtk.WRAP_WORD)
		prognoos_textarea.set_justification(gtk.JUSTIFY_LEFT)

		prognoos_containerh = gtk.HBox(False, 10)
		prognoos_containerh.pack_start(prognoos_scroller, True, True, 10)
		olgu = gtk.Button(stock=gtk.STOCK_OK)
		olgu.set_size_request(70, 30)

		olgu.connect("clicked", self.callback, None)
		olgu_containerh = gtk.HBox(False, 10)
		olgu_containerh.pack_start(olgu, False, False, 10)
		halign = gtk.Alignment(1, 0, 0, 0)
		halign.add(olgu_containerh)
		prognoos_containerv = gtk.VBox(False, 10)
		prognoos_containerv.pack_start(prognoos_containerh, True, True, 10)
		prognoos_containerv.pack_end(halign, False, False, 10)
		self.windowpop.add(prognoos_containerv)
		olgu.grab_focus()
		self.windowpop.show_all()

	def lisa_jupp(self, prognoos):
		text = ""
		try:
			text += "\t" + prognoos['text'] + '\n'
		except KeyError, e:
			print "tekst puudu"
		try:
			text += "\nMERI\n\t" + prognoos['sea'] + '\n'
		except KeyError, e:
			print "meri puudu"
		try:
			text += "\nPEIPSI\n\t" + prognoos['peipsi'] + '\n'
		except KeyError, e:
			print "peipsi puudu"
		return text

# If the program is run directly or passed as an argument to the python
# interpreter then create a Screenlet instance and show it
if __name__ == "__main__":
	import screenlets.session
	screenlets.session.create_session(EMHIScreenlet, threading=True)
