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

#  BrightnessScreenlet (c) Whise 2007 

import screenlets
from screenlets.options import BoolOption, ColorOption 
from screenlets import DefaultMenuItem
import pango
import dbus
import cairo
import gobject
#use gettext for translation
import gettext

_ = screenlets.utils.get_translator(__file__)

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

@tdoc
class BrightnessScreenlet (screenlets.Screenlet):
	"""A Screenlet that allows you to change the brightness of the screen using the mouse's scrollwheel"""
	
	# default meta-info for Screenlets (should be removed and put into metainfo)
	__name__	= 'BrightnessScreenlet'
	__version__	= '0.1.2'
	__author__	= 'Helder Fraga aka Whise'
	__desc__	= __doc__	# set description to docstring of class

	brightness = 0.0
	use_gradient = True
	horizontal = False


	font = "Sans Normal 12"
	color_text = (1,1,1,0.8)
	frame_color = (1,1,1,0.8)
	frame_color_selected = (1,1,1,0.8)
	bar_color = (1,1,1,0.8)
	toggle_color = (0,1,0,0.8)

	start = None

	# constructor
	def __init__ (self, **keyword_args):
		#call super (width/height MUST match the size of graphics in the theme)
		screenlets.Screenlet.__init__(self, width=50, height=140, 
			uses_theme=False, resize_on_scroll= False, **keyword_args)
		
		self.brightness = 0.0
		
		# add option group
		self.add_options_group(_('Options'), _('Options'))

		self.add_option(BoolOption(_('Options'),'use_gradient', 
			True, _('Paint with gradient'), 
			_('Use gradient')))

		self.add_option(BoolOption(_('Options'),'horizontal', 
			False, _('Display horizontaly'), 
			_('Display horizontaly')))

		self.add_option(ColorOption(_('Options'),'frame_color', 
			(1, 1, 1, 1), _('Frame color'), 
			_('Frame color')))
			
		self.add_option(ColorOption(_('Options'),'bar_color', 
			(0, 0, 1, 1), _('Frame color'), 
			_('Frame color')))
			
		self.add_option(ColorOption(_('Options'),'toggle_color', 
			(0, 0, 0, 0.6), _('Toggle color'), 
			_('Toggle color')))
			
		self.add_default_menuitems()
		self.start = gobject.timeout_add(1000, self.check_for_bus)

	def set_brightness(self, brightness):
		try:
			self.brightness = brightness
			self.hal_interface.SetBrightness(brightness)
			self.redraw_canvas()
		except:
			screenlets.show_error(None, _("Sorry, brightness could not be set. Please try running a freedesktop.org power managmement daemon."))

	def __setattr__(self, name, value):
		screenlets.Screenlet.__setattr__(self, name, value)
		if name == 'horizontal':
			if value == True:
				self.width = 140
				self.height = 50
			elif value == False:
				self.width = 50
				self.height = 140
	
	# ONLY FOR TESTING!!!!!!!!!
	def init_options_from_metadata (self):
		"""Try to load metadata-file with options. The file has to be named
		like the Screenlet, with the extension ".xml" and needs to be placed
		in the Screenlet's personal directory. 
		NOTE: This function always uses the metadata-file relative to the 
			  Screenlet's location, not the ones in SCREENLETS_PATH!!!"""
		print __file__
		p = __file__.rfind('/')
		mypath = __file__[:p]
		print mypath
		self.add_options_from_file( mypath + '/' + \
			self.__class__.__name__ + '.xml')
	
	def check_for_bus(self):
		try:
			bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
			self.hal_object = bus.get_object('org.freedesktop.PowerManagement','/org/freedesktop/PowerManagement/Backlight')
			self.hal_interface = dbus.Interface(self.hal_object,'org.freedesktop.PowerManagement.Backlight')
			self.hal_interface.connect_to_signal(_('BrightnessChanged'), lambda *args:self.update(*args))
			self.brightness = self.hal_interface.GetBrightness()
			return False
		except:
			return True

	def on_scroll_up (self):
		"""Called when mousewheel is scrolled up (button4)."""
		if self.brightness +5 >= 0 and self.brightness +5 <= 100:
			self.set_brightness(self.brightness+5)

	def on_scroll_down (self):
		"""Called when mousewheel is scrolled down (button5)."""
		if self.brightness -5 >= 0 and self.brightness-5  <= 100:
			self.set_brightness(self.brightness-5)
	
	def on_draw (self, ctx):
		"""In here we draw"""
		ctx.scale(self.scale, self.scale)
		if self.use_gradient:
			gradient = cairo.LinearGradient(0, self.height*2, 0, 0)
			gradient.add_color_stop_rgba(1, *self.frame_color)
			gradient.add_color_stop_rgba(0.7, self.frame_color[0], self.frame_color[1], self.frame_color[2], 1-self.frame_color[3]+0.5)

			ctx.set_source(gradient)
		else:
			ctx.set_source(*self.frame_color)
		self.draw_rectangle_advanced (ctx, 0, 0, self.width-12, self.height-12, rounded_angles=(5,5,5,5), fill=True, border_size=2, border_color=(0,0,0,0.5), shadow_size=6, shadow_color=(0,0,0,0.5))
		if self.use_gradient:
			gradient = cairo.LinearGradient(self.width*2,0,0, 0)
			gradient.add_color_stop_rgba(1,*self.bar_color)
			gradient.add_color_stop_rgba(0.7,self.bar_color[0],self.bar_color[1],self.bar_color[2],1-self.bar_color[3]+0.5)

			ctx.set_source(gradient)
		else:
			ctx.set_source(self.bar_color)
		if self.horizontal:
			a = 20	
			b = self.height/4
			c = self.brightness
			d = self.height/2
		else:
			a = self.width/4
			b = (self.height -20)-self.brightness
			c = self.width/2
			d = self.brightness
		self.draw_rectangle(ctx, a, b, c, d)
				
	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__":
	# create new session
	import screenlets.session
	screenlets.session.create_session(BrightnessScreenlet)

