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

import screenlets
from screenlets.options import DirectoryOption, ColorOption, IntOption, BoolOption, StringOption
from screenlets.options import create_option_from_node
from screenlets import DefaultMenuItem
import pango
import gobject
import os
import random
from datetime import datetime

pil_image_loaded = False

try:
	import PIL.Image
	pil_image_loaded = True
except:
	screenlets.show_error(None, _("To enable all features of PhotoWall, please install the python image module"))


#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

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

@tdoc
class PhotoWallScreenlet (screenlets.Screenlet):
	"""Loads a new wallpaper at set time intervals (or set times) from a set of selected pictures"""
	
	# default meta-info for Screenlets (should be removed and put into metainfo)
	__name__	= 'PhotoWallScreenlet'
	__version__	= '0.4.1'
	__author__	= 'Alex Konstantinou'
	__desc__	= __doc__

	GNOME_WALLPAPER_OPTIONS = ['centered', 'scaled', 'stretched', 'wallpaper', 'zoom']
	gnome_wallpaper_option = GNOME_WALLPAPER_OPTIONS[4]

	main_text = "-"
	text_font = "Sans Medium 5"
	text_color = (0.7, 1.0, 0.9, 1.0)
	bg_color = (0.0, 0.0, 0.0, 0.85)
	pic_types = ['.jpg', '.gif', '.png','.bmp', '.svg', '.jpeg', '.tif', '.tiff']
	photos = []
	photo_pnt = -1
	photo_directory = ''
	reload_interval = 30
	mins_remaining = 30
	subfolders = False
	randomphoto = False
	reload_times = ''
	reload_times_list = []
	reload_with_interval = False
	photos_loaded = False
	current_photo_filename = ''

	# constructor
	def __init__ (self, **keyword_args):

		#call super (width/height MUST match the size of graphics in the theme)
		screenlets.Screenlet.__init__(self, width=200, height=40, 
			uses_theme=True, **keyword_args)

		# set theme
		self.theme_name = "png"

		# Settings
		self.add_options_group(_('Photo'), _('Photo options'))
		self.add_option(DirectoryOption(_('Photo'),'photo_directory', self.photo_directory, 
			_('Photo directory'), _('Directory containg photos')))
		self.add_option(BoolOption(_('Photo'), 'subfolders', self.subfolders, _('Include sub-folders'),_('Also load images in sub-folders')))
		self.add_option(BoolOption(_('Photo'), 'randomphoto', self.randomphoto, _('Shuffle photos'),_('Loads photos in a random order')))
		self.add_option(IntOption(_('Photo'),'reload_interval', 
			self.reload_interval, _('Reload interval (minutes)'), 
			_('Reload interval (minutes)'), 
			min=1, max=300))

		self.add_options_group(_('Display'), _('Display options'))
		self.add_option(ColorOption(_('Display'),'text_color', 
			self.text_color, _('Text color'), 
			_('Text color')))
		self.add_option(ColorOption(_('Display'),'bg_color', 
			self.bg_color, _('Background color'), 
			_('Text bg_color')))
		self.add_option(ColorOption(_('Display'),'text_color', 
			self.text_color, _('Text color'), 
			_('Text color')))
		self.add_option(ColorOption(_('Display'),'bg_color', 
			self.bg_color, _('Background color'), 
			_('Text bg_color')))

		self.add_options_group(_('Advanced'), _('Advanced options'))
		self.add_option(StringOption(_('Advanced'),'reload_times',
			self.reload_times,	
			_('Reload at set times'),
			_('Change photo at a specific times during the day. Enter times using HH:MM format (e.g. 08:00, 19:30). Enter a set of times using a comma-separated list (e.g. "10:00, 16:00, 20:00").')
			))		

	def on_init (self):
		# add menu item
		self.add_menuitem("mi_about", _("About PhotoWalls"))
		self.add_menuitem("mi_info",_("Information"))
		self.add_menuitem("mi_change_photo",_("Change photo"))
		self.add_menuitem("mi_load_photos",_("Load photos"))

		# add default menu items
		self.add_default_menuitems()

		self.load_set_times()
		self.mins_remaining = self.reload_interval
		self.timer = gobject.timeout_add(60000, self.minute_timer)	
		self.load_photos()

	def load_set_times(self):
		times = self.reload_times.rsplit(',')
		for time in times:
			time = time.strip()
			if (len(time) != 5 or time[2] != ':'): continue
			hour = int(time[0:2])
			min = int(time[3:5])
			if (not(hour < 24 and hour >= 0 and min <= 60 or min >= 0)): continue
			
			if hour > 9:
				hour_str = hour
			elif hour > 0:
				hour_str = '0'+ str(hour)
			else:
				hour_str = '00';
			
			if min > 9:
				min_str = str(min)
			elif min > 0:
				min_str = '0'+ str(min)
			else:
				min_str = '00';
			
			time_str = hour_str + ':' + min_str 	
			ti = [hour, min, hour_str, min_str, time_str]
			self.reload_times_list.append(ti)
		self.reload_with_interval = len(self.reload_times_list) < 1
		pass
		

	def load_photos(self):
		if(not os.path.isdir(self.photo_directory)):
			self.warning_invalid_directory()
		else:
			self.photos = []
			self.photo_pnt = -1
