#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# GPL. (C) 2013 Paolo Patruno.

from autoradio.mpris2.mediaplayer2 import MediaPlayer2
from autoradio.mpris2.player import Player
from autoradio.mpris2.tracklist import TrackList
from autoradio.mpris2.interfaces import Interfaces
from autoradio.mpris2.some_players import Some_Players
from autoradio.mpris2.utils import get_players_uri
from autoradio.mpris2.utils import get_session
from dbus.mainloop.glib import DBusGMainLoop
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

import os,stat,time,urllib.parse,urllib.request,urllib.parse,urllib.error,optparse,sys
from gi.repository import GObject
import dbus
import autoradio.settings
import urllib.parse
import traceback

busaddress=autoradio.settings.busaddressplayer

def convert_ns(t):
    s,ns = divmod(t, 1000000)
    m,s = divmod(s, 60)
    
    if m < 60:
      return "%02i:%02i" %(m,s)
    else:
      h,m = divmod(m, 60)
    return "%i:%02i:%02i" %(h,m,s)


class Main(object):

  def playhandler(self, *args, **kw):
      playbackstatus = args[1].get("PlaybackStatus",None)
      position = args[1].get("Position",None)

      if playbackstatus is not None:
          print("PlaybackStatus",playbackstatus)

      if playbackstatus == "Stopped":
          self.play_button.set_sensitive(True)
          self.pause_button.set_sensitive(False)
          self.stop_button.set_sensitive(False)
      elif playbackstatus == "Playing":
          self.play_button.set_sensitive(True)
          self.pause_button.set_sensitive(True)
          self.stop_button.set_sensitive(True)
      elif playbackstatus == "Paused":
          self.play_button.set_sensitive(True)
          self.pause_button.set_sensitive(True)
          self.stop_button.set_sensitive(True)


      if position is not None:
          try:
              id = self.play.Metadata.get(u'mpris:trackid',None)
          except:
              id = None

          if id is not None:
              length=self.tl.GetTracksMetadata((id,))[0].get(u'mpris:length',None)
              if position <= length and length != 0:
                  frac = float(position)/float(length)
              else:
                  frac = 0
              if (self.oldid != id): self.update()
              self.oldid = id

          else:
              frac = 0
          self.pbar.set_fraction(frac)

      else:
          self.pbar.pulse()
                    
  def __init__(self):

    self.connected=False
    self.oldid=None
    
    #Connect to player
    DBusGMainLoop(set_as_default=True)
    uris = list(get_players_uri(pattern=".",busaddress=busaddress))

    if len(uris) >0 :
        uri=uris[0]

        if busaddress is None:
            bus = dbus.SessionBus()
        else:
            bus = dbus.bus.BusConnection(busaddress)

        self.mp2 = MediaPlayer2(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
        self.play = Player(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
    else:
        print("No players availables")
        return

    try:
        if hasattr (self.mp2, 'HasTrackList'):
            if self.mp2.HasTrackList:
                self.tl = TrackList(dbus_interface_info={'dbus_uri': uri,'dbus_session':bus})
                
                #self.tl.PropertiesChanged = self.update
                self.tl.TrackListReplaced = self.update
                self.tl.TrackAdded = self.update
                self.tl.TrackRemoved = self.update
                self.tl.TrackMetadataChanged = self.update

            else:
                self.tl = None
        else:
            self.tl = None
    except  dbus.exceptions.DBusException:
            self.tl = None
        
    self.play.PropertiesChanged = self.playhandler

    self.connected = True

    # Create the GUI
    #self.win = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
    self.win = Gtk.Window()

    self.win.set_size_request(400, 600)
    self.win.set_title("AutoPlayer gui")
    self.win.connect("destroy", Gtk.main_quit)
    vbox = Gtk.VBox(homogeneous=False,spacing=0)
    hbox = Gtk.HBox(homogeneous=False,spacing=0)
    self.load_file = Gtk.FileChooserButton(homogeneous="Choose Audio File")
    self.play_button = Gtk.ToolButton( stock_id=Gtk.STOCK_MEDIA_PLAY)
    self.pause_button = Gtk.ToolButton( stock_id=Gtk.STOCK_MEDIA_PAUSE)
    self.stop_button = Gtk.ToolButton( stock_id=Gtk.STOCK_MEDIA_STOP)
    self.delete_button = Gtk.Button(label='Delete')
    self.delete_button.connect('clicked', self.on_delete_button_clicked) 
    self.load_file.connect("selection-changed",self.on_file_selected)
    self.play_button.connect("clicked", self.on_play_clicked)
    self.pause_button.connect("clicked", self.on_pause_clicked)
    self.stop_button.connect("clicked", self.on_stop_clicked)
    hbox.pack_start(self.play_button, False, True, 0)
    hbox.pack_start(self.pause_button, False, True, 0)
    hbox.pack_start(self.stop_button, False, True, 0)
    hbox.pack_start(self.delete_button, False, False, 1)
#        # Create a centering alignment object
#    align = Gtk.Alignment.new(0.5, 0.5, 0, 0)
#    vbox.pack_start(align, False, False, 5)
#    align.show()


    # Create the ProgressBar
    self.pbar = Gtk.ProgressBar()
    self.pbar.set_inverted(False)
    self.pbar.set_fraction(.5)
    hbox.pack_start(self.pbar, True, True, 0)
    self.pbar.show()

    vbox.pack_start(self.load_file, False, True, 0)
    vbox.pack_start(hbox, False, True, 0)

#    vbox.pack_start(self.pbar, True, True, 0)
#    self.pbar.show()
#    self.pbar.pulse()
    #separator = Gtk.HSeparator()
    #vbox.pack_start(separator, False, False, 0)

        # create the TreeView
    column_names = ['ID', 'Len', 'Artist', 'Title']
    cell_data_funcs = (self.get_id, self.Len, self.Artist,self.Title)

    self.treeview = Gtk.TreeView()
 
        # create the TreeViewColumns to display the data
    self.tvcolumn = [None] * len(column_names)
    listmodel = self.make_list()

    for n in range(0, len(column_names)):
      cell = Gtk.CellRendererText()
      self.tvcolumn[n] = Gtk.TreeViewColumn(column_names[n], cell)
      if n == 1:
        cell.set_property('xalign', 1.0)
      self.tvcolumn[n].set_cell_data_func(cell, cell_data_funcs[n])
      self.treeview.append_column(self.tvcolumn[n])

    self.treeview.connect('row-activated', self.open_file)
    self.scrolledwindow = Gtk.ScrolledWindow()
    self.scrolledwindow.add(self.treeview)
    vbox.pack_start(self.scrolledwindow, True, True, 0)
    self.treeview.set_model(listmodel)
    self.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    self.win.add(vbox)
    self.win.show_all()

    #GObject.timeout_add(6000,self.update)

  def update(self, *args, **kw):
    print("update gtktree")
    try:
      new_model = self.make_list()
      self.treeview.set_model(new_model)
      while Gtk.events_pending():
          Gtk.main_iteration_do(True)
      #self.treeview.queue_draw()
      return True

    except:
      Gtk.main_quit()
      return False

  def on_delete_button_clicked(self, button):
     
      # Get the TreeView selected row(s)
      selection = self.treeview.get_selection()

      # get_selected_rows() returns a tuple
      # The first element is a ListStore
      # The second element is a list of tree paths
      # of all selected rows
      model, paths = selection.get_selected_rows()
        
      # Get the TreeIter instance for each path
      for path in paths:
          iter = model.get_iter(path)
          # Remove the ListStore row referenced by iter
          print("remove: ",model.get_value(iter, 0))
          self.tl.RemoveTrack(model.get_value(iter, 0))
          #model.remove(iter)


  def on_file_selected(self, widget):
    multimedia_file = self.load_file.get_filename()
    url=urllib.parse.urlsplit(multimedia_file)
    uri=urllib.parse.urljoin("file://",urllib.parse.unquote(url.path))
    new_model = self.make_list()
    self.treeview.set_model(new_model)
    self.tl.AddTrack(uri, self.play.Metadata.get(u'mpris:trackid',""), False)

  def on_play_clicked(self, widget):
      self.play.Play()
  def on_pause_clicked(self, widget):
    self.play.PlayPause()
  def on_stop_clicked(self, widget):
    self.play.Stop()

  def open_file(self, treeview, path, column):
        model = treeview.get_model()
        iter = model.get_iter(path)
        print("goto: ",model.get_value(iter, 0))
        self.tl.GoTo(model.get_value(iter, 0))
        new_model = self.make_list()
        self.treeview.set_model(new_model)

  def make_list(self):
    listmodel = Gtk.ListStore(object)

    try:
        if self.tl is not None:
            if  len(self.tl.Tracks) > 0:
                # attributes and methods together
                for track in  self.tl.GetTracksMetadata( self.tl.Tracks):
                    listmodel.append([track.get(u'mpris:trackid',"")])
    except:
        print(traceback.format_exc())
        print("Error getting player playlist")
        Gtk.main_quit()

    return listmodel

  def get_id(self, column, cell, model, iter, data=None):
        cell.set_property('text', model.get_value(iter, 0))
        if model.get_value(iter, 0) == self.play.Metadata.get(u'mpris:trackid',None):
            cell.set_property('cell-background',"red")
        else:
            cell.set_property('cell-background',"green")
        return
    
  def Len(self, column, cell, model, iter, data=None):
    track=self.tl.GetTracksMetadata((model.get_value(iter, 0),))
    cell.set_property('text', convert_ns(track[0].get(u'mpris:length',"")))
    return

  def Artist(self, column, cell, model, iter, data=None):
    track=self.tl.GetTracksMetadata((model.get_value(iter, 0),))
    dir=os.path.dirname(urllib.parse.urlparse(track[0].get(u'xesam:url',"")).path).split('/')[-1]
    cell.set_property('text', track[0].get(u'xesam:artist', dir))
    return

  def Title(self, column, cell, model, iter, data=None):
    track=self.tl.GetTracksMetadata((model.get_value(iter, 0),))
    file=os.path.basename(urllib.parse.urlparse(track[0].get(u'xesam:url',"")).path)
    cell.set_property('text', track[0].get(u'xesam:title',file))
    return
      
if __name__ == "__main__":


    from autoradio import  _version_

    p = optparse.OptionParser(usage="usage: %prog",
                              description="%prog graphic user interface for autoradio player",version="%prog "+_version_)
    args = sys.argv
    if args is not None:
        p.parse_args(args)
        if len(args) > 1:
            sys.exit(1)

    try:
        if Main().connected:
            Gtk.main()
    except KeyboardInterrupt :
        # Clean up
        print('Keyboard Exiting')
        Gtk.main_quit()
