#! /usr/bin/env python
import pygtk; pygtk.require("2.0")

import sys
import os.path
import gobject
import gtk
import gtk.gdk
import bonobo
import gconfsync
import gnome
import gnome.ui
import gettext
import gnome_osd_conf

gnome.program_init("gnome-osd-properties", gnome_osd_conf.VERSION)
gettext.install("gnome-osd", gnome_osd_conf.datadir + "/locale")

try:
    icon = gtk.gdk.pixbuf_new_from_file(os.path.join(gnome_osd_conf.datadir,
                                                     "pixmaps", "gnome-osd.png"))
    gtk.window_set_default_icon_list(icon)
    del icon
except gobject.GError:
    print "Icon file not found"


prefs = gconfsync.GConfSync("/apps/gnome-osd")

class HIGContainer(gtk.Alignment):
    def __init__(self, title, child):
        gtk.Alignment.__init__(self)
        self.set(xalign=0, yalign=0, xscale=1, yscale=1)
        vbox = gtk.VBox()
        vbox.show()
        self.add(vbox)
        vbox.set_spacing(6)
        label = gtk.Label(); label.show()
        label.set_markup('<span weight="bold">%s</span>' % title)
        label.set_use_underline(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label)
        hbox = gtk.HBox(); hbox.show()
        vbox.pack_start(hbox)
        label = gtk.Label('    '); label.show()
        hbox.pack_start(label, False, False)
        hbox.pack_start(child, True, True)
        self.show()
                 

class RadioGroup(gobject.GObject):
    __gsignals__ = {
        'changed': (gobject.SIGNAL_RUN_LAST,
                    None, # return type
                    (object, )) # parameter types
    }

    def __init__(self, items):
        self.__gobject_init__()
        self.radio_map = dict()
        self.items = dict()
        self.__ignore_toggled = False
        radio = None
        for item in items:
            radio = gtk.RadioButton(radio, item[0])
            self.radio_map[radio] = item[1]
            self.items[item[1]] = radio
            radio.show()
            radio.connect("toggled", self.__radio_toggled)

    def __radio_toggled(self, radio):
        if self.__ignore_toggled:
            return
        if radio.get_active():
            value = self.radio_map[radio]
            self.emit("changed", value)

    def get_value(self):
        for radio in self.radio_map:
            if radio.get_active():
                return self.radio_map[radio]

    def set_value(self, value):
        self.__ignore_toggled = True
        radio = self.items[value]
        radio.set_active(True)
        self.__ignore_toggled = False

gobject.type_register(RadioGroup)

class RadioGroupSync(object):

    ''' Synchronizes a gconf key with a radio group '''

    def __init__(self, group, prefs, key):
        prefs.connect("changed::%s" % key, self.__pref_changed)
        group.connect("changed", self.__gui_changed)
        self.group = group
        self.prefs = prefs
        self.key = key
        group.set_value(prefs[key])

    def __pref_changed(self, prefs, key):
        self.group.set_value(prefs[key])

    def __gui_changed(self, group, value):
        self.prefs[self.key] = value

class FontSync(object):
    def __init__(self, font, prefs, key):
        font.connect("font-set", self.__font_changed)
        prefs.connect("changed::%s" % key, self.__pref_changed)
        font.set_font_name(prefs[key])
        self.prefs = prefs
        self.key = key
        self.font = font
    def __font_changed(self, font, font_name):
        self.prefs[self.key] = font_name
    def __pref_changed(self, prefs, key):
        self.font.set_font_name(self.prefs[key])

class ToggleSync(object):
    def __init__(self, toggle, prefs, key):
        self.prefs = prefs
        self.key = key
        self.toggle = toggle
        toggle.set_active(prefs[key])
        toggle.connect("toggled", self.__toggled)
        prefs.connect("changed::%s" % key, self.__pref_changed)
        self.__ignore_toggled = False
    def __toggled(self, toggle):
        if self.__ignore_toggled:
            return
        self.prefs[self.key] = toggle.get_active()
    def __pref_changed(self, prefs, key):
        self.__ignore_toggled = True
        self.toggle.set_active(self.prefs[key])
        self.__ignore_toggled = False

RESPONSE_TEST = 1
dialog = gtk.Dialog(title=_("OSD Properties"),
                    buttons=(_("_Test"), RESPONSE_TEST,
                             gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE,
                             )
                    )