#			wall_photos = os.listdir(self.photo_directory)

			if self.subfolders:
				for root, dirs, files in os.walk(self.photo_directory): 
					for file in files:
						try:
							if os.path.splitext(file)[1].lower() in self.pic_types:
								self.photos.append(os.path.join(root,file))
						except:
							pass				
			else:
				if os.path.exists(self.photo_directory) and os.path.isdir(self.photo_directory): 
					for f in os.listdir(self.photo_directory):				
						try:
							if os.path.splitext(f)[1].lower() in self.pic_types: 
								self.photos.append(self.photo_directory + os.sep + f)
						except:
							pass

			if ((len(self.photos)) < 1):
				self.warning_empty_directory()
			else:
				self.photos_loaded = True;
				self.update_image()

	def warning_invalid_directory(self):
		screenlets.show_message(self, _('Please set a directory containing images in the screenlet preferences'))
		self.main_text = _('No photowall images')
		self.redraw_canvas()
		pass

	def warning_empty_directory(self):
		msg = _('Please set a directory containing images in the screenlet preferences.\n\n') 
		msg += _('Directory does not contain jpeg images:\n') + self.photo_directory
		screenlets.show_message(self, msg)
		self.main_text = _('No photowall images')
		self.redraw_canvas()
		pass

	def minute_timer (self):
		if (self.reload_with_interval):
			self.mins_remaining = self.mins_remaining - 1
			if (self.mins_remaining < 1):
				self.update_image()
				self.mins_remaining = self.reload_interval
		else:
			times = self.reload_times_list
			now = datetime.now()
			for time in times:
				h = time[0]
				m = time[1]
				if (now.hour== h and now.minute == m):
					self.update_image()
		return True

	def update_image (self):
		if (self.randomphoto):
			self.photo_pnt = random.randrange(0,len(self.photos))
		else:
			self.photo_pnt = self.photo_pnt + 1
			self.photo_pnt = self.photo_pnt % len(self.photos)
	
		tmp = self.photos[self.photo_pnt]
		indx = tmp.rfind('/') + 1
		tmp = tmp[indx:len(tmp)]
		self.current_photo_filename = tmp 
		if (len(tmp) > 12):
			tmp = tmp[0:9] + '..' + tmp[len(tmp) - 4:len(tmp)]
		self.main_text = '[' + str(self.photo_pnt + 1) + '/' + str(len(self.photos)) + '] ' + tmp
		self.set_image(self.photos[self.photo_pnt])
		self.redraw_canvas()
		pass

	def on_menuitem_select (self, id):
		"""Called when a menuitem is selected."""
		if id == "mi_about":
			screenlets.show_message(self, self.__desc__)
		elif id == "mi_change_photo":
			self.change_photo()
		elif id == "mi_info":
			if (not self.photos_loaded):
				self.load_photos()
			else:
				msg = _('Photo: ') + str(self.photo_pnt + 1)+ ' of ' + str(len(self.photos)) + '\n'
				msg += _('Filename: ') + self.current_photo_filename + '\n\n'
				if (self.reload_with_interval):
					msg += _('Photos change every ') + str(self.reload_interval) + _(' minutes.\n')
					msg += _('Next photo will load in ') + str(self.mins_remaining) + _(' minutes.\n')
				else:
					msg += _('Photos are set to change at specific times:\n')
					for reload_time in self.reload_times_list:				
						msg += reload_time[4] + ' '
					msg += '\n'
				screenlets.show_message(self, msg)
		elif id == "mi_load_photos":
			self.load_photos()
		pass
	
	def change_photo(self):
		if (not self.photos_loaded):
			self.load_photos()

		if (self.photos_loaded):			
			self.update_image()
			self.mins_remaining = self.reload_interval

	def on_draw (self, ctx):
		# if theme is loaded
		if self.theme:
			
			# set scale rel. to scale-attribute
			ctx.scale(self.scale, self.scale)
			ctx.set_source_rgba(self.bg_color[0], self.bg_color[1], self.bg_color[2], self.bg_color[3])	
			self.theme.draw_rounded_rectangle(ctx,0,0,20, self.width, self.height)

			self.theme.render(ctx, 'PhotoWall')
			ctx.set_source_rgba(self.text_color[0], self.text_color[1], self.text_color[2], self.text_color[3])	
			self.theme.draw_text(ctx, self.main_text, 8, 12, self.text_font , 10, self.width - 5, pango.ALIGN_LEFT)

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

	def set_wallpaper_options(self):
		"""Sets the GNOME/KDE wallpaper options."""
		os.system("gconftool-2 -t string -s /desktop/gnome/background/picture_options "
			+ self.gnome_wallpaper_option)
		
