# 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 cairo
import ConfigParser
import gettext
import glob
import os
import sys
import re
import config
from colors import *

def config_load():
    conf = config_default()
    if os.path.isfile(CONFIG_PATH):
        conf.read(CONFIG_PATH)
    else:
        c.warning(_("Using default Configuration"))
        
    c.debug("CONF: Start position: "    + conf.get('StartPosition','x') + "," 
        + conf.get ("StartPosition",'y'))
    c.debug("CONF: Theme Name:"         + conf.get("Theme","name"))
    c.debug("CONF: Player Name:"        + conf.get("Player","name"))
    c.debug("CONF: Lyrics Name:"        + conf.get("Lyrics","name"))
    c.debug("CONF: Tabs Name:"          + conf.get("Tabs","name"))
    c.debug("CONF: On top?:"            + conf.get("StartPosition","ontop"))
    c.debug("CONF: Amazon Covers:"      + conf.get("AmazonCovers","value"))
    c.debug("CONF: Docky:"              + conf.get("Docky","value"))
    c.debug("CONF: Stick to desktop:"   + conf.get("DesktopStick","value"))
    c.debug("CONF: Show status icon:"   + conf.get("StatusIcon","value"))
    
    return conf

def config_save(conf):
    if not os.path.isfile(CONFIG_PATH):
        d = os.path.dirname(CONFIG_PATH)
        c.debug(_('Configuration dir path') + ": " + d)
        if not os.path.exists(d):
            c.warning(_("Creating configuration directory"))
            os.makedirs(d)
    
    f = open(CONFIG_PATH, 'wb')
    conf.write(f)
    f.close()
    c.debug('Configuration saved')

def config_default(conf=None):
    if not conf:
        conf = ConfigParser.SafeConfigParser()
    conf.add_section('StartPosition')
    conf.add_section('Theme')
    conf.add_section('Player')
    conf.add_section('Lyrics')
    conf.add_section('Tabs')
    conf.add_section('AmazonCovers')
    conf.add_section('Docky')
    conf.add_section('DesktopStick')
    conf.add_section('StatusIcon')
    conf.add_section('Background')
    conf.add_section('MPD')
    
    conf.set('StartPosition','x'       ,'20')
    conf.set('StartPosition','y'       ,'20')
    conf.set('StartPosition','ontop'   ,'0')
    conf.set('Theme'        ,'name'    ,'BadChoice')
    conf.set('Theme'        ,'path'    ,ABS_PATH + '/themes/BadChoice')
    conf.set('Player'       ,'name'    ,'Rhythmbox')        
    conf.set('Lyrics'       ,'name'    ,'lyricswikia')
    conf.set('Lyrics'       ,'widget'  ,'0')
    conf.set('Lyrics'       ,'window'  ,'new')
    conf.set('Lyrics'       ,'refresh' ,'0')
    conf.set('Lyrics'       ,'try_all' ,'0')
    conf.set('Lyrics'       ,'cache' ,'0')
    #conf.set('Lyrics'       ,'cache_time' ,'0')
    conf.set('Tabs'         ,'name'    ,'ultimateguitar')
    #conf.set('Tabs'         ,'try_all' ,'0')
    conf.set('AmazonCovers' ,'value'   ,'1')
    conf.set('Docky'        ,'value'   ,'0')
    conf.set('DesktopStick' ,'value'   ,'1')
    conf.set('StatusIcon'   ,'value'   ,'1')
    conf.set('Background'   ,'show'    ,'0')
    conf.set('Background'   ,'opacity' ,'0.5')
    conf.set('MPD'          ,'host'    ,'localhost')
    conf.set('MPD'          ,'port'    ,'6600')
    conf.set('MPD'          ,'password','')
    conf.set('MPD'          ,'path'    ,HOME_PATH + '/Music')
    
    return conf
    
class Theme:
    def __init__(self, name, path):
        self.name = name
        self.path = path
        
    def __str__(self):
        return self.name
        
    def __cmp__(self, other):
        return cmp(self.name.lower(), other.name.lower())
        
def get_themes():
    themes = []
    for path in (ABS_PATH+'/themes/' , HOME_PATH+'/.CoverGloobus/themes/'):
        if os.path.exists(path)    :
            for infile in glob.glob( os.path.join(path, '*') ):
                if os.path.exists(infile + "/skin.xml"):
                    themes.append(Theme(infile[len(path):], infile))
    return sorted(themes)

def get_players():
    path = ABS_PATH +'/players/'
    players = []

    for infile in glob.glob( os.path.join(path, '*.py') ):
        players.append(infile[len(path):-3])
    return sorted(players)

