#!/usr/bin/env python
# -*-  coding: UTF-8 -*-

# 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.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
# Authors: Patrick Niklaus (marex@opencompositing.org)
# Copyright (C) 2007 Patrick Niklaus

import shutil
import os
import subprocess
import pygtk
import gtk
import gobject
import gtk.gdk as gdk
import gtk.glade as glade
import cairo
import compizconfig as ccs
import ccm
import locale
import gettext
from optparse import OptionParser
locale.setlocale(locale.LC_ALL, "")
_ = gettext.gettext

DataDir = '/usr/local/share/simple-ccsm/'
Profiles = [\
"Low Effects", "Easy to the eyes", "Medium Effects", "High Effects", "Hollywood got nothing"
]
# TODO Write descriptions
Descriptions = {\
'Low Effects': "",
'Easy to the eyes': "",
'Medium Effects': "",
'High Effects': "",
'Hollywood got nothing': ""
}

# Switcher keybinding
SwitcherKey = "<Alt>Tab"

# Since there seems no way to get the untranslated names,
# we need to keep a list here.
CloseOpenEffectNames = [\
'None', 'Random', 'Airplane', 'Beam Up', 'Burn', 'Curved Fold',
'Domino', 'Dream', 'Explode', 'Fade', 'Fold', 'Glide 1', 'Glide 2',
'Horizontal Folds', 'Leaf Spread','Magic Lamp', 'Razr', 'Sidekick',
'Skewer', 'Vacuum', 'Wave', 'Zoom'
]

MinimizeEffectNames = [\
'None', 'Random', 'Airplane', 'Beam Up', 'Burn', 'Curved Fold',
'Domino', 'Dream', 'Explode', 'Fade', 'Fold', 'Glide 1', 'Glide 2',
'Horizontal Folds', 'Leaf Spread','Magic Lamp', 'Razr', 'Sidekick',
'Skewer', 'Zoom'

]

# 0 to 10 points
AnimationRatings = {\
'None': 0,
'Random': 5,
'Airplane': 10,
'Beam Up': 7,
'Burn': 8,
'Curved Fold': 4,
'Domino': 6,
'Dream': 6,
'Explode': 7,
'Fade': 3,
'Fold': 6,
'Glide 1': 6,
'Glide 2': 6,
'Horizontal Folds': 6,
'Leaf Spread': 8,
'Magic Lamp': 10,
'Razr': 8,
'Sidekick': 6,
'Skewer': 6,
'Vacuum': 8,
'Wave': 8,
'Zoom': 4
}

gtk.glade.bindtextdomain("simple-ccsm", "/usr/local/share/locale")
gettext.bindtextdomain("simple-ccsm", "/usr/local/share/locale")
gettext.textdomain("simple-ccsm")

# Possible are 77 points (cube and wall conflict)
EffectPluginRatings = {\
'wobbly': 10,
'cube': 3,
'wall': 2,
'expo': 5,
'blur': 8,
'mblur': 10,
'3d': 8,
'water': 10,
'firepaint': 7,
'shift': 5,
'scale': 3,
'cubereflex': 8
}

Pages = {
'profile': 0,
'animations': 1,
'desktop': 2,
'accessibility': 3
}

# Possible are 2 points
AccessibilityPlugins = {\
'zoom': 1,
'ezoom': 1,
'colorfilter': 1
}

AnimationSettings = {
'openAnimationBox': "open_effects",
'closeAnimationBox': "close_effects",
'minimizeAnimationBox': "minimize_effects"
}

# Utility Functions
def EnablePlugin(plugin, active):
    # attempt to resolve conflicts...
    conflicts = plugin.Enabled and plugin.DisableConflicts or plugin.EnableConflicts
    conflict = ccm.PluginConflict(plugin, conflicts, autoResolve=True)
    if conflict.Resolve():
        plugin.Enabled = active
    else:
        return False

    plugin.Context.Write()

    return True

def SetupBoxModel(box):
    if not box.get_model():
        store = gtk.ListStore(gobject.TYPE_STRING)
        box.set_model(store)
        cell = gtk.CellRendererText()
        box.pack_start(cell, True)
        box.add_attribute(cell, 'text', 0)
    else:
        box.get_model().clear()

