#!/usr/bin/python
# vim: set fileencoding=utf-8 :
###########################################################################
#                                                                         #
#    .--~*teu.                                                  .uef^"    #
#  dF     988Nx    .xn!~%x.                                  :d88E        #
# d888b   `8888\  x888   888.         u                  .   `888E        #
# ?8888   98888F X8888   8888:     us888u.          .udR88N   888E .z8k   #
#  "**"  x88888~ 88888   X8888  .@88 "8888"        /888'888k  888E~?888L  #
#       d8888*`  88888   88888  9888  9888         9888 'Y"   888E  888E  #
#     z8**"`   : `8888  :88888X 9888  9888         9888       888E  888E  #
#   :?.....  ..F   `"**~ 88888' 9888  9888     .   9888       888E  888E  #
#  /""888888888~  .xx.   88888  9888  9888   .@8c  ?8888u../  888E  888E  #
#  8:  "888888*  '8888   8888~  "888*""888" '%888"  "8888P'  m888N= 888/  #
#  ""    "**"`    888"  :88%     ^Y"   ^Y'    ^*      "P'     `Y"   888   #
#                   ^"===""                                         J88"  #
#                                                        ,---.     @%     #
#  gcoherence - A GUI for the coherence framework       |'o o'|           #
#  Author:  Jonas Wagner                              B=.| m |.=B         #
#  License: GNU GPL V3 or later                          `,-.´            #
#  Website: http://29a.ch/                            B=´     `=B         #
#                                                                         #
#  Legal Foo                                                              #
#                                                                         #
#  Copyright (C) 2008 Jonas Wagner                                        #
#  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.                           #
#                                                                         #
###########################################################################
import atexit
import os
import subprocess
import time
import cPickle as pickle
import sys

import ConfigParser

import locale
locale.setlocale(locale.LC_ALL, '')

import gettext

PREFIX = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
LANGUAGES = [locale.getdefaultlocale()[0] or "en_US", "en_US"]
LOCALE_PATH = os.path.join(PREFIX, "share", "locale")
gettext.bindtextdomain('gcoherence', LOCALE_PATH)
gettext.textdomain('gcoherence')
gettext.translation('gcoherence', LOCALE_PATH,
        languages=LANGUAGES, fallback = True).install()

import pygtk
pygtk.require('2.0')
import gtk
import gobject


from x29a import mygtk, autostart

if sys.platform == "win32":
    def kill(pid):
        pass
else:
    def kill(proc):
        os.kill(proc.pid, 15)
        for n in range(10):
            if not proc.poll() is None:
                return
            time.sleep(0.1)
        os.kill(proc.pid, 9)
        proc.wait()

mygtk.register_webbrowser_url_hook()

NAME = "Coherence GUI"
VERSION = "1.0.0"
if sys.platform == "win32":
    DATA_PATH = os.path.expanduser("~/gcoherence/gcoherence.pickle")
else:
    XDG_CONFIG_HOME = os.path.expanduser(os.environ.get("XDG_CONFIG_HOME", "~/.config"))
    if not os.path.exists(XDG_CONFIG_HOME):
        os.mkdir(XDG_CONFIG_HOME)
    DATA_PATH = os.path.join(XDG_CONFIG_HOME, "gcoherence.pickle")

class Coherence(object):
    def __init__(self, shares):
        self.shares = shares
        self.start()

    def start(self):
        self.process = subprocess.Popen(["coherence"] +
            ["--plugin=backend:FSStore,name:%s,content:%s" %
                (share["name"], share["content"])
                for share in self.shares
            ]
        )

    def stop(self):
        kill(self.process)

    def restart(self):
        self.stop()
        self.start()

