# a plugin for pympd that helps with managing favorite songs.
import gtk
import os.path
import ConfigParser


__name = 'Favorites'
__version = '0.01'
__author = "Natan 'whatah' Zohar"
__blurb = 'Favorites is a bookmark type plugin for your playlist. When a song that has been added to the favorites is in the playlist, it will be available via the favorites menu.'
FAV_FILE = os.path.expanduser("~/.pympd/favorites.db")
FAV='favorites'

class Favorites:

    # called when we load the plugin. we get passed the mainWindow, plugin menu
    # item as well as a connection to mpd.
    def _init(self, data, get):
        self.xml, self.pluginMenu, self.pympd, self.base_dir, self.parser = data
        self.menuBar = self.xml.get_widget("menubar1")
        self.readConfigParser(FAV_FILE)
        self.files = []
        self.playlist_version = -1
        self.initWidgets()
        self.updateFStore()
        self.updateAFStore()

    def readConfigParser(self, filename):
        self.configParser = ConfigParser.ConfigParser()
        self.configParser.read(filename)
        if not self.configParser.has_section(FAV):
            self.configParser.add_section(FAV)

    def saveConfigParser(self, filename):
        self.configParser.write(open(filename, 'w'))

    def _conf(self, hasConf=False):
        return False
    
    # update plugin, data is of type mpdclient.Status
    def _spin(self, data, songChanged=False):
        if data.playlist != self.playlist_version:
            self.playlist_version = data.playlist
            self.updateFStore()
            self.updateAFStore()
        return

    # called on plugin unloaded
    def _unload(self):
        self.saveConfigParser(FAV_FILE)
#        page_num = self.notebook.page_num(self.fView)
#        self.notebook.remove_page(page_num)
        self.favWindow.destroy()
        self.pluginMenuEntry.destroy()
        return

    def initWidgets(self):
        self.xml = gtk.glade.XML("%s/glade/favorites.glade" % self.base_dir)
        self.favWindow = self.xml.get_widget("playlist_fav")
        self.notebook = self.xml.get_widget("notebook1")
#        self.fView = gtk.TreeView()
#        self.afView = gtk.TreeView()
        self.fView = self.xml.get_widget("treeview1")
        self.afView = self.xml.get_widget("treeview2")
        self.tSel = self.fView.get_selection()
        self.aSel = self.afView.get_selection()
#        label = gtk.Label("Favorites")
#        self.notebook.append_page(self.fView, label)
#        self.fView.show_all()
        self.buildFavStore()
        self.buildAFavStore()
        self.buildPluginMenu(self.pluginMenu)
        self.connectWidgets()

    def connectWidgets(self): 
        dict =  { 
                  "on_add_fav_clicked" : self.add_clicked,
                  "on_rem_fav_clicked" : self.rem_clicked,
                  "on_delete_decoy"       : self.close_dialog,
                }

        self.xml.signal_autoconnect(dict)

        self.fView.connect('row-activated', self.fav_activated)

    def add_clicked(self, obj):
        status = self.pympd.status()
        if not status.state == 'play':
            return
        song = self.pympd.getCurrentSong()
        row = [song.file.lower(), "%s - %s" % (song.artist, song.title), song.id, gtk.STOCK_ABOUT ]
        if not self.configParser.has_option(FAV, song.file.lower()):
            self.configParser.set(FAV, song.file.lower(), '')
            self.fStore.append(row)