class DesktopPreview(gtk.Widget):
    def __init__(self, size=(0,0)):
        gtk.Widget.__init__(self)

        self.size = size
        self.default_desktop_height = 30
        self.default_desktop_width = 40
        self.desktop_height = 30
        self.desktop_width = 40
        self.desktop_space = 5
        self.line_width = 1.0

        self.set_flags(self.flags() | gtk.NO_WINDOW)

    def set_value(self, size):
        self.size = size
        self.queue_resize()

    def get_value(self):
        return self.size
    
    def do_unrealize(self):
        self.window.destroy()

    def do_size_request(self, req):
        req.width = (self.default_desktop_width+self.desktop_space)*4
        req.height = (self.default_desktop_height+self.desktop_space)*2

    def do_size_allocate(self, allocation):
        self.allocation = allocation

        width = self.allocation.width
        height = self.allocation.height
        self.desktop_width = (width / self.size[0]) - self.desktop_space
        self.desktop_height = (self.desktop_width * 3.0) / 4.0
        factor = ((height / self.size[1]) - self.desktop_space) / self.desktop_height
        #factor = height / ((self.desktop_height + self.desktop_space) * self.size[1])

        if factor < 1.0:
            self.desktop_width = int(int(self.desktop_width) * factor)
            self.desktop_height = int(int(self.desktop_height) * factor)
        
    def do_expose_event(self, event):
        cr = self.window.cairo_create()
        
        fg = self.style.bg[gtk.STATE_SELECTED]
        dark = self.style.fg[gtk.STATE_NORMAL]

        x = self.allocation.x + self.line_width / 2.0
        y = self.allocation.y + self.line_width / 2.0
        for i in range(self.size[1]):
            for j in range(self.size[0]):
                cr.set_source_rgb(fg.red/65535.0,
                              fg.green/65535.0,
                              fg.blue/65535.0)

                cr.rectangle(x, y, self.desktop_width, self.desktop_height)
                cr.fill_preserve()
                
                cr.set_line_width(self.line_width)
                cr.set_source_rgb(dark.red/65535.0,
                              dark.green/65535.0,
                              dark.blue/65535.0)
                cr.stroke()

                x += self.desktop_width + self.desktop_space

            y += self.desktop_height + self.desktop_space 
            x = self.allocation.x + self.line_width / 2.0

class StarScale(gtk.Widget):
    def __init__(self, stars=0.0, max=5):
        gtk.Widget.__init__(self)

        self.stars = stars
        self.max = max
        self.star_size = 16
        self.star_space = 5

        self.image_star = cairo.ImageSurface.create_from_png("%s/images/star.png" % DataDir)
        self.image_dark = cairo.ImageSurface.create_from_png("%s/images/star_dark.png" % DataDir)
        self.surface_star = None
        self.surface_dark = None
        self.surface      = None

        self._size_changed = False
        
        self.set_flags(self.flags() | gtk.NO_WINDOW)

    def set_value(self, stars):
        self.stars = stars
        if self.surface:
            self.draw_surface()

    def set_max(self, max):
        self.max = max
        self.queue_resize()

    def get_value(self):
        return self.stars
    
    def get_max(self):
        return self.max

    def do_size_request(self, req):
        req.height = self.star_size
        req.width = (self.star_size+self.star_space)*self.max
        self._size_changed = True

    def draw_sources(self):
        width = self.allocation.width
        height = self.allocation.height
        self.surface_star = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        self.surface_dark = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

        data = ((self.surface_star, self.image_star), (self.surface_dark, self.image_dark))

        for target, source in data:
            cr = cairo.Context(target)
            x = 0
            for i in range(self.max):
                cr.set_source_surface(source, x, 0)
                cr.rectangle(x, 0, self.star_size, self.star_size)
                cr.fill()
                x += self.star_size + self.star_space

    def draw_surface(self):
        if not self.surface_dark or not self.surface_star or self._size_changed:
            self.draw_sources()
            self._size_changed = False

        width = self.allocation.width
        height = self.allocation.height
        self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        cr = cairo.Context(self.surface)

        width = (self.star_size+self.star_space)*self.max

        q = (self.max - self.stars) / self.max
        cr.set_source_surface(self.surface_dark)
        cr.rectangle(width - q*width, 0, q*width, self.star_size)
        cr.fill()

        q = self.stars / self.max
        cr.set_source_surface(self.surface_star)
        cr.rectangle(0, 0, q*width, self.star_size)
        cr.fill()

    def do_expose_event(self, event):
        if not self.surface or self._size_changed:
            self.draw_surface()

        x = self.allocation.x
        y = self.allocation.y
        width  = self.allocation.width
        height = self.allocation.height

        cr = self.window.cairo_create()
        cr.set_source_surface(self.surface, x, y)
        cr.rectangle(x, y, width, height)
        cr.fill()


