#!/usr/bin/python -OO
# Spotify Plugin
# From spotify-notify by SveinT (sveint@gmail.com)
# Original code by noalwin (lambda512@gmail.com)
# Based on pypanel code
# Developed by BadChoice (jordi.hernandezp@gmail.com)

import os, time, sys, datetime, string
import urllib2
import re
import gobject
import WEBServices
from xml.dom import minidom 
from GenericPlayer import GenericPlayer
from common import Track


try:
    from Xlib import X, display, error, Xatom
    import Xlib.protocol.event
except:
    print "You need the xlib-library. If you are using Ubuntu, try running\n\"sudo apt-get install python-xlib\""
    sys.exit(1)

CURRENT_DIR = os.path.abspath(os.curdir).replace(';','')+"/"


class SpotifyPlayer(GenericPlayer):

    __name__ = 'Spotify'
    __version__ = '0.0'
    __author__ = 'BadChoice <guitarboy000@gmail.com>'
    __desc__ = 'API to the Spotify Music Player'
    
    timeout_id = None

    def __init__(self, d=None):
        self._dsp = display.Display()
        self._screen  = self._dsp.screen()
        self._root    = self._screen.root
    #   self.error   = error.CatchError()
        self._root.change_attributes(event_mask=(X.PropertyChangeMask))
        self._dsp.flush()
        
    
        self._spotify_task = None
        self._spotify_obj = None
        self._spotify_title = None # Spotify's window title
        
        
        self._init_spotify_data()
        self.song = ""
        self.album = ""
    
    def _init_spotify_data(self):
        """Search the spotify window and initialize the data"""
        tasks = self._root.get_full_property(
                        self._dsp.intern_atom("_NET_CLIENT_LIST"),
                        Xatom.WINDOW
                ).value
        
        is_running = False
        
        for task in tasks:
            obj  = self._dsp.create_resource_object("window", task)
            name = ( obj.get_full_property(self._dsp.intern_atom("_NET_WM_NAME"), 0) or
                     obj.get_full_property(Xatom.WM_NAME, 0) )
            title = getattr(name,'value','')
            if title is not '' and title.startswith('Spotify'):
                obj.change_attributes(event_mask=(
                    X.PropertyChangeMask|X.StructureNotifyMask))
                is_running = True
                self._spotify_task = task
                self._spotify_obj = obj
                self._spotify_title = title
                break
                
        if not is_running and self._spotify_task is not None:
            self._delete_spotify_data()
        
    
    def _update_spotify_title(self):
        name = ( self._spotify_obj.get_full_property(self._dsp.intern_atom("_NET_WM_NAME"), 0) or
                 self._spotify_obj.get_full_property(Xatom.WM_NAME, 0) )
        title = getattr(name,'value','')
        if title is not '' and title.startswith('Spotify'):
            self._spotify_title = title
    
    def _delete_spotify_data(self):
        self._spotify_task = None
        self._spotify_obj = None
        self._spotify_title = None
    
    
    def _update(self):
        while self._dsp.pending_events():
            e = self._dsp.next_event()
            #print e
            
            if e.type == X.DestroyNotify:
                if e.window.id == self._spotify_task:
                    self._delete_spotify_data()
                    #print "Spotify has been closed"
            elif e.type == X.PropertyNotify:
                if e.atom == self._dsp.intern_atom("_NET_CLIENT_LIST"):
                    #print '_NET_CLIENT_LIST'
                    if self._spotify_task is not None:
                        #if hasattr(e, "window") and self._spotify_task == e.window.id:
                            #print 'Spotify seems to have changed'
                        pass
                    else:
                        # print 'Spotify has been started'
                        self._init_spotify_data()
                elif self._spotify_task is not None and e.window.id == self._spotify_task:
                    if e.atom in [Xatom.WM_NAME, self._dsp.intern_atom("_NET_WM_NAME")]:
                        try:
                            self._update_spotify_title()
                            #print 'Spotify has changed the name %s' % self._spotify_title
                        except Xlib.error.BadWindow:
                            #print "BADWINDOW!"
                            pass
    
    def get_song(self):
        self._update()
        # self._spotify_title -> "Spotify \xe2\x80\x93 Title - Artist"
        
        if self._spotify_title is None or self._spotify_title == 'Spotify':
            # Closed or stopped
            return "No Song"
        
        data = self._spotify_title[10:].split(' \xe2\x80\x93 ')
        #print self._spotify_title
        #data = self._spotify_title[10:].split('\x93 ')
        
        if len(data) == 2:
        #print "A: " + data[0]
        #print "T: " + data[1]
            return {'artist': data[0], 'title': data[1]}
        else:
            #Unexpected format
            return {'title': self._spotify_title[10:]}

    def get_album(self):                    #Get Album
        try:
            if self.song != self.get_song()["title"]:
                self.song = self.get_song()["title"]
                self.album = WEBServices.wikiLyrics_get_album(self.get_song()["artist"] ,self.get_song()["title"])    
                return self.album
            else:
                return self.album
        except:
            return ""

    def get_title(self):
        try:
            return self.get_song()["title"]
        except:
            return ""

    def get_artist(self):
        try:
            return self.get_song()["artist"]
            #return "TEST"
        except:
            return ""

    def is_active(self):        #Is the player open?
        self._update()
        if self._spotify_title:
            return True
        else:
            return False
            
    def connect(self):
        if not self.timeout_id:
            self.timeout_id = gobject.timeout_add(2000, self.check_new_song)
        return True
    
    def disconnect(self):
        if self.timeout_id:
            gobject.source_remove(self.timeout_id)
    
    def check_new_song(self):
        self.state_handler(track=True)
        return True
        
    def get_track(self):
        track = Track(
            title  = self.get_title(),
            album  = self.get_album(),
            artist = self.get_artist())
        return track

    def is_playing(self):
        return False

    def get_state(self):
        return 'playing'
