# Copyright 2005-2006 Sergey Fedoseev <fedoseev.sergey@gmail.com>
# Copyright 2007 Simon Morgan <zen84964@zen.co.uk>
#           2017 Nick Boultbee
#
# 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 2 of the License, or
# (at your option) any later version.

import os
import sys

if os.name == "nt" or sys.platform == "darwin":
    from quodlibet.plugins import PluginNotSupportedError
    raise PluginNotSupportedError

from gi.repository import GLib
from gi.repository import Gio
from gi.repository import Gtk

from quodlibet import _
from quodlibet.plugins.events import EventPlugin
from quodlibet.pattern import Pattern
from quodlibet.qltk import Frame, Icons
from quodlibet import config

# Translators: statuses relating to Instant Messenger apps
_STATUSES = {'online': _('online'),
             'offline': _('offline'),
             'chat': _('chat'),
             'away': _('away'),
             'xa': _('xa'),
             'invisible': _('invisible')}


class GajimStatusMessage(EventPlugin):
    PLUGIN_ID = 'Gajim status message'
    PLUGIN_NAME = _('Gajim Status Message')
    PLUGIN_DESC = _("Changes Gajim status message according to what "
                    "you are currently listening to.")
    PLUGIN_ICON = Icons.FACE_SMILE

    c_accounts = __name__ + '_accounts'
    c_paused = __name__ + '_paused'
    c_statuses = __name__ + '_statuses'
    c_pattern = __name__ + '_pattern'

    def __init__(self):
        try:
            self.accounts = config.get('plugins', self.c_accounts).split()
        except:
            self.accounts = []
            config.set('plugins', self.c_accounts, '')

        try:
            self.paused = config.getboolean('plugins', self.c_paused)
        except:
            self.paused = True
            config.set('plugins', self.c_paused, 'True')

        try:
            self.statuses = config.get('plugins', self.c_statuses).split()
        except:
            self.statuses = ['online', 'chat']
            config.set('plugins', self.c_statuses, " ".join(self.statuses))

        try:
            self.pattern = config.get('plugins', self.c_pattern)
        except:
            self.pattern = '<artist> - <title>'
            config.set('plugins', self.c_pattern, self.pattern)

    def enabled(self):
        self.interface = None
        self.current = ''

    def disabled(self):
        if self.current != '':
            self.change_status(self.accounts, '')

    def change_status(self, enabled_accounts, status_message):
        if not self.interface:
            try:
                self.interface = Gio.DBusProxy.new_for_bus_sync(
                    Gio.BusType.SESSION, Gio.DBusProxyFlags.NONE, None,
                    'org.gajim.dbus', '/org/gajim/dbus/RemoteObject',
                    'org.gajim.dbus.RemoteInterface', None)
            except GLib.Error:
                self.interface = None

        if self.interface:
            try:
                for account in self.interface.list_accounts():
                    status = self.interface.get_status('(s)', account)
                    if enabled_accounts != [] and \
                            account not in enabled_accounts:
                        continue
                    if status in self.statuses:
                        self.interface.change_status('(sss)',
                            status, status_message, account)
            except GLib.Error:
                self.interface = None

    def plugin_on_song_started(self, song):
        if song:
            self.current = Pattern(self.pattern) % song
        else:
            self.current = ''
        self.change_status(self.accounts, self.current)

    def plugin_on_paused(self):
        if self.paused and self.current != '':
            self.change_status(self.accounts,
                               "%s [%s]" % (self.current, _("paused")))

    def plugin_on_unpaused(self):
        self.change_status(self.accounts, self.current)

    def accounts_changed(self, entry):
        self.accounts = entry.get_text().split()
        config.set('plugins', self.c_accounts, entry.get_text())

    def pattern_changed(self, entry):
        self.pattern = entry.get_text()
        config.set('plugins', self.c_pattern, self.pattern)

    def paused_changed(self, c):
        config.set('plugins', self.c_paused, str(c.get_active()))

    def statuses_changed(self, b):
        if b.get_active() and b.get_name() not in self.statuses:
            self.statuses.append(b.get_name())
        elif b.get_active() is False and b.get_name() in self.statuses:
            self.statuses.remove(b.get_name())
        config.set('plugins', self.c_statuses, " ".join(self.statuses))

    def PluginPreferences(self, parent):
        vb = Gtk.VBox(spacing=6)

        pattern_box = Gtk.HBox(spacing=6)
        pattern_box.set_border_width(3)
        pattern = Gtk.Entry()
        pattern.set_text(self.pattern)
        pattern.connect('changed', self.pattern_changed)
        pattern_box.pack_start(Gtk.Label(label=_("Pattern:")), False, True, 0)
        pattern_box.pack_start(pattern, True, True, 0)

        accounts_box = Gtk.HBox(spacing=3)
        accounts_box.set_border_width(3)
        accounts = Gtk.Entry()
        accounts.set_text(" ".join(self.accounts))
        accounts.connect('changed', self.accounts_changed)
        accounts.set_tooltip_text(
            _("List accounts, separated by spaces, for "
              "changing status message. If none are specified, "
              "status message of all accounts will be changed."))
        accounts_box.pack_start(Gtk.Label(label=_("Accounts:")),
                                False, True, 0)
        accounts_box.pack_start(accounts, True, True, 0)

        c = Gtk.CheckButton(label=_("Add '[paused]'"))
        c.set_active(self.paused)
        c.connect('toggled', self.paused_changed)
        c.set_tooltip_text(_("If checked, '[paused]' will be added to "
                             "status message on pause"))

        table = Gtk.Table()
        self.list = []
        i = 0
        j = 0
        for status, translated in _STATUSES.items():
            button = Gtk.CheckButton(label=translated)
            button.set_name(status)
            if status in self.statuses:
                button.set_active(True)
            button.connect('toggled', self.statuses_changed)
            self.list.append(button)
            table.attach(button, i, i + 1, j, j + 1)
            if i == 2:
                i = 0
                j += 1
            else:
                i += 1

        vb.pack_start(pattern_box, True, True, 0)
        vb.pack_start(accounts_box, True, True, 0)
        vb.pack_start(c, True, True, 0)
        frame = Frame(label=_("Statuses for which message will be changed"),
                      child=table)
        vb.pack_start(frame, True, True, 6)
        return vb
