# Copyright (C) 2009-2010 Gloobus Developers
#
#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 2
#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, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import ConfigParser
import urllib
import re
import gtk
import cairo
from gtk import gdk
import os
import sys
import htmlentitydefs
import gettext
import config


"""
Class for getting the lyrics of a song, it will have another classes that will implement diferent search engines
"""
class Lyrics:
	"""
	This class crates a window and download the lyrics of the song from http://lyricwiki.org/
	It uses Cairo to draw a nice backgroun and the lyrics
	"""	
	song 		= ""
	win 		= None
	abspath 	= ""
	lyricengine = None
	
	# ========================= CONSTRUCTOR ============================= #
	def __init__(self, config, colors):
		self.config = config
		self.g = colors	

	# ========================== SHOW LYRICS============================== #
	def show_lyrics(self, artist, song):
		self.get_lyrics(artist,song)
		self.create_window()
		
	# ========================== GET SONG ============================== #
	def get_lyrics(self, artist, song):
	    if artist != "" and song != "":
	        lyricname = self.config.get("Lyrics","name")
	        
	        exec "from " + lyricname + " import *"		
	        exec "self.lyricengine = " + lyricname + "()"
	        
	        self.song = self.lyricengine.get_lyrics(artist,song)
	        if not self.song:
	            self.song = '\n' + _('No lyrics found') + '\n\n'
	        
	    else:
	        self.song = "\n " + _('No song playing') + "... \n\n";

	# ========================== CREATE WINDOW ============================== #
	def create_window(self):
		self.win = gtk.Window()   
		self.win.set_title(_('Lyrics'))
		self.win.stick()		
		self.win.set_default_size(self.get_width(), self.get_height())				#All desktops
    	#win.set_keep_below(True)													#Keep the window below the others
		self.win.set_decorated(False)												#No Decoration
		self.win.set_property("skip-taskbar-hint", True)							#No Deskbar Entry

   		#win.connect('delete-event', gtk.main_quit)
		self.win.set_app_paintable(True)
		self.win.connect('expose-event',	self.expose)

		self.win.add_events(gdk.BUTTON_PRESS_MASK)
		self.win.connect('button-press-event', self.clicked)
    
		self.win.set_colormap( self.win.get_screen().get_rgba_colormap())						#Set Alpha Screen
		self.win.show_all()
		
		self.draw_buttons()

		self.g.debug("Lyric window created")
	
	# ========================== EXPOSE EVENT ============================== #
	def expose(self, widget, event):
		(width, height) = widget.get_size()			 	#Get window size
		cr = widget.window.cairo_create()				#Get a cairo context
				
		cr.set_source_rgba(1.0, 1.0, 1.0, 0.0)			#Make the window transparent
		cr.set_operator(cairo.OPERATOR_SOURCE)			#Make the window transparent
		cr.paint()										#Make the window transparent
		cr.set_operator(cairo.OPERATOR_OVER);

		self.draw_background(cr,width,height)	 	#Draw the nice background
		self.draw_lyrics(cr)
	  
		return False

	# ========================== DRAW BACKGROUND ============================== #
	def draw_background(self, cr, w, h):
		x = 0
		y = 0
		r = 15
	
		cr.set_operator(cairo.OPERATOR_OVER);
		cr.set_source_rgba (0, 0, 0, 0.8);			# Background opacity
		
		cr.move_to	( x+r,y )                     	# Move to A
		cr.line_to	( x+w-r,y )                    	# Straight line to B
		cr.curve_to	( x+w-r,y,x+w,y,x+w,y+r )		# Curve to C
		cr.line_to	( x+w,y+h-r )                	# Move to D
		cr.curve_to	( x+w,y+h-r,x+w,y+h,x+w-r,y+h )	# Curve to E
		cr.line_to	( x+r,y+h )                  	# Line to F
		cr.curve_to	( x+r,y+h,x,y+h,x,y+h-r )   	# Curve to G
		cr.line_to	( x,y+r )                      	# Line to H
		cr.curve_to	( x,y+r,x,y,x+r,y)      		# Curve to G
		cr.fill		( )    

	# ========================== DRAW LYRICS ============================== #
	def draw_lyrics(self,cr):
		cr.save()

		cr.move_to(20,20)
		cr.select_font_face("Lucida Grande", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
		cr.set_font_size(12)
		y = 20
		for line in self.song.splitlines():
			cr.move_to(19,y)						#Shadow
			cr.set_source_rgba(0.0, 0.0, 0.0,0.9)	#Shadow
			try:
				cr.show_text(unicode(line, "utf-8"))	#Shadow
			except:
				cr.show_text(line)	#Shadow
			cr.move_to(20,y)						#Normal
			cr.set_source_rgb(1.0, 1.0, 1.0)		#Normal
			try:
				cr.show_text(unicode(line, "utf-8"))	#Normal
			except:
				cr.show_text(line)	#Normal

			y = y + 15		
		cr.restore()
		
	# ========================== GET HEIGHT ============================== #
	def get_height(self):
		if self.song == "":
			self.g.debug("No song so we return 50")
			return 50
		else:
			if(int(self.song.count("\n")*17) > 100):
				return int(self.song.count("\n")*17) 
			else:
				return 100

	# ========================== GET WIDTH ============================== #
	def	get_width(self):
		self.g.debug("Getting width")
		if self.song == "":
			self.g.debug("No Song so we return 10")
			return 10
		else:
			size = 40
			for line in self.song.splitlines():
				if len(line) > size:
					size = len(line)
					#print line
					#print len(line)
			return size * 8  			#Need to find this value
	
	# ========================= CLICKED ===================================== #
	## 
	## @param widget Main Application window
	## @param event Clicked Event
	## @return None
	##
	## This function starts a draw when the window is clicked
	def clicked(self,widget,event):
		if event.button == 2:
			self.win.destroy()
		else:
			self.win.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
			
	#====================== BUTTONS ======================================== #
	def draw_buttons(self):
		button = gtk.Button(_("Go to webpage"))
		button.connect('button-press-event', self.button_webpage)
		
		quitimage = gtk.Image()
		quitimage.set_from_file(os.path.abspath(os.path.dirname(sys.argv[0])) + "/images/close_button.png")
		
		quit = gtk.EventBox()										# Create EventBox
		quit.set_visible_window(False)								# Make EventBox transparent
		quit.add(quitimage)											# Add our image to EventBox
		quit.connect("button-press-event", self.close_lyrics_win)	# Bind EventBox to quit function on click
		
		fixed = gtk.Fixed()
		
		fixed.put(quit,self.get_width()-20,5)
		fixed.put(button,self.get_width()/2-50, self.get_height()-35)		
		
		fixed.show_all()
		self.win.add(fixed)
		
	#==================BUTTON_WEBPAGE =====================================#
	def button_webpage(self,widget,event):
		webpage = self.lyricengine.get_webpage()
		self.g.debug("URL: "+webpage)
		os.system("gnome-open " + webpage);
		
		
	#================== CLOSE LYRICS WINDOW ===============================#
	def close_lyrics_win(self,widget,event):
		self.win.destroy()
		self.g.debug("Lyric window closed")

# ========================= HTML_UNESCAPE ================================ #
## 
## @param text The HTML (or XML) source text.
## @return The plain text, as a Unicode string, if necessary.
##
## Removes HTML or XML character references and entities from a text string.
## from Fredrik Lundh
## http://effbot.org/zone/re-sub.htm#unescape-html
def html_unescape(text):
    def fixup(m):
        text = m.group(0)
        if text[:2] == "&#":
            # character reference
            try:
                if text[:3] == "&#x":
                    return unichr(int(text[3:-1], 16))
                else:
                    return unichr(int(text[2:-1]))
            except ValueError:
                pass
        else:
            # named entity
            try:
                text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
            except KeyError:
                pass
        return text # leave as is
    return re.sub("&#?\w+;", fixup, text)


#TRANSLATIONS
gettext.bindtextdomain('covergloobus', config.prefix+'/share/locale/')		##TODO GET IT FROM CONFIG
gettext.textdomain('covergloobus')
_ = gettext.gettext
