def __init__(self):
		self.lyrics = None
		self.lyricsTimer = None
		self.player = Player()
		self.player.registerOnPlayerConnected(self.onPlayerConnected)
		self.player.registerOnSongChange(self.onSongChanged)
		self.player.registerOnPlay(self.onPlay)
		self.player.registerOnStop(self.onStop)
		self.player.registerOnElapsedChanged(self.onSeek)
		self.lyricsEngine = LyricsEngine(self.onLyricsFound, self.onEngineFinish)
		self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet'])
		
		self.label = gtk.Label("Lyrics Applet")
		self.gconf_client = gconf.client_get_default()
		self.gconf_client.add_dir("/apps/lyrics_applet", gconf.CLIENT_PRELOAD_NONE)
		self.gconf_client.notify_add('/apps/lyrics_applet/color', self.color_changed)
		self.gconf_client.notify_add('/apps/lyrics_applet/font', self.font_changed)
		
		self.color_changed(None)
		self.font_changed(None)
class LyricsScreenlet(screenlets.Screenlet):#Widget
	"""Shows lyrics of the linux audio players"""
	# default meta-info for Screenlets
	__name__    = 'Lyrics Screenlet'
	__version__ = '0.7.1+'
	__author__  = 'Marcel Dancak'
	__desc__    = __doc__
	
	invisible          = False
	maximized          = None
	maxi_width		   = 300
	maxi_height        = 155
	state              = None
	player	           = None
	playing			   = False
	songInfo		   = None
	lyricsPanel		   = None
	autoHideTimer	   = None
	autoColorTimer     = None
	
	lyricsList         = None
	lyrics_index       = 0 
	
	install_path       = None
	lyrics_directory   = os.environ['HOME']
	saveFirstLyrics    = False # save flag for addlyrics
	save_lyrics        = False
	dirOption          = None
	filter_cjk         = True
	autoColorAdapt     = False
	autoPanelHide      = True
	colorAdaptation    = 'None'
	textAlign          = _('Center')
	translation_enabled = False
	language           = None
	
	# graphics, forwarded to LyricsPanel
	text_scale      = None
	font            = "sans 9"
	color_normal    = None
	color_highlight = None
	
	canvas          = None
	dimensions      = None
	#controlPanel 	= None
	minimizeToTray  = False
	trayIcon        = None
	safe_minimize   = True
	
	# constructor
	def __init__(self, **keyword_args):

		#call super (and not show window yet)
		screenlets.Screenlet.__init__(self, uses_theme=True, width=64, height=64, drag_drop=True, **keyword_args)
		self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
		self.translateMenuItem = gtk.CheckMenuItem("Google Translate")
		self.translateMenuItem.connect("activate", lambda item: self.__setattr__('translation_enabled', item.get_active()))
		self.translateMenuItem.show()

		#print dir(self.window.get_screen())
		#print self.window.get_screen().is_composited()
		#print self.window.get_screen().get_rgba_colormap()
		
		self.lyricsPanel = LyricsPanel()
		#self.lyricsPanel = LyricsAnimation()

		# path to screenlet installation directory
		self.install_path = path.dirname(path.abspath(__file__)) + os.sep	
		sys.path.append(self.install_path)
		
		# Options
		self.add_options_group(_('Lyrics'), _('Lyrics settings'))
		self.add_option(FontOption (_('Lyrics'), 'font', self.font, _('Font'), _('The font of lyrics')))
		self.add_option(ColorOption(_('Lyrics'), 'color_normal', self.color_normal, _('Normal Color'), _('Color of the common text')))
		self.add_option(ColorOption(_('Lyrics'), 'color_highlight', self.color_highlight, _('Highlight Color'), _('Color of the actual line')))
		self.add_option(StringOption(_('Lyrics'), 'colorAdaptation', self.colorAdaptation, _('Color Adaptation'), _('Lyrics text color adaptation by background'), choices = [_('None'), _('Inverse'), _('Black or White')]))
		self.add_option(FloatOption(_('Lyrics'), 'text_scale', self.text_scale, _('Text Scale'), _('Maximum scale of the highlighted text'), min=1, max=2, increment=0.05, digits=2))
		self.add_option(StringOption(_('Lyrics'), 'textAlign', self.textAlign, _('Text Align'), _('Lyrics text align'), choices = sorted(text_aligns)))
		
		self.add_option(BoolOption(_('Lyrics'), 'save_lyrics', self.save_lyrics, _('Save lyrics'), _('Allow saving downloaded lyrics to the selected directory')))
		self.dirOption = DirectoryOption(_('Lyrics'), 'lyrics_directory', self.lyrics_directory, _('Lyrics Directory'), _('Directory, where will be downloaded lyrics saved'))
		self.add_option(self.dirOption)
		self.add_option(BoolOption(_('Lyrics'), 'filter_cjk', self.filter_cjk, _('Filter some languages'), 
			_('Filter Chinese, Japanese, Korean languages (maybe more), which may cause troubles with scaling text during animation ')))
		
		self.add_option(BoolOption(_('Lyrics'), 'autoPanelHide', self.autoPanelHide, _('Hiding Control panel'), _('Hide Control panel when window loose focus')))
		self.add_option(BoolOption(_('Lyrics'), 'minimizeToTray', self.minimizeToTray, _('Use Tray Icon'), _('Use Tray Icon')))
		self.add_option(BoolOption(_('Lyrics'), 'safe_minimize', self.safe_minimize, _('Safe minimizing'), _('Use safe minimizing without real window resizing')))
		
		
		self.add_options_group(_('Google Translate'), _('Google Translate settings'))
		self.add_option(BoolOption(_('Google Translate'), 'translation_enabled', self.translation_enabled, _('Enabled'), _('Google Translate')))
		self.add_option(StringOption(_('Google Translate'), 'language', self.language, _('Language'), _('Language'), choices = sorted(languages)))
		
		
		self.lyricsEngine = LyricsEngine(self.addLyrics, self.onEngineFinish)
		self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet'])
		#self.lyricsEngine.setLyricsSources(['lyricsscreenlet'])
		
		self.player = player.Player()
		self.xmmsPlayer = None
		for p in self.player.player_list:
			if p.__name__ == "xmms":
				self.xmmsPlayer = p
		self.player.registerOnSongChange(self.onSongChanged)
		self.player.registerOnPlay(self.onPlay)
		self.player.registerOnStop(self.onStop)
		self.player.registerOnElapsedChanged(self.onElapsed)
		self.player.registerOnPlayerConnected(self.onPlayerConnected)
		self.player.registerOnPlayerDisconnected(self.onPlayerDisconnected)
		self.player.registerOnActivePlayerListChange(self.onPlayerListChange)
		
		
		self.disconn = ImageButton('disconnected', 'disconnected')
		self.disconn.registerEvent('button_pressed', self.on_minimized_pressed)
		self.disconn.registerEvent('button_pressed', self.lyricsPanel_pressed) # moving screenlet
		self.disconn.registerEvent('resized', self.on_minimized_resized)
		self.disconn.setPosition(0, 0)
		self.disconn.setVisible(False)
		self.disconn.rectangleBounds = True # better for transparent images/themes
		
		templateAnim = Animation(100, 6)
		templateAnim.addLinearTransition('setOverAlpha', 0.0, 1.0, LINEAR)
		templateAnim.addTransition('scale', LinearVectorInterpolator([1.0, 1.0], [1.4, 1.4]), LINEAR)
				
		pressedAnim = Animation(4, 20)
		pressedAnim.addTransition('scale', LinearVectorInterpolator([1.4, 1.4], [1.25, 1.25]), LINEAR)
		
		self.next = ImageButton('next', 'next_over')
		self.next.registerEvent('button_pressed', self.nextLyrics)
		self.next.setEnterAnimation(templateAnim.create(self.next))
		self.next.setPressedAnimation(pressedAnim.create(self.next))
		
		self.prev = ImageButton('prev', 'prev_over')
		self.prev.registerEvent('button_pressed', self.previousLyrics)
		self.prev.setEnterAnimation(templateAnim.create(self.prev))
		self.prev.setPressedAnimation(pressedAnim.create(self.prev))
		
		self.save = ImageButton('harddisk', 'harddisk')
		self.save.registerEvent('button_pressed', self.saveButtonPressed)
		self.save.setEnterAnimation(templateAnim.create(self.save))
		self.save.setEnabled(self.save_lyrics)
		
		self.search = ImageButton('search', 'search')
		self.search.registerEvent('button_pressed', self.onSearchClicked)
		self.search.setEnterAnimation(templateAnim.create(self.search))
		
		self.upload = ImageButton('upload', 'upload')
		self.upload.registerEvent('button_pressed', self.uploadButtonPressed)
		self.upload.setEnterAnimation(templateAnim.create(self.upload))
		
		self.invisibleButton = ImageButton('bubak', 'bubak')
		self.invisibleButton.visibilityThreshold = 50 # more transparent icon is planned for this
		self.invisibleButton.registerEvent('button_pressed', self.invisible_pressed)
		
		self.notifier = Label(_('Uploaded '), fixedSize = False)
		self.notifier.bgColor = [0.7, 0.4, 0.4, 0.8]
		self.notifier.setVisible(False)
		self.notifier.animation = animation.CompositeAnimation(10, 500)
		self.notifier.animation.addTransition(self.notifier.__setattr__, animation.LinearScalarInterpolator(1.0, 0.0), 'alpha')
		self.notifier.animation.addTaskOnFinish(self.notifier.setVisible, False)
		self.notifier.animation.startupDelay = 2000
		
		self.label = Label('1 of 1', fixedSize = True)
		prefSize = self.label.getPrefferedSize()
		self.label.setSize(40, prefSize[1]+6)
		self.label.align = Label.CENTER

		# component for resizing screenlet
		self.resize = ImageButton('resize', 'resize')
		self.resize.registerEvent('button_pressed', self.onResizeStart)
		self.resize.registerEvent('mouse_drag_motion', self.onResize)
		self.resize.registerEvent('button_released', self.do_resize)
		
		self.lyricsPanel.setPosition(0, 0)
		self.lyricsPanel.registerEvent('button_pressed', self.lyricsPanel_pressed)
		
		self.searching = ImageButton('searching_bg', 'searching_bg')
		self.searching_arrow = ImageButton('searching_glow', 'searching_glow')
		self.searching.addWidget(self.searching_arrow)
		self.searching.animation = animation.CompositeAnimation(20, 800, loop = True)
		self.searching.animation.addTransition(self.searching_arrow.__setattr__, animation.LinearScalarInterpolator(0.0, 6.29), 'rotation')
		self.searching.setVisible(False)
		
		#"""
		from gui.cairo_widgets import CairoCanvas
		#from gui.ls_widget import VirtualCanvas
		self.canvas = CairoCanvas(self.window)
		#self.canvas = VirtualCanvas(self.window)
		
		self.canvas.addWidget(self.lyricsPanel)
		self.canvas.addWidget(self.notifier)
		self.canvas.addWidget(self.searching)
		self.canvas.addWidget(self.resize)
		self.canvas.addWidget(self.disconn)
		self.canvas.addWidget(self.invisibleButton)
		
		self.playersDropDown = DropDownList([_('Not Connected')])
		self.playersDropDown.registerItemSelected(self.activePlayerChanged)
		self.playersDropDown.setSize(100, 20)
		
		self.controlPanel = Widget()
		
		self.controlPanel.addWidget(self.next)
		self.controlPanel.addWidget(self.label)
		self.controlPanel.addWidget(self.prev)
		self.controlPanel.addWidget(self.search)
		self.controlPanel.addWidget(self.save)
		self.controlPanel.addWidget(self.upload)
		
		tf = TextField(100, 30, "heloo")
		#self.canvas.addWidget(tf)
		self.canvas.addWidget(self.controlPanel)
		self.canvas.addWidget(self.playersDropDown)
		
		# set theme
		self.theme_name = 'default'
		self.updateWidgetPositions(self.width, self.height)	

	def translate_callback(self, arg):
		print arg
		print arg.get_active()
	# attribute-"setter", handles setting of attributes
	def __setattr__(self, name, value):
		#if name == 'text_scale' or name == 'font' or name == 'color_highlight' or name == 'color_normal':
		#	print name + ': '+str(value)
		if name == 'colorAdaptation':
			if value == 'None':
				if self.autoColorTimer != None:
					gobject.source_remove(self.autoColorTimer)
					self.autoColorTimer = None
				self.colorAnimation(self.color_normal, self.color_highlight)
			elif self.autoColorTimer == None:
					self.autoColorTimer = gobject.timeout_add(1000, self.doColorAdaptation)
					
		# forward options to LyricsPanel
		if name in ['color_normal', 'color_highlight', 'text_scale', 'theme', 'textAlign']:
			if name == 'textAlign':
				
				self.lyricsPanel.__setattr__(name, text_aligns[value])
			else:
				self.lyricsPanel.__setattr__(name, value)
		if name == 'font' and isinstance(value, str):
			self.lyricsPanel.setFont(pango.FontDescription(value))
			
		if name == 'lyrics_directory':
			if isinstance(value, bool):
				return

		if name == 'save_lyrics':
			self.save.setEnabled(value)
		# call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!)
				# forward value to canvas
		if name == 'scale' and self.canvas != None:
			self.canvas.scale = value
		
		screenlets.Screenlet.__setattr__(self, name, value)
		
		if name == 'theme_name':
			#print "THEME CHANGED %s" % value
			self.onThemeChanged(self.theme)
		
		if (name == 'width' or name == 'height') and self.canvas != None:
			self.updateWidgetPositions(self.width, self.height)
		
		if name in [ "playing"]:
			print "UPDATE STATE %s = %s" % (name, value)
			#self.updateState()
	
		if name == 'minimizeToTray':
			if value == True:
				if self.trayIcon == None:
					self.trayIcon = gtk.StatusIcon()
					trayIconImage = os.path.dirname(os.path.abspath(__file__)) + os.sep + "tray.png"
					self.trayIcon.set_from_file(trayIconImage)
					self.trayIcon.set_tooltip("yep, even screenlets can have tray icon :D") 
					self.trayIcon.connect('activate', self.tray_activate)
				else:
					self.trayIcon.set_visible(True)
			if value == False and self.trayIcon:
				self.trayIcon.set_visible(False)
		
		if name == 'language':
			if self.lyricsList != None:
				self.setLyricsIndex(self.lyrics_index)
		if name == 'translation_enabled':
			print "\tGOOGLE TRANSLATE: %s" % (self.translation_enabled)
			self.translateMenuItem.set_active(value)
			if self.lyricsList != None:
				self.setLyricsIndex(self.lyrics_index)

	def on_init (self):
		log.info(_("Screenlet has been initialized."))
		# add default menuitems
		#self.add_menuitem("translation", "Google Translate")
		
		self.menu.append(self.translateMenuItem)
		self.add_default_menuitems()
		
		self.state = self.load_option('state')
		if self.state == None:
			self.state = 'minimized' # default state
			self.session.backend.save_option(self.id, 'state', self.state)
		log.debug(_("MINIMIZING Startup state: %s") % self.state)
		
		width  = self.load_option('maxi_width' )
		height = self.load_option('maxi_height')
		if (width != None and height != None):
			self.maxi_width  = int(width )
			self.maxi_height = int(height)
		log.debug("MINIMIZING Initialized maximized dimensions: width=%d height=%d" % (self.maxi_width, self.maxi_height))
			
		self.minimize("disconnected")
		
		
	def tray_activate(self, widget):
		if self.state == 'minimized':
			self.maximize()
		else:
			self.minimize()
			
	def on_menuitem_select(self, item):
		print item

	def on_minimized_resized(self, width, height):
		print "on_minimized_resized: w=%d h=%d" % (width, height)
		if self.state == 'minimized' and not self.safe_minimize:
			self.width  = width
			self.height = height
			#self.canvas.setSize(width, height)
			#self.update_shape()

	def on_minimized_pressed(self, widget, event):
		if event.type == gtk.gdk._2BUTTON_PRESS:
			self.maximize()
		
	def pack(self, widget):
		screen = self.window.get_screen()
		log.debug(_("MINIMIZING Compute minimized layout"))
		log.debug("MINIMIZING Screen: width=%d height=%d" % (screen.get_width(), screen.get_height()))
		log.debug("MINIMIZING Maximized dimmensions: width=%d height=%d" % (self.maxi_width, self.maxi_height))
		#print "x=%s  y=%s width=%s" % (self.x, self.y, self.maxi_width)
		left = self.x
		right = screen.get_width() - (left + self.maxi_width)
		up = self.y
		bottom = screen.get_height() - (up + self.maxi_height)
		#print "PACK LEFT=%s  RIGHT=%s" % (left, right)
		
		ml = (left/float(left+right))*(self.maxi_width-widget.bounds.width)
		#mr = (1.0-(left/float(left+right)))*(self.maxi_width-widget.bounds.width)
		#print "%s vs %s" % (ml, mr)
		mu = (up/float(up+bottom))*(self.maxi_height-widget.bounds.height)
		
		#print "offset  x=%s  y=%s" % (ml, mu)
		return [ml, mu]
		
	def expand(self, widget, width, height):
		screen = self.window.get_screen()
		
		screenWidth  = screen.get_width()
		screenHeight = screen.get_height()
		#print "prev x=%s widget.bounds.x=%s" % (self.x, widget.bounds.x)
		prevX = self.x + widget.bounds.x
		prevY = self.y + widget.bounds.y

		left = prevX
		right = screenWidth - (prevX+widget.bounds.width)
		up = prevY
		bottom = screenHeight - (prevY+widget.bounds.height)
		#print "LEFT=%s  RIGHT=%s" % (left, right)
		#print "right/left %s" % (right/float(left+right))
		#print "MOVE LEFT %s" % ((1.0-right/float(left+right))*(width-widget.bounds.width))
		#print "MOVE RIGHT %s" % (right/float(left+right)*(width-widget.bounds.width))
		
		#left*ratio + right*ratio = width
		ratioH = width/float(left+right)
		ratioV = height/float(up+bottom)

		#left*r + right*r = widget.bounds.width
		rh = widget.bounds.width/float(left+right)
		rv = widget.bounds.height/float(up+bottom)

		newX = int(prevX+rh*left-ratioH*left)
		newY = int(prevY+rv*up-ratioV*up)
		
		new = [int(prevX-(1.0-right/float(left+right))*(width-widget.bounds.width))]
		#print "%s vs %s" % (new, newX)
		
		return [newX, newY]
		
	def load_option(self, name):
		if self.session != None:
			try:
				return self.session.backend.load_option(self.id, name)
			except Exception, e:
				pass
	def __init__(self, **keyword_args):

		#call super (and not show window yet)
		screenlets.Screenlet.__init__(self, uses_theme=True, width=64, height=64, drag_drop=True, **keyword_args)
		self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
		self.translateMenuItem = gtk.CheckMenuItem("Google Translate")
		self.translateMenuItem.connect("activate", lambda item: self.__setattr__('translation_enabled', item.get_active()))
		self.translateMenuItem.show()

		#print dir(self.window.get_screen())
		#print self.window.get_screen().is_composited()
		#print self.window.get_screen().get_rgba_colormap()
		
		self.lyricsPanel = LyricsPanel()
		#self.lyricsPanel = LyricsAnimation()

		# path to screenlet installation directory
		self.install_path = path.dirname(path.abspath(__file__)) + os.sep	
		sys.path.append(self.install_path)
		
		# Options
		self.add_options_group(_('Lyrics'), _('Lyrics settings'))
		self.add_option(FontOption (_('Lyrics'), 'font', self.font, _('Font'), _('The font of lyrics')))
		self.add_option(ColorOption(_('Lyrics'), 'color_normal', self.color_normal, _('Normal Color'), _('Color of the common text')))
		self.add_option(ColorOption(_('Lyrics'), 'color_highlight', self.color_highlight, _('Highlight Color'), _('Color of the actual line')))
		self.add_option(StringOption(_('Lyrics'), 'colorAdaptation', self.colorAdaptation, _('Color Adaptation'), _('Lyrics text color adaptation by background'), choices = [_('None'), _('Inverse'), _('Black or White')]))
		self.add_option(FloatOption(_('Lyrics'), 'text_scale', self.text_scale, _('Text Scale'), _('Maximum scale of the highlighted text'), min=1, max=2, increment=0.05, digits=2))
		self.add_option(StringOption(_('Lyrics'), 'textAlign', self.textAlign, _('Text Align'), _('Lyrics text align'), choices = sorted(text_aligns)))
		
		self.add_option(BoolOption(_('Lyrics'), 'save_lyrics', self.save_lyrics, _('Save lyrics'), _('Allow saving downloaded lyrics to the selected directory')))
		self.dirOption = DirectoryOption(_('Lyrics'), 'lyrics_directory', self.lyrics_directory, _('Lyrics Directory'), _('Directory, where will be downloaded lyrics saved'))
		self.add_option(self.dirOption)
		self.add_option(BoolOption(_('Lyrics'), 'filter_cjk', self.filter_cjk, _('Filter some languages'), 
			_('Filter Chinese, Japanese, Korean languages (maybe more), which may cause troubles with scaling text during animation ')))
		
		self.add_option(BoolOption(_('Lyrics'), 'autoPanelHide', self.autoPanelHide, _('Hiding Control panel'), _('Hide Control panel when window loose focus')))
		self.add_option(BoolOption(_('Lyrics'), 'minimizeToTray', self.minimizeToTray, _('Use Tray Icon'), _('Use Tray Icon')))
		self.add_option(BoolOption(_('Lyrics'), 'safe_minimize', self.safe_minimize, _('Safe minimizing'), _('Use safe minimizing without real window resizing')))
		
		
		self.add_options_group(_('Google Translate'), _('Google Translate settings'))
		self.add_option(BoolOption(_('Google Translate'), 'translation_enabled', self.translation_enabled, _('Enabled'), _('Google Translate')))
		self.add_option(StringOption(_('Google Translate'), 'language', self.language, _('Language'), _('Language'), choices = sorted(languages)))
		
		
		self.lyricsEngine = LyricsEngine(self.addLyrics, self.onEngineFinish)
		self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet'])
		#self.lyricsEngine.setLyricsSources(['lyricsscreenlet'])
		
		self.player = player.Player()
		self.xmmsPlayer = None
		for p in self.player.player_list:
			if p.__name__ == "xmms":
				self.xmmsPlayer = p
		self.player.registerOnSongChange(self.onSongChanged)
		self.player.registerOnPlay(self.onPlay)
		self.player.registerOnStop(self.onStop)
		self.player.registerOnElapsedChanged(self.onElapsed)
		self.player.registerOnPlayerConnected(self.onPlayerConnected)
		self.player.registerOnPlayerDisconnected(self.onPlayerDisconnected)
		self.player.registerOnActivePlayerListChange(self.onPlayerListChange)
		
		
		self.disconn = ImageButton('disconnected', 'disconnected')
		self.disconn.registerEvent('button_pressed', self.on_minimized_pressed)
		self.disconn.registerEvent('button_pressed', self.lyricsPanel_pressed) # moving screenlet
		self.disconn.registerEvent('resized', self.on_minimized_resized)
		self.disconn.setPosition(0, 0)
		self.disconn.setVisible(False)
		self.disconn.rectangleBounds = True # better for transparent images/themes
		
		templateAnim = Animation(100, 6)
		templateAnim.addLinearTransition('setOverAlpha', 0.0, 1.0, LINEAR)
		templateAnim.addTransition('scale', LinearVectorInterpolator([1.0, 1.0], [1.4, 1.4]), LINEAR)
				
		pressedAnim = Animation(4, 20)
		pressedAnim.addTransition('scale', LinearVectorInterpolator([1.4, 1.4], [1.25, 1.25]), LINEAR)
		
		self.next = ImageButton('next', 'next_over')
		self.next.registerEvent('button_pressed', self.nextLyrics)
		self.next.setEnterAnimation(templateAnim.create(self.next))
		self.next.setPressedAnimation(pressedAnim.create(self.next))
		
		self.prev = ImageButton('prev', 'prev_over')
		self.prev.registerEvent('button_pressed', self.previousLyrics)
		self.prev.setEnterAnimation(templateAnim.create(self.prev))
		self.prev.setPressedAnimation(pressedAnim.create(self.prev))
		
		self.save = ImageButton('harddisk', 'harddisk')
		self.save.registerEvent('button_pressed', self.saveButtonPressed)
		self.save.setEnterAnimation(templateAnim.create(self.save))
		self.save.setEnabled(self.save_lyrics)
		
		self.search = ImageButton('search', 'search')
		self.search.registerEvent('button_pressed', self.onSearchClicked)
		self.search.setEnterAnimation(templateAnim.create(self.search))
		
		self.upload = ImageButton('upload', 'upload')
		self.upload.registerEvent('button_pressed', self.uploadButtonPressed)
		self.upload.setEnterAnimation(templateAnim.create(self.upload))
		
		self.invisibleButton = ImageButton('bubak', 'bubak')
		self.invisibleButton.visibilityThreshold = 50 # more transparent icon is planned for this
		self.invisibleButton.registerEvent('button_pressed', self.invisible_pressed)
		
		self.notifier = Label(_('Uploaded '), fixedSize = False)
		self.notifier.bgColor = [0.7, 0.4, 0.4, 0.8]
		self.notifier.setVisible(False)
		self.notifier.animation = animation.CompositeAnimation(10, 500)
		self.notifier.animation.addTransition(self.notifier.__setattr__, animation.LinearScalarInterpolator(1.0, 0.0), 'alpha')
		self.notifier.animation.addTaskOnFinish(self.notifier.setVisible, False)
		self.notifier.animation.startupDelay = 2000
		
		self.label = Label('1 of 1', fixedSize = True)
		prefSize = self.label.getPrefferedSize()
		self.label.setSize(40, prefSize[1]+6)
		self.label.align = Label.CENTER

		# component for resizing screenlet
		self.resize = ImageButton('resize', 'resize')
		self.resize.registerEvent('button_pressed', self.onResizeStart)
		self.resize.registerEvent('mouse_drag_motion', self.onResize)
		self.resize.registerEvent('button_released', self.do_resize)
		
		self.lyricsPanel.setPosition(0, 0)
		self.lyricsPanel.registerEvent('button_pressed', self.lyricsPanel_pressed)
		
		self.searching = ImageButton('searching_bg', 'searching_bg')
		self.searching_arrow = ImageButton('searching_glow', 'searching_glow')
		self.searching.addWidget(self.searching_arrow)
		self.searching.animation = animation.CompositeAnimation(20, 800, loop = True)
		self.searching.animation.addTransition(self.searching_arrow.__setattr__, animation.LinearScalarInterpolator(0.0, 6.29), 'rotation')
		self.searching.setVisible(False)
		
		#"""
		from gui.cairo_widgets import CairoCanvas
		#from gui.ls_widget import VirtualCanvas
		self.canvas = CairoCanvas(self.window)
		#self.canvas = VirtualCanvas(self.window)
		
		self.canvas.addWidget(self.lyricsPanel)
		self.canvas.addWidget(self.notifier)
		self.canvas.addWidget(self.searching)
		self.canvas.addWidget(self.resize)
		self.canvas.addWidget(self.disconn)
		self.canvas.addWidget(self.invisibleButton)
		
		self.playersDropDown = DropDownList([_('Not Connected')])
		self.playersDropDown.registerItemSelected(self.activePlayerChanged)
		self.playersDropDown.setSize(100, 20)
		
		self.controlPanel = Widget()
		
		self.controlPanel.addWidget(self.next)
		self.controlPanel.addWidget(self.label)
		self.controlPanel.addWidget(self.prev)
		self.controlPanel.addWidget(self.search)
		self.controlPanel.addWidget(self.save)
		self.controlPanel.addWidget(self.upload)
		
		tf = TextField(100, 30, "heloo")
		#self.canvas.addWidget(tf)
		self.canvas.addWidget(self.controlPanel)
		self.canvas.addWidget(self.playersDropDown)
		
		# set theme
		self.theme_name = 'default'
		self.updateWidgetPositions(self.width, self.height)	