class MainWindow(gtk.Dialog):
    def __init__(self):
        gtk.Dialog.__init__(self, NAME)
        self.set_icon_name("gcoherence")
        self.set_default_size(450, 300)
        self.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY)
        self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
        self.vbox.pack_start(gtk.Label(_("Configure shares")), False)
        self.model = mygtk.ListStore(name=str, content=str)
        self.hbox = gtk.HBox()
        self.hbox.set_spacing(5)

        self.view = gtk.TreeView(self.model)
        self.view.insert_column_with_attributes(0, _("Name"),
                gtk.CellRendererText(), text=self.model.columns.name)
        self.view.insert_column_with_attributes(1, _("Content"),
                gtk.CellRendererText(), text=self.model.columns.content)

        self.hbox.pack_start(self.view)
        self.vbox_buttons = gtk.VBox()
        self.vbox_buttons.set_spacing(5)

        button_add = gtk.Button(stock=gtk.STOCK_ADD)
        button_add.connect("clicked", self.add_share)
        self.vbox_buttons.pack_start(button_add, False)

        button_modify = gtk.Button(stock=gtk.STOCK_PROPERTIES)
        button_modify.connect("clicked", self.modify_share)
        self.vbox_buttons.pack_start(button_modify, False)

        button_delete = gtk.Button(stock=gtk.STOCK_DELETE)
        button_delete.connect("clicked", self.remove_share)
        self.vbox_buttons.pack_start(button_delete, False)

        self.hbox.pack_start(self.vbox_buttons, False)
        self.vbox.pack_start(self.hbox)

        self.autostart = gtk.CheckButton(_("Start gcoherence automatically"))
        self.autostart.set_active(autostart.exists("gcoherence"))
        self.autostart.connect("toggled", self.autostart_toggled)
        self.vbox.pack_start(self.autostart, False)

        self.connect("delete-event", lambda *args: self.hide() or True)
        self.connect("destroy", lambda *args: self.hide() or True)

    def add_share(self, sender):
        dialog = ShareDialog()
        dialog.show_all()
        if dialog.run() == gtk.RESPONSE_APPLY:
            self.model.append(name=dialog.entry_name.get_text(),
                    content=dialog.path_chooser.get_filename())
        dialog.destroy()

    def modify_share(self, sender):
        model, titer = self.view.get_selection().get_selected()
        if titer is None:
            return
        dialog = ShareDialog()
        dialog.entry_name.set_text(self.model.get_value(titer, self.model.columns.name))
        dialog.path_chooser.set_filename(self.model.get_value(titer, self.model.columns.content))
        dialog.show_all()
        if dialog.run() == gtk.RESPONSE_APPLY:
            self.model.set(titer, self.model.columns.name, dialog.entry_name.get_text())
            self.model.set(titer, self.model.columns.content, dialog.path_chooser.get_filename())
        dialog.destroy()

    def remove_share(self, sender):
        model, titer = self.view.get_selection().get_selected()
        if titer is None:
            return
        model.remove(titer)

    def autostart_toggled(self, sender):
        if sender.get_active():
            app = os.path.abspath(__file__)
            autostart.add("gcoherence", app)
        else:
            autostart.remove("gcoherence")

class ShareDialog(gtk.Dialog):
    def __init__(self):
        gtk.Dialog.__init__(self, _("Share Properties"))
        self.set_modal(True)
        self.set_icon_name("gcoherence")
        self.entry_name = gtk.Entry()
        self.path_chooser = gtk.FileChooserButton(
            gtk.FileChooserDialog(_("Select a Folder to share"),
                self, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
        )
        self.vbox.pack_start(mygtk.make_table([
            [gtk.Label(_("Name")), self.entry_name],
            [gtk.Label(_("Path")), self.path_chooser]
        ]))
        self.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY)
        self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)


class StatusIcon(gtk.StatusIcon):
    def __init__(self):
        gtk.StatusIcon.__init__(self)
        try:
            self.shares = pickle.load(open(DATA_PATH))
        except Exception:
            self.shares = []
        self.coherence = Coherence(self.shares)
        self.set_from_icon_name("gcoherence")
        self.connect("activate", self.show_settings)
        self.connect("popup-menu", self.show_menu)
        self.menu = gtk.Menu()
        settings_item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PROPERTIES)
        settings_item.connect("activate", self.show_settings)
        self.menu.append(settings_item)
        about_item = gtk.ImageMenuItem(stock_id=gtk.STOCK_ABOUT)
        about_item.connect("activate", self.show_about)
        self.menu.append(about_item)
        self.menu.append(gtk.SeparatorMenuItem())
        quit_item = gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT)
        quit_item.connect("activate", gtk.main_quit)
        self.menu.append(quit_item)
        self.dialog = None
        atexit.register(self.destroy)

    def destroy(self):
        self.coherence.stop()
        pickle.dump(self.shares, open(DATA_PATH, "w"), protocol=2)

    def show_about(self, sender):
        dialog = gtk.AboutDialog()
        dialog.set_name(NAME)
        dialog.set_version(VERSION)
        dialog.set_comments(
                _("A GUI for the Coherence DLNA/UPnP Framework"))
        dialog.set_copyright("Copyright (c) 2008 by Jonas Wagner")
        dialog.set_license("""
Copyright (C) 2008 Jonas Wagner
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.
        """)
        dialog.set_logo(mygtk.iconfactory.get_icon("gcoherence", 128))
        dialog.set_website("http://29a.ch/")
        dialog.set_website_label("http://29a.ch/")
        dialog.set_authors(["Jonas 'veers' Wagner"])
        dialog.set_artists(["Jonas 'veers' Wagner",
            "Tango project ( http://tango.freedesktop.org/ )"])
        dialog.set_translator_credits(_("translator-credits"))
        dialog.run()
        dialog.destroy()


    def show_settings(self, sender):
        if self.dialog:
            self.dialog.hide()
            self.dialog.show()
            return
        self.dialog = MainWindow()
        dialog = self.dialog
        dialog.model.unserialize(self.shares)
        dialog.show_all()
        result = dialog.run()
        self.shares = dialog.model.serialize()
        self.dialog = None
        dialog.destroy()
        self.coherence.shares = self.shares
        self.coherence.restart()
        if result == gtk.RESPONSE_APPLY:
            self.show_settings(sender)

    def show_menu(self, icon, button, time):
        self.menu.show_all()
        self.menu.popup(None, None, None, button, time)


def main():
    icon = StatusIcon()
    gtk.main()


if __name__ == "__main__":
    main()
