# -*- coding: utf-8 -*-
    
import time
import gtk

import adesk.plugin as Plg
import adesk.core as Core
import adesk.ui as UI

try:
    import wnck
except:
    Core.logINFO('Plugin "desktop" need python-wnck')
    Core.logINFO(' -- debian/ubuntu : "sudo apt-get install python-wnck"')

class Plugin(Plg.Plugin):
    def __init__(self, bar, settings):
        Plg.Plugin.__init__(self, bar, settings)
        self.settings = settings
        self.can_zoom = True
        self.taskbar = TaskBar(self, bar)

    def onClick(self, widget, event):
        self.taskbar.toggle()

    def resize(self):
        self.set_size_request(self.cfg['icon_size'], self.cfg['icon_size'])

class TaskBar(UI.PopupWindow):
    def __init__(self, plugin, bar):
        UI.PopupWindow.__init__(self, bar, plugin)

        self.workspaces = {}
        self.windows = {}
        self.windows_needing_attention = {}

        mainbox = gtk.HBox(False, 0)
        mainbox.set_spacing(10)
        mainbox.set_border_width(0)
        self.add(mainbox)

        self.container = gtk.HBox(False, 0)
        self.container.set_border_width(4)
        self.container.set_spacing(10)

        #~ frame = gtk.Frame()
        #~ frame.add(self.container)
        mainbox.pack_start(self.container, False, False)

        self.disp = gtk.gdk.display_get_default().get_name()

        screen = wnck.screen_get_default()
        screen.force_update()
        windows = screen.get_windows()

        gtk.gdk.error_trap_push() # silently ignore x errors like a pro

        screen.connect('window-opened', self.window_opened)
        screen.connect('window-closed', self.window_closed)
        screen.connect('workspace-created', self.workspace_add)
        screen.connect('workspace-destroyed', self.workspace_remove)

        for i in range(0, screen.get_workspace_count()):
            self.workspace_add(screen, screen.get_workspace(i))

        for window in windows:
            self.window_opened(screen, window)

        self.pager = wnck.Pager(screen)
        #~ self.pager.connect("scroll-event", self.pager_scroll)

        widget = gtk.Button()
        widget.set_tooltip_text('Show Desktop')
        widget.set_focus_on_click(False)
        widget.set_property('can-focus', False)
        widget.connect("button-release-event", self.showdesktop)
        image = gtk.Image()
        pixbuf = Core.pixbuf_from_file('images/plugins/desktop.png', 24, 24)
        image.set_from_pixbuf(pixbuf)
        widget.add(image)

        frame = gtk.Frame()
        frame.add(self.pager)
        frame.set_size_request(-1, 24)
        mainbox.pack_start(frame, False, False)
        mainbox.pack_end(widget, False, False)
        mainbox.show_all()

        self.screen = screen

    def toggle(self, widget = 0):
        self.resize(1, 1)
        UI.PopupWindow.toggle(self)

    def showdesktop(self, widget, event):
        showing_windows = not self.screen.get_showing_desktop()
        self.screen.toggle_showing_desktop(showing_windows)

    def window_get_icon(self, window):
        return window.get_icon().scale_simple(24, 24, gtk.gdk.INTERP_BILINEAR)

    def workspace_add(self, screen, space):
        workspace = gtk.HBox(False, 0)
        workspace.set_border_width(0)
        workspace.set_spacing(8)

        separator = None

        if len(self.workspaces) > 0:
            separator = gtk.VSeparator()
            self.container.pack_start(separator)
            separator.show()

        self.workspaces[space] = [workspace, separator]

        self.container.pack_start(workspace)
        workspace.show()

    def workspace_remove(self, screen, space):
        self.workspaces[space][0].destroy()
        self.workspaces[space][1].destroy()

        del self.workspaces[space]

    def icon_clicked_cb(self, widget, event):
        window = wnck.window_get(int(widget.get_name()))

        # left click
        if event.button == 1:
            if window.is_minimized():
                window.unminimize(event.get_time())
            window.get_workspace().activate(event.get_time())
            window.activate(event.get_time())
        # right click
        elif event.button == 3:
            if window.is_minimized():
                window.unminimize(event.get_time())
            else:
                window.minimize()
        # middle click
        else:
            if window.is_maximized():
                window.unmaximize()
            else:
                if window.is_minimized():
                    window.unminimize(event.get_time())
                window.maximize()

    def icon_hover_cb(self, widget, event):
        window = wnck.window_get(int(widget.get_name()))
        pbuf = self.window_get_icon(window)
        image = widget.get_children()[0]
        self.hover = image.get_pixbuf()
        image.set_from_pixbuf(pbuf)

    def icon_unhover_cb(self, widget, event):
        image = widget.get_children()[0]
        image.set_from_pixbuf(self.hover)

    def window_add(self, window):
        pbuf = self.window_get_icon(window).copy()
        if window.is_minimized():
            pass
            #~ pbuf = self.pixbuf_tint(pbuf, self.config['minimized_alpha'])
        elif window.is_active():
            self.window_active = window
        else:
            pass
            #~ pbuf = self.pixbuf_tint(pbuf, self.config['inactive_alpha'])

        def window_add(window, workspace):
            icon = gtk.Image()
            icon.set_from_pixbuf(pbuf)
            button = gtk.EventBox()
            button.set_visible_window(False)
            button.set_tooltip_text(window.get_name())

            button.set_name(str(window.get_xid()))
            button.add(icon)
            button.connect('button_release_event', self.icon_clicked_cb)
            button.connect('enter-notify-event', self.icon_hover_cb)
            button.connect('leave-notify-event', self.icon_unhover_cb)

            self.workspaces[workspace][0].pack_start(button)

            # display if necessary! lawl
            if not window.is_skip_pager():
                icon.show()
                button.show()

            return button

        workspace = window.get_workspace()

        buttons = []

        if workspace: buttons.append(window_add(window, workspace))
        else:
            for workspace in self.workspaces: buttons.append(window_add(window, workspace))

        button = buttons[0]
        self.windows[window] = [buttons, window.get_workspace()]

        # XXX: this works only for newly opened windows, fix it
        # (it's because our window has yet to map)
        icon = button.get_children()[0]
        if icon.window:
            x, y = icon.window.get_origin()
            #print "%d %d" % (x, y)
            window.set_icon_geometry(x, y, button.allocation.width, button.allocation.height)


    def window_remove(self, window):
        try:
            wn = self.windows[window]
            for button in wn[0]:
                button.destroy()
        except: pass

    def window_workspace_changed(self, window):
        # xxx: doesn't this lack intelligence?
        self.window_remove(window)
        self.window_add(window)

    def window_name_changed(self, window):
        #~ pass
        buttons = self.windows[window][0]
        for button in buttons:
            button.set_tooltip_text(window.get_name())

    def pixbuf_tint(self, pixbuf, fraction):
        w = pixbuf.get_width()
        h = pixbuf.get_height()
        blank = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
        blank.fill(0)

        pixbuf.composite(blank, 0, 0, w, h, 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, int(fraction * 255.0))
        return blank

    def window_icon_changed(self, window):
        # xxx: doesn't this lack intelligence?
        pos = -1
        if window.get_workspace(): # not sticky
            widget = self.windows[window][0][0]
            pos = widget.get_parent().get_children().index(widget)

        self.window_remove(window)
        self.window_add(window)
        if pos != -1:
            widget = self.windows[window][0][0]
            widget.get_parent().reorder_child(widget, pos)

    def window_opened(self, screen, window):
        if window.is_skip_tasklist():
            return
        window.connect('workspace-changed', self.window_workspace_changed)
        window.connect('name-changed', self.window_name_changed)
        window.connect('icon-changed', self.window_icon_changed)
        self.window_add(window)

    def window_closed(self, screen, window):
        if window.is_skip_tasklist():
            return
        self.window_remove(window)
        if self.windows.has_key(window):
            del self.windows[window]




