#!/usr/bin/env python

import gobject
import pygtk
pygtk.require('2.0')
import gtk
from gtk import gdk
import cairo
import datetime
import calendar
import math
import pickle

name = "kalendar"
size = (512,256)
weekdays = ["Monday", "Thuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
months = ["January","February","March","April","May","June","July","August","September","October","November","December"]

class Kalendar(object):
	def __init__(self):
		#global size
		self.now = datetime.datetime.now()
		self.calendar = calendar.TextCalendar()
		self.month = self.calendar.formatmonth(self.now.year,self.now.month)
		self.lastmonth = self.calendar.formatmonth(self.now.year,self.now.month-1)
		self.nextmonth = self.calendar.formatmonth(self.now.year,self.now.month+1)
		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(3600000, 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
		#date
		self.now = datetime.datetime.now()
		self.month = self.calendar.formatmonth(self.now.year,self.now.month)
		self.lastmonth = self.calendar.formatmonth(self.now.year,self.now.month-1)
		self.nextmonth = self.calendar.formatmonth(self.now.year,self.now.month+1)
		#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
		#	circle
		toile.arc(0.5*w, 0, radius*2, 0, 3.14)			#draw a circle
		toile.set_source_rgba(0.0, 0.0, 0.3, 0.3)		#a blue hearth
		toile.fill()
		toile.stroke()						#end of polygon
		#drawing text
		toile.set_source_rgba(1.0, 1.0, 1.0, 1.0)
		toile.select_font_face("Mono", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		#this month
		toile.set_font_size(0.12 * radius)
		x,y = 0.35 , 0.5
		for text in self.month.split("\n"):
			toile.move_to(x * w, y * h)
			toile.show_text(text)
			toile.stroke()
			y += 0.06
		#last month
		toile.set_font_size(0.08 * radius)
		x,y = 0.1 , 0.2
		for text in self.lastmonth.split("\n"):
			toile.move_to(x * w, y * h)
			toile.show_text(text)
			toile.stroke()
			y += 0.04
		#next month
		toile.set_font_size(0.08 * radius)
		x,y = 0.7 , 0.2
		for text in self.nextmonth.split("\n"):
			toile.move_to(x * w, y * h)
			toile.show_text(text)
			toile.stroke()
			y += 0.04
		#today
		toile.set_font_size(0.2 * radius)
		toile.move_to(0.45 * w, 0.1 * h)
		toile.show_text(weekdays[self.now.weekday()])
		#toile.stroke()
		toile.move_to(0.4 * w, 0.2 * h)
		toile.show_text(str(self.now.day))
		#toile.stroke()
		toile.move_to(0.5 * w, 0.2 * h)
		toile.show_text(months[self.now.month])
		#toile.stroke()
		toile.move_to(0.45 * w, 0.3 * h)
		toile.show_text(str(self.now.year))
		toile.stroke()
		#click mask
		clickmask = gtk.gdk.Pixmap(None, w, h, 1)
		clickmaskcairo = clickmask.cairo_create()
		clickmaskcairo.arc(0.5*w, 0, 2* radius, 0, 3.14)
		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__':
	Kalendar()