def get_lyric_engines():
    path = ABS_PATH + '/lyrics/'
    lyrics = []
    for infile in glob.glob( os.path.join(path, '*.py') ):
        name = infile[len(path):-3]
        if name != "lyrics" and name != "lyricsfly":
            lyrics.append(name)
    return sorted(lyrics)

def get_tab_engines():
    path = ABS_PATH + '/tabs/'
    tabs = []
    for infile in glob.glob( os.path.join(path, '*.py') ):
        if infile[len(path):]!="tabs.py":
            tabs.append(infile[len(path):-3])
    return sorted(tabs)
    
class Track:
    def __init__(self, title='', album='',artist='',rating=0,cover='', 
        genre='', year=0, tracknumber=0):
        self.title = title
        self.album = album
        self.artist = artist
        if rating == '':
            self.rating = 0
        else:
            self.rating = int(rating)
        self.cover = cover
        self.genre = genre
        if year == '':
            self.year = 0
        else:
            self.year = int(year)
        self.tracknumber = tracknumber
        
    def __str__(self):
        return self.artist + ', ' + self.title + ', ' + self.album + ', ' + str(self.rating) + ', ' + self.cover + ', ' + self.genre

def draw_background(context, width, height, opacity=0.8, r=12):
    """
        This function draws a nice semiblack background using cairo.
        
        @param context: Cairo context
        @param width: width of the rectangle to draw
        @param height: height of the rectangle to draw
        @param opacity: background opacity
        @param r: background roundness
        @return: None
    """
    context.set_operator(cairo.OPERATOR_OVER);
    context.set_source_rgba (0, 0, 0, opacity)
        
    context.move_to (r, 0)
    context.line_to (width - r, 0)
    context.curve_to(width - r, 0, width, 0, width, r )
    context.line_to (width, height - r )
    context.curve_to(width, height - r, width , height, width - r, height)
    context.line_to (r, height)
    context.curve_to(r, height, 0, height, 0, height - r)
    context.line_to (0, r)
    context.curve_to(0, r, 0, 0, r, 0)
    context.fill    ()

def get_pid():
    """
        Checks if covergloobus.pid,
        if exists checks in /proc if it is really covergllobus,
        if it is covergloobus returns its pid, None otherwise
    """
    try:
        if os.path.exists('/tmp/covergloobus.pid'):
            f = open('/tmp/covergloobus.pid', 'r')
            pid = f.read()
            f.close()
            if os.path.exists('/proc/' + pid + '/cmdline'):
                f = open('/proc/' + pid + '/cmdline')
                cmd = f.read()
                f.close()
                if cmd.find('covergloobus.py') == -1:
                    os.remove('/tmp/covergloobus.pid')
                    pid = None
                else:
                    pid = int(pid)
            else:
                pid = None
        else:
            pid = None
    except:
        pid = None
    return pid

# ============================= HTML_UNESCAPE ================================ #

def html_unescape(text):
    """
        Removes HTML or XML character references and entities from a text string.
        from Fredrik Lundh
        http://effbot.org/zone/re-sub.htm#unescape-html
        
        @param text The HTML (or XML) source text.
        @return The plain text, as a Unicode string, if necessary.
    """
    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)
   
# ============================================================================ #

ABS_PATH = os.path.abspath(os.path.dirname(sys.argv[0]))
HOME_PATH = os.path.expanduser("~")
CONFIG_PATH = HOME_PATH + '/.config/CoverGloobus/CoverGloobus.cfg'
ICON_PATH = ABS_PATH + '/images/covergloobus.png'
GLOOBUS_URL = 'http://gloobus.net/'
CACHE_PATH = HOME_PATH + '/.cache/covergloobus/'
if not os.path.exists(CACHE_PATH):
    os.mkdir(CACHE_PATH)

THREAD_COUNTER = 0

gettext.bindtextdomain('covergloobus', config.prefix+'/share/locale/')
gettext.textdomain('covergloobus')
_ = gettext.gettext

c = colors()
for a in sys.argv:
    if a == '--debug':
        c.set_debug(True)
        c.debug('Installed themes:')
        for theme in get_themes():
            print theme, ',',
        print '\n',
        c.debug('Installed players:')
        print get_players()
        c.debug('Installed lyrics search engines:')
        print get_lyric_engines()
        c.debug('Installed tabs search engines:')
        print get_tab_engines()

c.debug("Prefix: " + config.prefix)
#c.debug(config.prefix+'/share/locale/')
#c.debug(config.sysconfdir)
c.debug("ABS_PATH: " + ABS_PATH)
