#!/usr/bin/python

# LADITools - Linux Audio Desktop Integration Tools
# laditray - System tray integration for LADI
# Copyright (C) 2011-2012 Alessio Treglia <quadrispro@ubuntu.com>
# Copyright (C) 2007-2010, Marc-Olivier Barre <marco@marcochapeau.org>
# Copyright (C) 2007-2009, Nedko Arnaudov <nedko@arnaudov.name>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

import os
import sys
import signal
import gettext
import argparse

sig_handler = signal.getsignal(signal.SIGTERM)
signal.signal(signal.SIGINT, sig_handler)

from laditools import _gettext_domain
gettext.install(_gettext_domain)

from laditools import get_version_string
from laditools import LadiConfiguration

from gi.repository import Gtk
from gi.repository import GdkPixbuf
from gi.repository import GObject
from laditools.gtk import LadiManager
from laditools.gtk import find_data_file

timeout_add = GObject.timeout_add

# Default configuration
autostart_default = False

class laditray (Gtk.StatusIcon, LadiManager):
    def __init__ (self):
        # Handle the configuration
        self.global_config = LadiConfiguration()
        self.laditray_param_dict = self.global_config.get_config_section ('laditray')
        if self.laditray_param_dict != None:
            if 'autostart' not in self.laditray_param_dict:
                self.laditray_param_dict['autostart'] = str (autostart_default)
        else:
            self.laditray_param_dict = {}
            self.laditray_param_dict['autostart'] = str (autostart_default)
        autostart = self.laditray_param_dict['autostart']
        # Build the UI
        LadiManager.__init__(self, self.global_config.get_config_section ('ladimenu'), autostart)
        GObject.GObject.__init__ (self)
        self.icon_state = ""
        self.last_status_text = ""
        # Create the needed pixbufs to manage the status icon's look
        self.stopped_pixbuf = GdkPixbuf.Pixbuf.new_from_file(find_data_file("stopped.svg"))
        self.starting_pixbuf = GdkPixbuf.Pixbuf.new_from_file(find_data_file("starting.svg"))
        self.started_pixbuf = GdkPixbuf.Pixbuf.new_from_file(find_data_file("started.svg"))
        self.set_icon ("stopped")
        # Get the initial status
        self.update ()
        # Add the auto update callback
        self.auto_updater = timeout_add (250, self.update, None)
        # Make the menu popup when the icon is right clicked
        self.connect ("popup-menu", self.menu_activate)

    def menu_activate(self, status_icon, button, activate_time, user_data=None):
        menu = self.create_menu()
        menu.popup (parent_menu_shell=None,
                    parent_menu_item=None,
                    func=self.position_menu,
                    data=self,
                    button=button,
                    activate_time=activate_time)
        menu.reposition ()

    def set_starting_status (self):
        self.set_tooltip_safe ("JACK is starting")
        self.set_icon ("starting")

    def set_icon (self, newstate):
        if self.icon_state == newstate:
            return
        self.icon_state = newstate
        if newstate == "stopped": self.set_from_pixbuf (self.stopped_pixbuf)
        if newstate == "started": self.set_from_pixbuf (self.started_pixbuf)
        if newstate == "starting": self.set_from_pixbuf (self.starting_pixbuf)

    def set_tooltip_safe (self, text):
        if text != self.last_status_text:
            self.set_tooltip_text (text)
            self.last_status_text = text

    def update (self, user_data = None):
        try:
            if self.jack_is_started():
                # Get Realtime status
                if self.jack_is_realtime():
                    status_text = "RT | "
                else:
                    status_text = ""
                # Get DSP Load
                status_text += str (round (float (self.jack_get_load()),1)) + "% | "
                # Get Xruns
                status_text += str (self.jack_get_xruns())
                # Set a started status
                self.set_tooltip_safe (status_text)
                self.set_icon ("started")
            else:
                self.set_tooltip_safe ("JACK is stopped")
                self.set_icon ("stopped")
            self.clear_diagnose_text()
        except Exception, e:
            self.set_tooltip_safe ("JACK is sick")
            self.set_diagnose_text(repr(e))
            self.set_icon ("stopped")
            self.clear_jack_proxies()
        # Take a look at the processes we've started so we don't get any zombies
        for i in self.proc_list:
            i.poll ()
        return True

    def run(self):
        Gtk.main ()
        # Some default config might need to be injected in the config file,
        # we handle all that before we quit.
        self.global_config.set_config_section ('ladimenu', self.menu_array)
        self.global_config.set_config_section ('laditray', self.laditray_param_dict)
        self.global_config.save ()
        return 0

#try:

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=_('system tray icon that allows users to start, stop and'
                                                    'monitor JACK, as well as start some JACK related applications'),
                                     epilog=_('This program is part of the LADITools suite.'))
    parser.add_argument('--version', action='version', version="%(prog)s " + get_version_string())

    parser.parse_args()

    laditray().run()
    sys.exit(0)
#except Exception, e:
#    error = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, "Unexpected error\n\n" + repr(e))
#    error.run()
#    exit(1)
