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

#  CountdownScreenlet (c) Patrik Kullman 2007 <patrik@yes.nu>
#
# INFO:
# - Count down to a specific event
# 
# TODO:
# -  beautify
#
# CHANGELOG:
# v0.2:
# - centered text
# - display the event text instead of a negative countdown
# 
# v0.1:
# - initial version

import screenlets
from screenlets.options import StringOption
import cairo
import gtk
import pango
import time
from os import system
import gobject
#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

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

@tdoc

class CountdownScreenlet(screenlets.Screenlet):
	"""Display time left to a specific date and time"""
	
	# default meta-info for Screenlets
	__name__ = 'CountdownScreenlet'
	__version__ = '0.3'
	__author__ = 'Patrik Kullman'
	__desc__ = __doc__

	# internals
	__timeout = None
	p_layout = None
	# editable options and defaults
	__update_interval = 1 # every second
	text = "New Year 2012"
	to_date = "2012-01-01 00:00:00"
		
	# constructor
	def __init__(self, **keyword_args):
		# call super
		screenlets.Screenlet.__init__(self, width=300, height=100, **keyword_args)
		# set theme
		self.theme_name = "default"
		
		# add option groups
		self.add_options_group(_('Countdown'), _('Countdown settings'))
		self.add_option(StringOption(_('Countdown'),
			'text', 						# attribute-name
			self.text,						# default-value
			_('Countdown text'), 						# widget-label
			_('What to count down to') # description
			))
		self.add_option(StringOption(_('Countdown'),
			'to_date', 						# attribute-name
			self.to_date,						# default-value
			_('Countdown to'), 						# widget-label
			_('The DateTime (YYYY-MM-DD HH:MM:SS) to count down to') # description
			))
		# add default menu items
		self.add_default_menuitems()
		self.__timeout = gobject.timeout_add(self.__update_interval * 1000, self.update)

	def __setattr__(self, name, value):
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
		screenlets.Screenlet.__setattr__(self, name, value)
		# redraw the canvas when server-info is changed since a server host/ip addition/removal will change the size of the screenlet

	def update(self):
		gobject.idle_add(self.redraw_canvas)
		return True

	def on_draw(self, ctx):
		self.__timeleft = self.get_time_left(self.to_date)
		# scaling above 500% is very slow and might brake it (why?)
		if self.scale > 5:
			self.scale = 5
		# if theme is loaded
		if self.theme:
			# find out how many servers that are configured and force a update_shape() when they're changed from the last draw.
			# apparently the settings doesn't get loaded until the widget is first displayed, and no update_shape is performed at
			# that point
			# make sure that the background covers all the icons
			ctx.save()
			ctx.scale(self.scale * 1.5, self.scale)
			ctx.translate(0, 0)
			self.theme.render(ctx, 'background')
			ctx.restore()

			ctx.save()
			ctx.scale(self.scale, self.scale)
			self.draw_text(ctx, _("Time left to: ") + self.text, 10, 10, 12)
			self.draw_text(ctx, self.__timeleft, 10, 45, 18)
			ctx.restore()

			ctx.save()
			ctx.scale(self.scale * 1.5, self.scale)
			ctx.translate(0, 0)
			self.theme.render(ctx, 'glass')
			ctx.restore()

	def on_draw_shape(self, ctx):
		if self.theme:
			self.on_draw(ctx)

	def draw_text(self, ctx, value, x, y, size):
		# stolen from CalcScreenlet ;)
		ctx.save()
		ctx.translate(x, y)
		if self.p_layout == None : 
			self.p_layout = ctx.create_layout() 
		else: 
			ctx.update_layout(self.p_layout)
		p_fdesc = pango.FontDescription()
		p_fdesc.set_family_static("Sans")
		p_fdesc.set_size(size * pango.SCALE)
		self.p_layout.set_font_description(p_fdesc)
		self.p_layout.set_width(280 * pango.SCALE)
		self.p_layout.set_alignment(pango.ALIGN_CENTER)
		self.p_layout.set_markup(value)
		ctx.set_source_rgba(1, 1, 1, 0.8)
		ctx.show_layout(self.p_layout)
		self.p_layout.set_alignment(pango.ALIGN_LEFT)
		ctx.restore()

	def get_time_left(self, date):
		try:
			then = time.mktime(time.strptime(date, "%Y-%m-%d %H:%M:%S"))
			now = time.time()
			seconds_left = then - now
			if (seconds_left > 0):
				days_left = int(seconds_left / 60 / 60 / 24)
				seconds_left = seconds_left - (days_left * 24 * 60 * 60)
				hours_left = int(seconds_left / 60 / 60)
				seconds_left = seconds_left - (hours_left * 60 * 60)
				minutes_left = int(seconds_left / 60)
				seconds_left = int(seconds_left - (minutes_left * 60))
				return str(days_left) + "d " + str(hours_left) + "h " + str(minutes_left) + "m " + str(seconds_left) + "s"
			else:
				return self.text + "!"
		except ValueError:
			return _("Invalid date format")
	
# 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(CountdownScreenlet)