gobject.type_register(StarScale)
gobject.type_register(DesktopPreview)

class CheckImage(gtk.HBox):
    def __init__(self, value=False):
        gtk.HBox.__init__(self)
        self.image = gtk.Image()
        self.label = gtk.Label()

        self.set_spacing(5)

        self.pack_start(self.image, False, False)
        self.pack_start(self.label, False, False)

        self.value = value

        self.image.props.xalign = 0.0
        self.label.props.xalign = 0.0

        self.update()
    
    def set_value(self, value):
        self.value = value

        self.update()

    def get_value(self):
        return self.value
    
    def update(self):
        size = gtk.ICON_SIZE_BUTTON
        if self.value:
            self.image.set_from_stock(gtk.STOCK_APPLY, size)
            self.label.set_text(_("Enabled"))
        else:
            self.image.set_from_stock(gtk.STOCK_DIALOG_ERROR, size)
            self.label.set_text(_("Disabled"))

class ProfilePage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context

        # Check List
        self.EffectStars = StarScale()
        self.AnimationStars = StarScale()
        self.AccessibilityCheck = CheckImage()
        effectsAlign = self.GladeXML.get_widget("effectsAlignment")
        effectsAlign.add(self.EffectStars)
        animationAlign = self.GladeXML.get_widget("animationsAlignment")
        animationAlign.add(self.AnimationStars)
        accessibilityAlign = self.GladeXML.get_widget("accessibilityAlignment")
        accessibilityAlign.add(self.AccessibilityCheck)

        # Desktop Label
        self.DesktopLayout = "%s"
        self.DesktopLabel = self.GladeXML.get_widget("desktopLabel")

        self.GladeXML.signal_autoconnect(self)

    def UpdateDesktopPlugins(self):
        self.DesktopPlugins = {}
        for plugin in self.Context.Plugins.values():
            if "largedesktop" in plugin.Features:
                self.DesktopPlugins[plugin.ShortDesc] = plugin
    
    def SetDesktopLabel(self):
        for shortDesc, plugin in self.DesktopPlugins.items():
            if plugin.Enabled:
                self.DesktopLabel.set_markup(self.DesktopLayout % shortDesc)
                break

    def SetEffectRating(self, widget=None):
        rating = 0.0

        for pluginName, points in EffectPluginRatings.items():
            if not pluginName in self.Context.Plugins:
                continue
            plugin = self.Context.Plugins[pluginName]
            if plugin.Enabled:
                rating += points

        rating = (rating / 77.0) * 5

        self.EffectStars.set_value(rating)

    def SetAnimationRating(self, widget=None):
        names = {
            'close_effects': CloseOpenEffectNames,
            'open_effects': CloseOpenEffectNames,
            'minimize_effects': MinimizeEffectNames
        }
        plugin = self.Context.Plugins['animation']

        rating = 0.0
        for box, settingName in AnimationSettings.items():
            box = self.GladeXML.get_widget(box)
            if not box.get_model():
                continue
            text = box.get_active_text()
            setting = plugin.Screens[0][settingName]
            value = setting.Value[0]
            name = names[settingName][value]
            rating += AnimationRatings[name]

        if not plugin.Enabled:
            rating = 0.0
        if self.Context.Plugins['fade'].Enabled:
            rating += AnimationRatings['Fade'] * 2
        if self.Context.Plugins['minimize'].Enabled:
            rating += AnimationRatings['Zoom'] / 3

        rating = rating / (10 * len(AnimationSettings)) * 5

        self.AnimationStars.set_value(rating)

    def CheckAccessibility(self, widget=None):
        rating = 0.0
        for name in AccessibilityPlugins.keys():
            if name in self.Context.Plugins and self.Context.Plugins[name].Enabled:
                rating += AccessibilityPlugins[name]

        self.AccessibilityCheck.set_value(rating >= 2.0)

    def Update(self):
        self.UpdateDesktopPlugins()
        self.SetDesktopLabel()
        self.SetEffectRating()
        self.SetAnimationRating()
        self.CheckAccessibility()

