# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.

import pgm

from elisa.plugins.pigment.graph.node import Node
from elisa.plugins.pigment.graph.image import Image
from elisa.plugins.pigment.widgets.widget import Widget
from elisa.plugins.pigment.widgets.theme import ValueWithUnit


class PiecePanel(Widget):
    """
    DOCME
    """

    pieces = ["top_left",
              "top_middle",
              "top_right",
              "middle_left",
              "middle_middle",
              "middle_right",
              "bottom_left",
              "bottom_middle",
              "bottom_right"]

    # DOCME
    top_height = ValueWithUnit(0, "px")
    bottom_height = ValueWithUnit(0, "px")
    left_width = ValueWithUnit(0, "px")
    right_width = ValueWithUnit(0, "px")

    def __init__(self):
        super(PiecePanel, self).__init__()
        # whether or not _compute_border_sizes has been called before
        self._sizes_computed = False
        self._create_widgets()
        self.update_style_properties(self.style.get_items())

    def _create_widgets(self):
        def create_piece():
            piece = Image()
            self.add(piece)
            piece.bg_a = 0
            piece.layout = pgm.IMAGE_FILLED
            piece.interp = pgm.IMAGE_NEAREST
            piece.visible = True
            return piece

        for name in self.pieces:
            piece = create_piece()
            setattr(self, name, piece)

    # Overridden from Group

    def regenerate(self):
        self._update_size()
        self._layout()
        super(PiecePanel, self).regenerate()

    def do_mapped(self):
        self._update_size()
        self._layout()

    def update_style_properties(self, props=None):
        super(PiecePanel, self).update_style_properties(props)
        if "top_height" in props or "bottom_height" in props or \
           "left_width" in props or "right_width" in props:
            self._update_size()
            self._layout()

    def clean(self):
        result = super(PiecePanel, self).clean()
        for name in self.pieces:
            setattr(self, name, None)
        return result

    # x, y, z and position

    def set_absolute_x(self, value):
        Node.set_absolute_x(self, value)
        self._layout()

    def set_absolute_y(self, value):
        Node.set_absolute_y(self, value)
        self._layout()

    def set_absolute_z(self, value):
        Node.set_absolute_z(self, value)
        self._layout()

    def set_absolute_position(self, value):
        Node.set_absolute_position(self, value)
        self._layout()


    def update_absolute_x(self, parent):
        Node.update_absolute_x(self, parent)
        self._layout()

    def update_absolute_y(self, parent):
        Node.update_absolute_y(self, parent)
        self._layout()

    def update_absolute_z(self, parent):
        Node.update_absolute_z(self, parent)
        self._layout()

    def update_absolute_position(self, parent):
        Node.update_absolute_position(self, parent)
        self._layout()


    # width, height and size

    def set_absolute_width(self, value):
        width, height = self.absolute_size
        Node.set_absolute_width(self, value)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)

    def update_absolute_width(self, parent):
        width, height = self.absolute_size
        Node.update_absolute_width(self, parent)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)


    def set_absolute_height(self, value):
        width, height = self.absolute_size
        Node.set_absolute_height(value)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)

    def update_absolute_height(self, parent):
        width, height = self.absolute_size
        Node.update_absolute_height(self, parent)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)


    def set_absolute_size(self, value):
        width, height = self.absolute_size
        Node.set_absolute_size(value)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)

    def update_absolute_size(self, parent):
        width, height = self.absolute_size
        Node.update_absolute_size(self, parent)
        self._update_size()
        self._layout()
        self.emit("resized", width, height)



    def _layout(self):
        if not self.is_mapped:
            return
        if not self._sizes_computed:
            return
        ax, ay, az = self.absolute_position
        aw, ah = self.absolute_size

        # layout_top_row
        self.top_left.set_position(ax, ay, az)

        x = ax + self._left_width
        self.top_middle.set_position(x, ay, az)

        x = ax + aw - self._right_width
        self.top_right.set_position(x, ay, az)

        # layout_middle_row
        y = ay + self._top_height
        self.middle_left.set_position(ax, y, az)

        x = ax + self._left_width
        self.middle_middle.set_position(x, y, az)

        x = ax + aw - self._right_width
        self.middle_right.set_position(x, y, az)

        # layout_bottom_row
        y = ay + ah - self._bottom_height
        self.bottom_left.set_position(ax, y, az)

        x = ax + self._left_width
        self.bottom_middle.set_position(x, y, az)

        x = ax + aw - self._right_width
        self.bottom_right.set_position(x, y, az)

    def _compute_border_sizes(self):
        if isinstance(self.left_width,int) and self.left_width==0:
            self.left_width = ValueWithUnit(0, "px")

        fx, fy = self.get_factors_absolute(self.left_width.unit)
        self._left_width = fx*self.left_width.value

        if isinstance(self.right_width,int) and self.right_width==0:
            self.right_width = ValueWithUnit(0, "px")

        fx, fy = self.get_factors_absolute(self.right_width.unit)
        self._right_width = fx*self.right_width.value

        if isinstance(self.top_height,int) and self.top_height==0:
            self.top_height = ValueWithUnit(0, "px")

        fx, fy = self.get_factors_absolute(self.top_height.unit)
        self._top_height = fy*self.top_height.value

        if isinstance(self.bottom_height,int) and self.bottom_height==0:
            self.bottom_height = ValueWithUnit(0, "px")

        fx, fy = self.get_factors_absolute(self.bottom_height.unit)
        self._bottom_height = fy*self.bottom_height.value
        self._sizes_computed = True

    def _update_size(self):
        if not self.is_mapped:
            return
        self._compute_border_sizes()
        self.top_left.set_size(self._left_width, self._top_height)
        self.top_right.set_size(self._right_width, self._top_height)
        self.bottom_left.set_size(self._left_width, self._bottom_height)
        self.bottom_right.set_size(self._right_width, self._bottom_height)

        self._middle_width = self.absolute_width - self._left_width - self._right_width
        self._middle_height = self.absolute_height - self._top_height - self._bottom_height

        self.top_middle.set_size(self._middle_width, self._top_height)
        self.middle_left.set_size(self._left_width, self._middle_height)
        self.middle_middle.set_size(self._middle_width, self._middle_height)
        self.middle_right.set_size(self._right_width, self._middle_height)
        self.bottom_middle.set_size(self._middle_width, self._bottom_height)



    @classmethod
    def _demo_widget(cls, *args, **kwargs):
        import os.path
        from elisa.plugins.pigment.widgets.const import STATE_SELECTED

        widget = cls()
        widget.set_name("demo")
        widget.position = (50.0, 50.0, 0.0)
        widget.size = (130.0, 40.0)
        widget.state = STATE_SELECTED
        widget.visible = True

        def key_press_event_cb(self, viewport, event, widget):
            increment = 5.0
            if event.keyval == pgm.keysyms.Right:
                widget.width += increment
            elif event.keyval == pgm.keysyms.Left:
                widget.width -= increment
            elif event.keyval == pgm.keysyms.Down:
                widget.height -= increment
            elif event.keyval == pgm.keysyms.Up:
                widget.height += increment
            elif event.keyval == pgm.keysyms.p:
                from elisa.core.utils.profiling import profileit
                @profileit
                def timethat():
                    for i in range(1000):
                        widget._layout()

                timethat()

        widget.connect('key-press-event', key_press_event_cb)

        return widget


if __name__ == '__main__':
    from elisa.plugins.pigment.widgets.panel import PiecePanel
    i = PiecePanel.demo()

    try:
        __IPYTHON__
    except NameError:
        pgm.main()