dialog.set_property("has-separator", 0)
dialog.set_border_width(12)
dialog.vbox.set_spacing(18)
dialog.set_default_response(RESPONSE_TEST)
dialog.set_resizable(False)

# Font
hbox = gtk.HBox(False, 6)
label = gtk.Label(_("OSD _Font: "))
label.set_use_underline(True)
label.set_alignment(0, 0.5)
hbox.pack_start(label, False, True)

font = gnome.ui.FontPicker()
font.set_property('mode', gnome.ui.FONT_PICKER_MODE_FONT_INFO)
hbox.pack_start(font, True, True)
label.set_mnemonic_widget(font)
hbox.show_all()
dialog.vbox.add(hbox)

FontSync(font, prefs, 'osd_font')

hbox = gtk.HBox(False, 6)
hbox.show()
dialog.vbox.add(hbox)

# Animations
animations = gtk.CheckButton(_("_Animations"))
animations.show()
hbox.add(animations)
ToggleSync(animations, prefs, "animations")

# Drop shadow
drop_shadow = gtk.CheckButton(_("_Drop shadow"))
drop_shadow.show()
hbox.add(drop_shadow)
ToggleSync(drop_shadow, prefs, "drop_shadow")

# Sound
sound = gtk.CheckButton(_("_Sound"))
sound.show()
hbox.add(sound)
ToggleSync(sound, prefs, "enable_sound")

# Hide on hover
hide = gtk.CheckButton(_("_Hide on mouse hover"))
hide.show()
dialog.vbox.add(hide)
ToggleSync(hide, prefs, "hide_on_hover")

# --- Alignment
group = RadioGroup([
    (_("Top _left"),     'top-left'),
    (_("_Top"),          'top-center'),
    (_("Top _right"),    'top-right'),
    (_("Bottom l_eft"),  'bottom-left'),
    (_("_Bottom"),       'bottom-center'),
    (_("Bottom r_ight"), 'bottom-right'),
    ])

table = gtk.Table(2, 3)
table.show()
table.set_row_spacings(6)
table.set_col_spacings(6)

table.attach(group.items['top-left'], 0, 1, 0, 1)
table.attach(group.items['top-center'], 1, 2, 0, 1)
table.attach(group.items['top-right'], 2, 3, 0, 1)
table.attach(group.items['bottom-left'], 0, 1, 1, 2)
table.attach(group.items['bottom-center'], 1, 2, 1, 2)
table.attach(group.items['bottom-right'], 2, 3, 1, 2)

class AlignmentGroupSync(object):
    def __init__(self, group):
        self.group = group
        self.__pref_changed(prefs, None)
        prefs.connect("changed::osd_halignment", self.__pref_changed)
        prefs.connect("changed::osd_vposition", self.__pref_changed)
        group.connect("changed", self.__gui_changed)

    def __pref_changed(self, prefs, name):
        halign = prefs['osd_halignment']
        valign = prefs['osd_vposition']
        self.group.set_value("-".join((valign, halign)))
        
    def __gui_changed(self, group, value):
        valign, halign = value.split('-')
        prefs['osd_halignment'] = halign
        prefs['osd_vposition'] = valign

AlignmentGroupSync(group)


# Avoid Panels
avoid = gtk.CheckButton(_("A_void panels"))
avoid.show()
ToggleSync(avoid, prefs, "avoid_panels")

vbox = gtk.VBox(False, 6)
vbox.show()
vbox.add(table)
vbox.add(avoid)

container = HIGContainer(_("Alignment"), vbox)
dialog.vbox.add(container)

def dialog_response(dialog, response):
    if response == gtk.RESPONSE_CLOSE:
        dialog.destroy()
    elif response == RESPONSE_TEST:
        osd = bonobo.get_object("OAFIID:GNOME_OSD", "IDL:Bonobo/Application:1.0")
        osd.ref() # AppClient steals one reference
        osd = bonobo.AppClient(osd)
        osd.msg_send("show",
                     [_("This is a %s %s test sent from the preferences dialog")
                      % (gnome_osd_conf.PACKAGE, gnome_osd_conf.VERSION)])

dialog.connect("response", dialog_response)
dialog.connect("destroy", lambda *args: gtk.main_quit())
dialog.show()

gtk.main()
