# -*- Mode: python; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*-
#
# GNOME Activity Journal
#
# Copyright © 2010 Stefano Candori <stefano.candori@gmail.com>
# Copyright © 2011 Collabora Ltd.
#             By Siegfried-Angel Gevatter Pujals <siegfried@gevatter.com>
# Copyright © 2020 The GNOME Activity Journal developers
#
# 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

from .config import get_icon_path, preference_settings
from .blacklist import BLACKLIST
from .common import *

import gi
from gi.repository import Gtk

HAS_INDICATOR = True
HAS_TRAYICON = False

try:
    gi.require_version('AyatanaAppIndicator3', '0.1')
    from gi.repository import AyatanaAppIndicator3 as AppIndicator3
    print("Using Ayatana AppIndicator3 for tray icons.")
except:
    HAS_INDICATOR = False

if not HAS_INDICATOR:
    try:
        gi.require_version('AppIndicator3', '0.1')
        from gi.repository import AppIndicator3
        print("Using default AppIndicator3 for tray icons. If it doesn't "
              "work, install the AyatanaAppIndicator3 gir package.")
        HAS_INDICATOR = True
    except:
        HAS_INDICATOR = False

if HAS_INDICATOR:
    class Indicator(object):
        """
        A wrapper class for appindicator
        """
        def __init__(self, main_window):
            path = get_icon_path(APP_ICON_NORMAL)
            name = _("Activity Journal")
            self.indicator = AppIndicator3.Indicator.new(id=name, icon_name=path, \
                                                         category=AppIndicator3.IndicatorCategory.APPLICATION_STATUS)

            self.main_window = main_window
            menu = Menu(self.main_window, self)
            self.indicator.set_menu(menu)

        def set_visible(self, visible):
            status = AppIndicator3.IndicatorStatus.ACTIVE if visible else AppIndicator3.IndicatorStatus.PASSIVE
            self.indicator.set_status(status)

        def set_icon(self, paused):
            name = APP_ICON_PAUSED if paused else APP_ICON_NORMAL
            self.indicator.set_icon(get_icon_path(name))

class TrayIcon(Gtk.StatusIcon):
    """
    A widget that implements the tray icon
    """
    def __init__(self, main_window):

        Gtk.StatusIcon.__init__(self)
        self.main_window = main_window
        path = get_icon_path(APP_ICON_PAUSED)
        self.set_from_file(path)
        self.set_tooltip_text(_("Activity Journal"))
        self.connect('activate', self._on_activate)
        self.connect('popup-menu', self._on_popup)

        self.menu = Menu(self.main_window, self)

    def _on_activate(self, trayicon):
        if(self.main_window.get_property("visible")):
            self.main_window.hide()
        else:
            self.main_window.show()

    def _on_popup(self, trayicon, button, activate_time):
        position = None
        if os.name == 'posix':
            position = Gtk.status_icon_position_menu
        self.menu.popup(None, None, position, button, activate_time, trayicon)

    def set_icon(self, paused):
        name = APP_ICON_PAUSED if paused else APP_ICON_NORMAL
        self.set_from_file(get_icon_path(name))

class Menu(Gtk.Menu):
    """
    a widget that represents the menu displayed on the trayicon on the
    main window
    """

    def __init__(self, main_window, parent=None):

        Gtk.Menu.__init__(self)
        self.main_window = main_window
        self._parent = parent
        self.show_app = Gtk.MenuItem(_('Show Activity Journal'))
        self.show_app.connect('activate', self._on_activate)
        self.incognito_enable = Gtk.MenuItem(_('Pause Event Logging'))
        self.incognito_enable.connect('activate', self._toggle_incognito)
        self.incognito_disable = Gtk.MenuItem(_('Resume Event Logging'))
        self.incognito_disable.connect('activate', self._toggle_incognito)
        self.quit_item = Gtk.MenuItem(_('Quit'))
        self.quit_item.connect('activate',
            lambda *args: self.main_window.quit_and_save())

        self.append(self.show_app)
        self.append(self.incognito_enable)
        self.append(self.incognito_disable)
        self.append(Gtk.SeparatorMenuItem())
        self.append(self.quit_item)

        self.show_all()

        BLACKLIST.set_incognito_toggle_callback(self._update_incognito)
        if self._update_incognito() is None:
            self.incognito_enable.hide()
            self.incognito_disable.hide()

    def _on_activate(self, tray):
        if self.main_window != None:
            self.main_window.present_with_time(Gtk.get_current_event_time())

    @ignore_exceptions()
    def _update_incognito(self):
        enabled = BLACKLIST.get_incognito()
        if enabled:
            self.incognito_enable.hide()
            self.incognito_disable.show()
        else:
            self.incognito_enable.show()
            self.incognito_disable.hide()
        if self._parent is not None:
            self._parent.set_icon(paused=enabled)
        self.main_window.update_title_from_status(enabled)
        return enabled

    @ignore_exceptions()
    def _toggle_incognito(self, *discard):
        BLACKLIST.toggle_incognito()

class TrayIconManager():

    def __init__(self, main_window):
        self.tray = None
        self.main_window = main_window
        if preference_settings["enable-tray-icon"]:
            self._create_tray_icon(self.main_window)

        preference_settings.connect("changed", self._on_tray_conf_changed)

    @staticmethod
    def check_dependencies():
        return (HAS_INDICATOR or HAS_TRAYICON)

    def _create_tray_icon(self, main_window):
        if HAS_INDICATOR:
            self.tray = Indicator(main_window)
        else:
            self.tray = TrayIcon(main_window)
            if self.tray.is_embedded():
                print("Using GtkStatusIcon for Tray icons. If it doesn't "
                      "work, install the AppIndicator3 or AyatanaAppIndicator3 "
                      "gir packages.")
                HAS_TRAYICON = True
            else:
                self.tray = None

        if self.tray:
            self.tray.set_visible(True)

    def _on_tray_conf_changed(self, settings, key):
        if key == 'enable-tray-icon':
            if not self.tray:
                self._create_tray_icon(self.main_window)
            else:
                self.tray.set_visible(settings.get_boolean(key))