#            self.afStore.append(self.pympd.search('filename', song.file))
            menuEntry = gtk.MenuItem("%s - %s" % (song.artist, song.title))
            menuEntry.connect('activate', self.play_menu_entry, song.id)
            self.pluginSubMenu.append(menuEntry)
            menuEntry.show()
        self.saveConfigParser(FAV_FILE)

    def rem_clicked(self, obj):
        # If current page is playlist favorites
        current_page = self.notebook.get_current_page()
        if current_page == 0:
            model, iter = self.tSel.get_selected()
            if not iter == None:
                filename = model.get(iter, 0)
                title = model.get(iter, 1)
                for item in self.pluginSubMenu.get_children()[3:]:
                    label = item.get_children()[0]
                    if label.get_text() == title[0]:
                        self.pluginSubMenu.remove(item)
                        continue
                # TODO: Remove item from self.afStore
                model.remove(iter)
                self.configParser.remove_option(FAV, filename[0])
        # Otherwise, if the page is all favorites.
        elif current_page == 1:
            model, iter = self.aSel.get_selected()
            if not iter == None:
                filename = model.get(iter, 0)
                model.remove(iter)
                self.configParser.remove_option(FAV, filename[0].file)
        self.saveConfigParser(FAV_FILE)

    def fav_activated(self, treeview, path, column):
        model = treeview.get_model()
        iter = model.get_iter(path)
        songid = model.get(iter, 2)
        self.pympd.play(songid[0])

    def showFavorites(self, obj):
        self.favWindow.present()

    def buildPluginMenu(self, pluginMenu):
        self.pluginMenuEntry = gtk.MenuItem('Favorites')
        self.pluginSubMenu = gtk.Menu()
        self.pluginSubMenu.set_title('Favorites')
        menuEntry = gtk.ImageMenuItem(gtk.STOCK_ADD)
        menuEntry.get_children()[0].set_text("Add Favorite...")
        menuEntry.connect('activate', self.add_clicked)
        self.pluginSubMenu.append(menuEntry)
        
        menuEntry = gtk.ImageMenuItem(gtk.STOCK_EDIT)
        menuEntry.get_children()[0].set_text("Manage Favorites...")
        menuEntry.connect('activate', self.showFavorites)
        self.pluginSubMenu.append(menuEntry)

        menuEntry = gtk.SeparatorMenuItem()
        self.pluginSubMenu.append(menuEntry)

        self.pluginMenuEntry.set_submenu(self.pluginSubMenu)
        self.pluginMenuEntry.show_all()
        self.menuBar.insert(self.pluginMenuEntry, 4)


    def buildFavStore(self):
        self.fStore = gtk.ListStore(str, str, str, str);
        self.fCol = gtk.TreeViewColumn("Playlist Favorites")
        self.fCol.set_widget(None)
        self.fView.append_column(self.fCol)
        cellSong = gtk.CellRendererText()
        cellFav = gtk.CellRendererPixbuf()
        self.fCol.pack_start(cellFav, False)
        self.fCol.add_attribute(cellFav, 'stock-id', 3)
        self.fCol.pack_start(cellSong)
        self.fCol.set_attributes(cellSong, text=1)

    def buildAFavStore(self):
        self.afStore = gtk.ListStore(object)
        cellStr = gtk.CellRendererText()
        column = gtk.TreeViewColumn("All Favorites", cellStr)
        column.set_cell_data_func(cellStr, self.cell_data_func, (0, 'foo'))
        self.afView.append_column(column)
        
    
    def updateFStore(self):
        self.fView.set_model(None)
        self.fStore.clear()
        options = self.configParser.options(FAV)
        playlist = self.pympd.playlist()
        filenames = []
        for child in self.pluginSubMenu.get_children()[3:]:
            self.pluginSubMenu.remove(child)
#        self.pluginSubMenu.append(menuEntry)
        for song in playlist:
            filenames.append((song.file.lower(), song.artist, song.title, song.id))
        union = [f for f in filenames if f[0] in options]
        self.files = []
        for f in union:
            menuEntry = gtk.MenuItem("%s - %s" % (f[1], f[2]))
            menuEntry.connect('activate', self.play_menu_entry, f[3])
            self.pluginSubMenu.append(menuEntry)
            self.fStore.append([f[0], "%s - %s" % (f[1], f[2]), f[3], gtk.STOCK_ABOUT]) 
            self.files.append(f[0])
        self.pluginSubMenu.show_all()
        self.fView.set_model(self.fStore)

    def play_menu_entry(self, obj, data):
        self.pympd.play(data)

    def updateAFStore(self):
        self.afView.set_model(None)
        self.afStore.clear()
        options = self.configParser.options(FAV)
        for o in options:
            song = self.pympd.search('filename', o)
            if song[0].file.lower() not in self.files:
                self.afStore.append(song)
        self.afView.set_model(self.afStore)

    def cell_data_func(self, column, cell, model, iter, col_key):
         song = model.get_value(iter, 0)
         text = "%s - %s" % (song.artist, song.title)
         cell.set_property("text", text)

    def close_dialog(self, obj, data):
        obj.hide()
        return True