class AnimationPage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context
        self.Block    = 0

        self.GladeXML.signal_autoconnect(self)

    def EnableAnimationsChanged(self, widget):
        if self.Block > 0:
            return

        plugin = self.Context.Plugins['animation']
        EnablePlugin(plugin, widget.get_active())
    
    def AnimationBoxChanged(self, widget):
        if self.Block > 0:
            return

        name = widget.get_name()
        settingName = AnimationSettings[name]

        text = widget.get_active_text()
        plugin = self.Context.Plugins['animation']
        setting = plugin.Screens[0][settingName]
        value = setting.Value
        if len(value) >= 1:
            value[0] = setting.Info[1][2][text]
            setting.Value = value
            self.Context.Write()
        else:
            for setting in plugin.Groups[setting.Group][setting.SubGroup].Screens[0].values():
                setting.Reset()
            self.Context.Write()
            self.AnimationBoxChanged(widget, settingName)

    def SetEnableAnimations(self):
        plugin = self.Context.Plugins['animation']
        widget = self.GladeXML.get_widget("enableAnimations")
        widget.set_active(plugin.Enabled)
    
    def FillAnimationBoxes(self):
        plugin = self.Context.Plugins['animation']
        
        for boxName, settingName in AnimationSettings.items():
            box = self.GladeXML.get_widget(boxName)
            setting = plugin.Screens[0][settingName]
            items = sorted(setting.Info[1][2].items(), key=ccm.EnumSettingKeyFunc)
            SetupBoxModel(box)
            for key, value in items:
                box.append_text(key)
            if len(setting.Value):
                value = setting.Value[0]
                box.set_active(value)
            else:
                box.set_active(0)

    def Update(self):
        self.Block += 1
        self.SetEnableAnimations()
        self.FillAnimationBoxes()
        self.Block -= 1

