#!/usr/bin/env python

import gobject
import pygtk
import gtk
from gtk import gdk
import cairo
import urllib
import xml.dom.minidom
import datetime
import math
import pickle
pygtk.require('2.0')

#moon cycle (29.53 days) Dec 12	4:38 PM 2008 fullmoon

name = "soleil"
size = (256,256)
#environment canada http://www.weatheroffice.gc.ca/rss/city/qc-136_e.xml
#meteomedia http://rss.theweathernetwork.com/weather/caqc0489
url = "http://meteo.gc.ca/rss/city/"
city = "qc-136_e"

def drop(toile,x,y,radius,angle):
	toile.set_source_rgba(0.2, 0.2, 1.0, 0.7)
	toile.arc(x, y, radius, 0-angle, 3.14-angle)
	toile.move_to(x + radius*math.sin(angle+1.57), y + radius*math.cos(angle+1.57))
	toile.line_to(x + 2.4*radius*math.sin(angle-3.14), y + 2.4*radius*math.cos(angle-3.14))
	toile.line_to(x + radius*math.sin(angle-1.57), y + radius*math.cos(angle-1.57))
	toile.fill()
	toile.stroke()
	toile.set_source_rgba(1.0, 1.0, 1.0, 0.7)
	toile.arc(x + 0.5*radius*math.sin(angle+0.785), y + 0.5*radius*math.cos(angle+0.785), 0.2*radius, 0, 6.28)
	toile.fill()
	toile.stroke()
	toile.set_source_rgba(0.2, 0.2, 1.0, 0.7)
	toile.arc(x + 0.4*radius*math.sin(angle+0.785), y + 0.4*radius*math.cos(angle+0.785), 0.2*radius, 0, 6.28)
	toile.fill()
	toile.stroke()
	return

def weather():
	print "Retrieving Weather From The net..."
	rss = urllib.urlopen(url+city+".xml").read()
	print "processing"
	dom = xml.dom.minidom.parseString(rss)
	today = dom.getElementsByTagName("description")[2].toxml()
	d = {}
	for s in today.lstrip("<description>").rstrip("</description>").split("\n"):
		p = s.lstrip("&lt;b&gt;").rstrip("&lt;br/&gt;").split(":")
		if len(p) > 1:
			d[p[0]] = p[1].lstrip("&lt;/b&gt;")
	for s in d:
		print s + ": " + d[s]
	return d