class Lyrics(object):

	color = gtk.gdk.Color()
	font = "Sans 10"
	applet = None
	label = None
	lyrics_directory = "/home/dencer/Lyrics"

	def __init__(self):
		self.lyrics = None
		self.lyricsTimer = None
		self.player = Player()
		self.player.registerOnPlayerConnected(self.onPlayerConnected)
		self.player.registerOnSongChange(self.onSongChanged)
		self.player.registerOnPlay(self.onPlay)
		self.player.registerOnStop(self.onStop)
		self.player.registerOnElapsedChanged(self.onSeek)
		self.lyricsEngine = LyricsEngine(self.onLyricsFound, self.onEngineFinish)
		self.lyricsEngine.setLyricsSources(['alsong', 'minilyrics', 'lrcdb', 'lyricsscreenlet'])
		
		self.label = gtk.Label("Lyrics Applet")
		self.gconf_client = gconf.client_get_default()
		self.gconf_client.add_dir("/apps/lyrics_applet", gconf.CLIENT_PRELOAD_NONE)
		self.gconf_client.notify_add('/apps/lyrics_applet/color', self.color_changed)
		self.gconf_client.notify_add('/apps/lyrics_applet/font', self.font_changed)
		
		self.color_changed(None)
		self.font_changed(None)


	def color_changed(self, client, *args):
		color = self.gconf_client.get_string("/apps/lyrics_applet/color")
		if color:
			self.color = gtk.gdk.Color(color)
			self.label.modify_fg(gtk.STATE_NORMAL, self.color)

	def font_changed(self, client, *args):
		font = self.gconf_client.get_string("/apps/lyrics_applet/font")
		if font:
			self.font = font
			font_desc = pango.FontDescription(font)
			self.label.modify_font(font_desc)

	def onPlayerConnected(self):
		print "onPlayerConnected"

	def onStop(self):
		if self.lyricsTimer:
			self.lyricsTimer.pause()

	def onPlay(self):
		if self.lyricsTimer:
			self.lyricsTimer.resume()

	def onSeek(self, elapsed):
		print "## seek to:", elapsed
		if self.lyrics:
			self.lyricsTimer.pause()
			self.lyricsTimer = LyricsTimer(self.lyrics, self.update)
			self.lyricsTimer.start(elapsed)
			self.label.set_text(self.lyrics[self.lyricsTimer.actualLine].text[0].strip())

	def onSongChanged(self, songFile):
		try:
			self.lyrics = None
			if self.lyricsTimer:
				self.lyricsTimer.pause()
				self.lyricsTimer = None
		
			print "onSongChanged"
			metadata = getSongMetadata(self.player)
			metadata['file'] = songFile
		
			self.label.set_text("")
			print metadata
		
			lyrics = self.getLyricsFromDisk(metadata)
			if lyrics is None:
				self.lyricsEngine.search(metadata)
				print "searching started"
			else:
				self.onLyricsFound(lyrics)
		except:
			traceback.print_exc()


	def onLyricsFound(self, lyrics):
		if not self.lyrics and lyrics:
			print "onLyricsFound"
			try:
				parsed = lyricsparser.parseLyrics(lyrics)
				if isinstance(parsed[0], LyricEntity):
					self.lyrics = parsed
					self.lyricsTimer = LyricsTimer(self.lyrics ,self.update)
					elapsed = self.player.getElapsed()
					#print "elapsed:", elapsed
					self.lyricsTimer.start(elapsed)
					self.label.set_text(self.lyrics[self.lyricsTimer.actualLine].text[0].strip())
					self.lyricsEngine.stop()
			except:
				traceback.print_exc()

	def update(self, lyricsLine):
		lyricLine = self.lyrics[lyricsLine].text[0].strip()
		if lyricLine:
			self.label.set_text(self.lyrics[lyricsLine].text[0].strip())

	def onEngineFinish(self):
		print "onEngineFinish"

	def getLyricsFromDisk(self, songInfo):
		logger.debug("searching lyrics on disk")
		# check for .lrc file in song file directory
		lrc_file = None
		if songInfo.has_key('file'):
			lrc_file = songInfo['file'].rstrip("mp3")+"lrc" #TODO: not only mp3 expecting
		if lrc_file == None or not os.path.exists(lrc_file):
			lrc_path = lyricsFile(songInfo)
			lrc_file = os.path.join(self.lyrics_directory, lrc_path['folder'], lrc_path['file'])
			logger.debug("lyrics should be here: %s" % lrc_file)
			
		print lrc_file
		if lrc_file != None and os.path.exists(lrc_file):
			f = open(lrc_file, 'r')
			print "lyrics from file: %s" % lrc_file
			lrc = f.read()
			f.close()
			return lrc
		print "Nothing on disk"
		return None

	def show_about(self, *args):
		print args
		pass

	def show_preferences(self, *args):
		dialog = OptionsDialog(self)
		response = dialog.run()
		if response == gtk.RESPONSE_OK:
			dialog.save_preferences()
		dialog.destroy()