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

from __future__ import division
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import range
from builtins import object
from past.utils import old_div
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 pygtk
try:
    from gi import pygtkcompat
except ImportError:
    pygtkcompat = None

if pygtkcompat is not None:
    pygtkcompat.enable() 
    pygtkcompat.enable_gtk(version='3.0')

import gtk

import os,stat,time,urllib.parse,urllib.request,urllib.parse,urllib.error,optparse,sys
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 delete_event(self, widget, event, data=None):
    gtk.main_quit()
    return False
 
  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:
          id = self.play.Metadata.get(u'mpris:trackid',None)
          if id is not None:
              length=self.tl.GetTracksMetadata((id,))[0].get(u'mpris:length',None)
              if position <= length and length != 0:
                  frac = old_div(float(position),float(length))
              else:
                  frac = 0
          else:
              frac = 0
          self.pbar.set_fraction(frac)
      else:
          self.pbar.pulse()


  def __init__(self):

    self.connected=False

    #Connect to player
    DBusGMainLoop(set_as_default=True)
    uris = 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(gtk.WINDOW_TOPLEVEL)

    self.win.set_size_request(400, 600)
    self.win.set_title("AutoPlayer gui")
    self.win.connect("delete_event", self.delete_event)
    vbox = gtk.VBox(False, 0)
    hbox = gtk.HBox(False, 0)
    self.load_file = gtk.FileChooserButton("Choose Audio File")
    self.play_button = gtk.ToolButton( gtk.STOCK_MEDIA_PLAY)
    self.pause_button = gtk.ToolButton( gtk.STOCK_MEDIA_PAUSE)
    self.stop_button = gtk.ToolButton( gtk.STOCK_MEDIA_STOP)
    self.delete_button = gtk.Button('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(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)
    self.pbar.show()

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

#    vbox.pack_start(self.pbar)
#    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.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.SELECTION_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)
      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 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()