class EffectPage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context
        self.Block    = 0

        self.GladeXML.signal_autoconnect(self)

    def UpdateSwitcherPlugins(self):
        self.SwitcherPlugins = {}
        for pluginName in ('switcher', 'shift', 'ring'):
            if pluginName in self.Context.Plugins:
                plugin = self.Context.Plugins[pluginName]
                if pluginName == 'shift':
                    self.SwitcherPlugins[_("%s (Cover)") % plugin.ShortDesc] = plugin
                    self.SwitcherPlugins[_("%s (Flip)") % plugin.ShortDesc] = plugin
                else:
                    self.SwitcherPlugins[plugin.ShortDesc] = plugin

        self.SwitcherKeySettings = {}
        for pluginName in ('switcher', 'shift', 'ring'):
            plugin = self.Context.Plugins[pluginName]
            setting = plugin.Display['next_key']
            self.SwitcherKeySettings[pluginName] = setting

    def EffectPluginChanged(self, widget):
        if self.Block > 0:
            return

        name = widget.get_name()
        effectPlugins = {
        'enableScale': "scale",
        'enableWobbly': "wobbly",
        'enableBlur': "blur",
        'enableExpo': "expo"
        }
        pluginName = effectPlugins[name]

        plugin = self.Context.Plugins[pluginName]
        value  = widget.get_active()

        EnablePlugin(plugin, value)
 
    def SwitcherBoxChanged(self, widget):
        if self.Block > 0:
            return

        text = widget.get_active_text()

        for shortDesc, plugin in self.SwitcherPlugins.items():
            if text != shortDesc:
                EnablePlugin(plugin, False)
                setting = self.SwitcherKeySettings[plugin.Name]
                if not setting.IsDefault and setting.DefaultValue != SwitcherKey:
                    setting.Reset()

        self.Context.Write()

        for shortDesc, plugin in self.SwitcherPlugins.items():
            if text == shortDesc:
                EnablePlugin(plugin, True)

                # Set default key binding to Alt-Tab
                setting = self.SwitcherKeySettings[plugin.Name]
                settings = self.SwitcherKeySettings.values()
                conflict = ccm.ActionConflict(setting, key=SwitcherKey, settings=settings, autoResolve=True)
                if conflict.Resolve(ccm.GlobalUpdater):
                    setting.Value = SwitcherKey

                # Exception for shift, since it has 2 modes
                if plugin.Name == 'shift':
                    setting = plugin.Screens[0]['mode']

                    if text.find(_("Cover")) != -1:
                        setting.Value = 0
                    elif text.find(_("Flip")) != -1:
                        setting.Value = 1

        self.Context.Write()

    def SetEffectPlugins(self):
        widgets = {
        'scale': "enableScale",
        'wobbly': "enableWobbly",
        'blur': "enableBlur",
        'expo': "enableExpo"
        }

        for pluginName, widgetName in widgets.items():
            widget = self.GladeXML.get_widget(widgetName)
            plugin = self.Context.Plugins[pluginName]
            widget.set_active(plugin.Enabled)

    def FillSwitcherBox(self):
        box = self.GladeXML.get_widget("switcherPluginChooser")
        SetupBoxModel(box)

        i = 0
        for shortDesc, plugin in self.SwitcherPlugins.items():
            box.append_text(shortDesc)
            if plugin.Enabled:
                if plugin.Name == 'shift':
                    modes = [_("Cover"), _("Flip")]
                    setting = plugin.Screens[0]['mode']
                    mode = modes[setting.Value]
                    if shortDesc.find(mode) != -1:
                        box.set_active(i)
                else:
                    box.set_active(i)
            i += 1

    def Update(self):
        self.Block += 1
        self.SetEffectPlugins()
        self.UpdateSwitcherPlugins()
        self.FillSwitcherBox()
        self.Block -= 1

class DesktopPage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context
        self.Block    = 0

        self.GladeXML.signal_autoconnect(self)

        # Preview Widget
        self.DesktopPreview = DesktopPreview()
        previewAlign = self.GladeXML.get_widget("previewAlignment")
        previewAlign.add(self.DesktopPreview)

    def UpdateDesktopPlugins(self):
        self.DesktopPlugins = {}
        for plugin in self.Context.Plugins.values():
            if "largedesktop" in plugin.Features:
                self.DesktopPlugins[plugin.ShortDesc] = plugin
    
    def DesktopSizeChanged(self, widget):
        if self.Block > 0:
            return

        name = widget.get_name()
        settings = {
        'horizontalDesktops': "hsize",
        'verticalDesktops': "vsize"
        }
        settingName = settings[name]

        value = widget.get_value()
        self.Context.Plugins['core'].Screens[0][settingName].Value = value
        self.Context.Write()
        self.SetDesktopPreview()

    def AppearenceBoxChanged(self, widget):
        if self.Block > 0:
            return

        text = widget.get_active_text()

        for shortDesc, plugin in self.DesktopPlugins.items():
            if text != shortDesc:
                EnablePlugin(plugin, False)

        self.Context.Write()

        for shortDesc, plugin in self.DesktopPlugins.items():
            if text == shortDesc:
                plugin.Enabled = True
                # exception for cube, since it requires rotate
                if plugin.Name == 'cube':
                    setting = self.Context.Plugins['core'].Screens[0]['vsize']
                    setting.Value = 1 # Cube can only use 1 vertical viewport
                    EnablePlugin(self.Context.Plugins['rotate'], True)

        self.Context.Write()
        self.SetDesktopSize()

    def SetDesktopPreview(self):
        hsize = self.Context.Plugins['core'].Screens[0]["hsize"].Value
        vsize = self.Context.Plugins['core'].Screens[0]["vsize"].Value
        self.DesktopPreview.set_value((hsize, vsize))

    def SetDesktopSize(self):
        scales = {"horizontalDesktops" : "hsize",
                  "verticalDesktops"   : "vsize"}

        for widgetName, settingName in scales.items():
            widget = self.GladeXML.get_widget(widgetName)
            setting = self.Context.Plugins['core'].Screens[0][settingName]
            widget.set_value(setting.Value)

    def FillAppearenceBox(self):
        box = self.GladeXML.get_widget("desktopPluginChooser")
        SetupBoxModel(box)

        i = 0
        for shortDesc, plugin in self.DesktopPlugins.items():
            box.append_text(shortDesc)
            if plugin.Enabled:
                box.set_active(i)
            i += 1

    def Update(self):
        self.Block += 1
        self.SetDesktopPreview()
        self.SetDesktopSize()
        self.UpdateDesktopPlugins()
        self.FillAppearenceBox()
        self.Block -= 1

