#!/usr/bin/env python

#    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/>.

#SensorScreenlet (c) Whise <helder.fraga@hotmail.com>

import screenlets
from screenlets import sensors
from screenlets.options import FloatOption, BoolOption, StringOption, IntOption, ColorOption, FontOption
import cairo
import pango
import sys
import gobject
import math
#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

def tdoc(obj):
	obj.__doc__ = _(obj.__doc__)
	return obj

@tdoc
class CircleClockScreenlet(screenlets.Screenlet):
	"""Circle Clock Screenlet."""

	# default meta-info for Screenlets
	__name__ = 'CircleClockScreenlet'
	__version__ = '0.7.1'
	__author__ = 'chh-gx7.deviantart.com'
	__desc__ = __doc__

	# internals
	__timeout = None

	# settings
	update_interval = 1
	show_text = True
	show_time24 = True
	text_prefix = '<span size="xx-small" rise="10000"></span><b>'
	text_suffix = '</b>'
	text_font = "Sans 25"
	font_name = "Sans"
	font_size = 25
	color_back = (1, 1, 1, 0.6)
	color_front =(1, 1, 1, 0.9)
	color_text = (1, 1, 1, 1)
	color_hour = (1, 1, 1, 0.8)
	color_seconds = (1, 1, 1, 0.7)
	sensor = 'CircleClock'
	hour = 0
	min = 0
	sec = 0
	new_time = 0
	day = ''
	show_hour_ring = False
	show_seconds_ring = False
	radius = 86
	y_position = 52
	thin_line = 5
	thick_line = 10

	# constructor
	def __init__(self,**keyword_args):
		screenlets.Screenlet.__init__(self, width=200, height=200, 
			uses_theme=True, **keyword_args)

		self.theme_name = "default"
		# add default menu items
		# add settings
		self.add_options_group(_('Clock'), _('Clock appearance options'))

		self.add_option(BoolOption(_('Clock'), 'show_text',
			self.show_text, _('Show Text'), _('Show the text on the clock face.')))
		self.add_option(BoolOption(_('Clock'), 'show_time24',
			self.show_time24, _('24 Hour time'), _('Show hours with 24 hour format')))
		self.add_option(ColorOption(_('Clock'),'color_back', 
			self.color_back, _('Background color'), _('Background color of clock ring')))
		self.add_option(ColorOption(_('Clock'),'color_front', 
			self.color_front, _('Front color'), _('Front color of clock ring')))
		self.add_option(ColorOption(_('Clock'),'color_text', 
			self.color_text, _('Text color'), _('Text color of date/time display')))
		self.add_option(IntOption(_('Clock'), 'radius',
			self.radius, _('Radius'),
			_('Radius of Front(minutes) circle'), min=70, max=90))
		self.add_option(IntOption(_('Clock'), 'y_position',
			self.y_position, _('Y position'),
			_('Y position of Clock text'), min=50, max=100))
		self.add_option(IntOption(_('Clock'), 'update_interval',
			self.update_interval, _('Update interval'),
			_('Update interval for clock in seconds'), min=1, max=60))
		
		self.add_options_group(_('Additional'), _('Additional Clock appearance options'))

		self.add_option(BoolOption(_('Additional'), 'show_hour_ring',
			self.show_hour_ring, _('Show Hours circle'), _('Show ring for hours additionally')))
		self.add_option(ColorOption(_('Additional'), 'color_hour',
			self.color_hour, _('Hour color'), _('Circle Color of Hour')))
		self.add_option(BoolOption(_('Additional'), 'show_seconds_ring',
			self.show_seconds_ring, _('Show Seconds circle'), _('Show ring for seconds additionally')))
		self.add_option(ColorOption(_('Additional'), 'color_seconds',
			self.color_seconds, _('Seconds color'), _('Circle Color of Seconds')))

		self.add_options_group(_('Font'), _('Font selection'))

		self.add_option(FontOption(_('Font'), 'text_font',
			self.text_font, _('Font lookup'), _('Just lookup for fonts')))
		self.add_option(StringOption(_('Font'), 'font_name',
			self.font_name, _('Font'), _('Font of the clock text')), realtime=False)
		self.add_option(IntOption(_('Font'), 'font_size',
			self.font_size, _('Size'), _('Font size'), min=10, max=26))

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

		self.radius = 86
		self.y_position = 52
		
		# these will be additional options too?
		self.thin_line = 5
		self.thick_line = 10


	def on_init(self):
		self.add_default_menuitems()

	# attribute-"setter", handles setting of attributes
	def __setattr__(self, name, value):
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
		screenlets.Screenlet.__setattr__(self, name, value)
		# check for this Screenlet's attributes, we are interested in:
		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(int(value * 1000), self.update)
			else:
				# TODO: raise exception!!!
				self.__dict__['update_interval'] = 1
				pass

	# timeout-function
	def update(self):
		self.sensor = sensors.cal_get_local_date()
		self.new_time = sensors.cal_get_time()
		if self.show_time24 == False:
			self.new_time = sensors.cal_get_time12()[0:8]
		self.hour = sensors.cal_get_hour()
		self.min = sensors.cal_get_minute()
		self.sec = sensors.cal_get_second()
		self.day = sensors.cal_get_day_name()

		self.redraw_canvas()
		return True

	def on_draw(self, ctx):
		ctx.scale(self.scale, self.scale)
		# draw bg (if theme available)
		ctx.set_operator(cairo.OPERATOR_OVER)
		
		#always draw the hour ring with 12 hour format coz it's quicker readable.
		h = int(sensors.cal_get_hour12())*30
		m = int(self.min)*6 #draw whole minute ring within 60 minutes
		s = int(self.sec)*6

		#self.theme.draw_rounded_rectangle(ctx,0,0,100,self.width,self.height)
		ctx.set_source_rgba(self.color_back[0],self.color_back[1],self.color_back[2],self.color_back[3])
		ctx.set_line_width (self.thick_line)
		ctx.arc (self.width/2,self.height/2,self.radius,0,math.pi*2) # Arc(cx, cy, radius, start_angle, stop_angle)
		ctx.set_line_width (self.thick_line)
		ctx.stroke ()
		ctx.set_source_rgba(self.color_front[0],self.color_front[1],self.color_front[2],self.color_front[3])
		try:
			ctx.arc (self.width/2,self.height/2,self.radius,-math.pi/2,(m*math.pi)/180 -math.pi/2) # Arc(cx, cy, radius, start_angle, stop_angle)
			if self.show_hour_ring == True:
				ctx.stroke ()
				ctx.set_source_rgba(self.color_hour[0],self.color_hour[1],self.color_hour[2],self.color_hour[3])
				ctx.set_line_width (self.thin_line)
				ctx.arc (self.width/2,self.height/2,self.radius-self.thin_line-2,-math.pi/2,(h*math.pi)/180 -math.pi/2)
			if self.show_seconds_ring == True:
				ctx.stroke ()
				ctx.set_source_rgba(self.color_seconds[0],self.color_seconds[1],self.color_seconds[2],self.color_seconds[3])
				ctx.set_line_width (self.thin_line)
				ctx.arc (self.width/2,self.height/2,self.radius+self.thin_line+2,-math.pi/2,(s*math.pi)/180 -math.pi/2)

		except:pass
		#ctx.set_source_rgb (0.3, 0.2, 0.5) # Solid color
	
		ctx.stroke ()
		# draw text
		if len(str(self.new_time))==7:
			self.new_time = "0" + str(self.new_time)

		if self.show_text == True:
			ctx.set_source_rgba(self.color_text[0],self.color_text[1],self.color_text[2],self.color_text[3])
			text = '<small><small><small>' + self.sensor + '</small></small></small>\n' + self.text_prefix + str(self.new_time) + self.text_suffix + '\n' + '<small><small><small>' + self.day + '</small></small></small>'
			if self.theme:self.theme.draw_text(ctx,text, 0, self.y_position, self.font_name, self.font_size, self.width,pango.ALIGN_CENTER)
	
	def on_draw_shape(self,ctx):
		self.on_draw(ctx)


# 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(CircleClockScreenlet)