#		if self.gnome_wallpaper_option == 'stretched': 
#			kde_wall = 6
#		else:
#			kde_wall = 7
#		try:
#			os.system("/usr/bin/dcop kdesktop KBackgroundIface setWallpaper " + self.wpath + "/wallpaper.png " + kde_wall)
#		except:
#			pass
        pass

	def set_image(self, img_path):
		
		if (pil_image_loaded):
			image = PIL.Image.open(img_path)
			if (image.size[1] > image.size[0]):
				self.gnome_wallpaper_option = self.GNOME_WALLPAPER_OPTIONS[1]
			else:
				self.gnome_wallpaper_option = self.GNOME_WALLPAPER_OPTIONS[4]
		else:
			self.gnome_wallpaper_option = self.GNOME_WALLPAPER_OPTIONS[4]

		self.set_wallpaper_options()

#		if self.xfce_workarround:
#			os.system ("killall -USR1 xfdesktop &")
		os.system("gconftool-2 -t string -s /desktop/gnome/background/picture_filename \"" + img_path + "\"")
	
		#os.system("gconftool-2 -t bool -s /desktop/gnome/background/draw_background False")
		#os.system("gconftool-2 -t bool -s /desktop/gnome/background/draw_background True")
		
#		if self.gnome_wallpaper_option == 'stretched': 
#			kde_wall = 6
#		else:
#			kde_wall = 7
#		try:
#			os.system("/usr/bin/dcop kdesktop KBackgroundIface setWallpaper " + img + kde_wall)
#		except:
#			pass
        pass

	def on_mouse_down (self, event):
		if (str(event.type) == "<enum GDK_2BUTTON_PRESS of type GdkEventType>"):
			self.change_photo()
		return False

# 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__":
	# create new session
	import screenlets.session
	screenlets.session.create_session(PhotoWallScreenlet)