class ZoomPage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context
        self.Block    = 0

        self.GladeXML.signal_autoconnect(self)

        # Zoom Keybindings
        self.Widgets = {}
        self.Settings = {
        # identifier  -   plugin   -    setting     -      container
        'screenZoomIn':  ('ezoom', 'zoom_in',         'screenZoomBox'),
        'screenZoomOut': ('ezoom', 'zoom_out',        'screenZoomBox'),
        'areaZoomIn':    ('mag',   'zoom_in_button',  'areaZoomBox'),
        'areaZoomOut':   ('mag',   'zoom_out_button', 'areaZoomBox')
        }

    def ZoomChanged(self, widget):
        if self.Block > 0:
            return
        
        available = {}
        for name in ('ezoom', 'zoom', 'mag'):
            if name in self.Context.Plugins:
                plugin = self.Context.Plugins[name]
                available[name] = plugin
        
        widget = self.GladeXML.get_widget("enableZoom")
        if 'ezoom' in available:
            available['ezoom'].Enabled = widget.get_active()
        elif 'zomm' in available:
            available['zoom'].Enabled = widget.get_active()

        widget = self.GladeXML.get_widget("enableMag")
        if 'mag' in available:
            available['mag'].Enabled = widget.get_active()

        self.Context.Write()
    
    def SetZoom(self):
        for identifier, data in self.Settings.items():
            pluginName, settingName, containerName = data

            if pluginName not in self.Context.Plugins:
                continue

            if identifier not in self.Widgets:
                plugin    = self.Context.Plugins[pluginName]
                setting   = plugin.Display[settingName]
                widget    = ccm.MakeSetting(setting)
                container = self.GladeXML.get_widget(containerName)
                container.pack_start(widget.EBox)
                if not plugin.Enabled:
                    container.set_sensitive(False)
                self.Widgets[identifier] = widget

            self.Widgets[identifier].Read()

        available = {}
        for name in ('ezoom', 'zoom', 'mag'):
            if name in self.Context.Plugins:
                plugin = self.Context.Plugins[name]
                available[name] = plugin

        widget = self.GladeXML.get_widget("enableZoom")
        widget.set_sensitive(True)
        if 'ezoom' in available:
            plugin = available['ezoom']
            widget.set_active(plugin.Enabled)
        elif 'zoom' in available:
            plugin = available['zoom']
            widget.set_active(plugin.Enabled)
        else:
            widget.set_sensitive(False)
            widget.set_active(False)

        widget = self.GladeXML.get_widget("enableMag")
        widget.set_sensitive(True)
        if 'mag' in available:
            plugin = available['mag']
            widget.set_active(plugin.Enabled)
        else:
            widget.set_sensitive(False)
            widget.set_active(False)

    def Update(self):
        self.Block += 1
        self.SetZoom()
        self.Block -= 1

class EdgePage:
    def __init__(self, context, gladeXML):
        self.GladeXML = gladeXML
        self.Context  = context
        self.Block    = 0

        align = self.GladeXML.get_widget("edgesAlignment")
        self.EdgeSelector = ccm.GlobalEdgeSelector(self.Context)
        align.add(self.EdgeSelector)

    def Update(self):
        pass