class Soleil(object):
	def __init__(self):
		self.weirdget = gtk.Window()					
		self.weirdget.set_colormap(self.weirdget.get_screen().get_rgba_colormap())	#if this fail , this mean no alpha , it will crash
		(self.w, self.h) = size
		self.weirdget.set_default_size(self.w, self.h)			#(200,200) if not set
		try:
			tmp = open("."+name+".pkl","rb")				#open file if present
			(self.x,self.y) = pickle.load(tmp)				#latest desktop position is serialized here
			self.weirdget.move(self.x,self.y)				#then always start at the same place
		except IOError:
			tmp = open("."+name+".pkl","wb")				#if not present , create it
			(self.x,self.y) = self.weirdget.get_position()			#set default value
			pickle.dump((self.x,self.y),tmp)				#then serialize them in new file
		self.weirdget.set_property("skip-taskbar-hint", True)		#weirdget shouldnt show in taskbar
		self.weirdget.set_property("skip-pager-hint", True)		#weirdget shouldnt show in pager
		self.weirdget.set_title(name)					#weirdget title
		self.weirdget.set_app_paintable(True)
		self.weirdget.set_decorated(False)				#a weirdget is do not use wm decoration
		self.weirdget.stick()						#a weirdget stay on all desktop
		self.weirdget.add_events(gdk.BUTTON_PRESS_MASK)			#allow mouse to click
		self.weirdget.connect('delete-event', gtk.main_quit)		#event quit
		self.weirdget.connect('expose-event', self.draw)		#event draw
		self.weirdget.connect('button-press-event', self.click)		#event click
		gobject.timeout_add(600000, self.update)	#refresh timer
		self.weirdget.show_all()
		gtk.main()

	def update(self):
		#remember position
		(x,y) = self.weirdget.get_position()			#check position		
		if self.x != x and self.y != y:
			self.x,self.y = x,y				#if not the same
			tmp = (x,y)					#replace it
			pickle.dump(tmp, open("."+name+".pkl","wb"))	#and reserialize
		#update draw
		self.weirdget.queue_draw()				#redraw
		return True

	def draw(self,widget, event):
		#(w,h) = widget.get_size()
		w,h = self.w, self.h				#get size for geometry
		toile = widget.window.cairo_create()		#build a cairo canvas
	    	#transparency
		toile.set_source_rgba(1.0, 1.0, 1.0, 0.0)	#set transparent white
		toile.set_operator(cairo.OPERATOR_SOURCE)	
		toile.paint()					#and fill the background
		#cairo draw
		if w < h:
			radius = w/2.0 - 0.8		#calculate radius with the shortest ratio
		else:
			radius = h/2.0 - 0.8
		#	soleil
		t = datetime.datetime.now().hour
		if t > 18 or t < 6:
			toile.set_source_rgba(0.8, 1.0, 0.4, 0.8)
			toile.arc(0.5*w, 0.5*h, 0.9*radius, 0, 6.28)
			toile.fill()
			toile.set_source_rgba(1.0, 1.0, 1.0, 0.0)
			toile.arc(0.7*w, 0.3*h, 0.6*radius, 0, 6.28)
			toile.fill()
			toile.stroke()
		else:
			toile.arc(w/2.0, h/2.0, 0.6*radius, 0, 6.28)		#draw a circle
			toile.set_source_rgba(1.0, 1.0, 0.0, 0.8)		#a yellow hearth
			toile.fill()
			toile.set_line_width(0.2 * radius)
			for rayon in range(10):
				angle = rayon * 6.28 / 10.0
				toile.move_to(w/2.0 + 0.7 * radius * math.sin(angle), h/2.0 + 0.7 * radius * math.cos(angle))
				toile.line_to(w/2.0 + 0.95 * radius * math.sin(angle), h/2.0 + 0.95 * radius * math.cos(angle))
			toile.stroke()
		#	cloud
		toile.set_source_rgba(1.0, 1.0, 0.8, 0.7)
		toile.arc(0.52*w, 0.72*h, 0.24*radius, 0, 6.28)
		toile.fill()
		toile.arc(0.16*w, 0.69*h, 0.3*radius, 0, 6.28)
		toile.arc(0.31*w, 0.53*h, 0.29*radius, 0, 6.28)
		toile.arc(0.48*w, 0.58*h, 0.25*radius, 0, 6.28)
		toile.arc(0.32*w, 0.75*h, 0.3*radius, 0, 6.28)
		toile.fill()
		toile.stroke()
		#	Drop
		toile.set_source_rgba(0.0, 0.0, 0.8, 0.7)
		toile.arc(0.75*w, 0.72*h, 0.3*radius, 0, 6.28)
		toile.fill()
		toile.stroke()
		toile.set_source_rgba(1.0, 1.0, 1.0, 0.7)
		toile.arc(0.75*w, 0.72*h, 0.25*radius, 0, 6.28)
		toile.fill()
		toile.stroke()
		drop(toile,0.75*w,0.85*h,0.1 * radius,0.785)
		drop(toile,0.8*w,0.70*h,0.09 * radius,0.785)
		drop(toile,0.7*w,0.72*h,0.08 * radius,0.785)
		#	weather
		d = weather()
		#		temp
		toile.set_source_rgba(0.0, 0.0, 1.0, 1.0)
		toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		toile.set_font_size(0.3*radius)
		toile.move_to(0.30*w,0.35*h)
		toile.show_text(d["Temperature"])
		toile.stroke()
		#		air
		toile.set_source_rgba(0.2, 0.2, 0.2, 0.8)
		#toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		toile.set_font_size(0.1*radius)
		toile.move_to(0.15*w,0.8*h)
		toile.show_text(d["Wind"])
		#toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		#toile.set_font_size(0.1*radius)
		toile.move_to(0.07*w,0.73*h)
		toile.show_text(d["Pressure / Tendency"])
		#toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		#toile.set_font_size(0.1*radius)
		if "Wind Chill" in d:
			toile.move_to(0.08*w,0.66*h)
			toile.show_text("Wind Chill "+d["Wind Chill"])
		toile.stroke()
		#		humidity
		toile.set_source_rgba(0.0, 0.0, 0.0, 0.8)
		#toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		#toile.set_font_size(0.10*radius)
		toile.move_to(0.65*w,0.8*h)
		toile.show_text(d["Dewpoint"])
		#toile.select_font_face("Georgia",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		#toile.set_font_size(0.1*radius)
		toile.move_to(0.7*w,0.73*h)
		toile.show_text(d["Humidity"])
		toile.stroke()
		#click mask
		clickmask = gtk.gdk.Pixmap(None, w, h, 1)
		clickmaskcairo = clickmask.cairo_create()
		clickmaskcairo.arc(w/2.0, w/2.0, radius, 0, 6.28)
		clickmaskcairo.fill()
		clickmaskcairo.stroke()
		self.weirdget.input_shape_combine_mask(clickmask, 0, 0)
		return False

	def click(self,widget, event):
		#make it movable
		if event.state & gtk.gdk.SHIFT_MASK:
			self.weirdget.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)


if __name__ == '__main__':
	Soleil()
	#weather()