class MainWin:
    def __init__(self, context, page = -1):
        self.GladeXML = glade.XML(DataDir + "simple-ccsm.glade", domain="simple-ccsm")
        self.GladeXML.signal_autoconnect(self)

        self.Context = context
        self.Block = 0

        if page != -1 and page in Pages:
            notebook = self.GladeXML.get_widget("notebook1")
            notebook.set_current_page (Pages[page])

        # Window
        window = self.GladeXML.get_widget("mainWin")

        # Icon
        theme = gtk.icon_theme_get_default()
        iconList = (\
            theme.load_icon("simple-ccsm", 16, 0),
            theme.load_icon("simple-ccsm", 32, 0),
            theme.load_icon("simple-ccsm", 48, 0),
        )
        window.set_icon_list(*iconList)

        # Profile Chooser
        self.ProfileChooser = self.GladeXML.get_widget("profileChooser")

        # Pages
        self.AnimationPage = AnimationPage(self.Context, self.GladeXML)
        self.EffectPage    = EffectPage(self.Context, self.GladeXML)
        self.DesktopPage   = DesktopPage(self.Context, self.GladeXML)
        self.ZoomPage      = ZoomPage(self.Context, self.GladeXML)
        self.ProfilePage   = ProfilePage(self.Context, self.GladeXML)
        self.EdgePage      = EdgePage(self.Context, self.GladeXML)

        self.Update()
        window.show_all()

    def Update(self):
        self.Context.Read()

        self.AnimationPage.Update()
        self.EffectPage.Update()
        self.DesktopPage.Update()
        self.ZoomPage.Update()
        self.ProfilePage.Update()
        self.EdgePage.Update()

        self.SetProfile()

    def OpenAdvanced(self, widget):
        notebook = self.GladeXML.get_widget("notebook")
        page = notebook.get_current_page()
        child = notebook.get_nth_page(page)
        name = notebook.get_tab_label_text(child)
        options = {
        _("Profile"): "",
        _("Animations"): "--plugin animation",
        _("Desktop"): "--category Desktop",
        _("Effects"): "--category Effects",
        _("Zoom"): "--plugin ezoom"
        }
        option = options[name]
        cmd = "ccsm %s" % option
        cmd = cmd.split(" ")
        subprocess.Popen(cmd)

    def ApplyProfile(self, widget):
        profile = self.ProfileChooser.get_active_text()

        if not profile in self.Context.Profiles.keys():
            profilePath = "%s/profiles/%s.profile" % (DataDir, profile)
            self.Context.CurrentProfile = ccs.Profile(self.Context, profile)
            self.Context.Read()
            self.Context.UpdateProfiles()
            self.Context.Import(profilePath)
        else:
            if profile == _("Default"):
                self.Context.ResetProfile()
            else:
                self.Context.UpdateProfiles()
                self.Context.CurrentProfile = self.Context.Profiles[profile]

        self.Update()
        self.Context.Write()

    def SetProfile(self):
        SetupBoxModel(self.ProfileChooser)

        self.Context.UpdateProfiles()

        self.ProfileChooser.append_text(_("Default"))
        for profile in Profiles:
            self.ProfileChooser.append_text(profile)

        current = self.Context.CurrentProfile.Name or _("Default")
        if current in Profiles:
            pos = Profiles.index(current) + 1
            self.ProfileChooser.set_active(pos)
        elif current != _("Default"):
            self.ProfileChooser.prepend_text(current)
            self.ProfileChooser.set_active(0)
        else:
            self.ProfileChooser.set_active(0)

    def Quit(self, widget):
        gtk.main_quit()

if __name__ == "__main__":
    context = ccs.Context()
    page = -1
    parser = OptionParser()
    parser.add_option("-p", "--page", dest = "page",
		      help = "Directly jump to page PAGE", metavar = "PAGE")
    (options, args) = parser.parse_args()
    if options.page:
        page = options.page
    mainWin = MainWin(context, page)
    gtk.main()
