# -*- mode: python; coding: utf-8 -*-
#
# Pigment Python tools
#
# Copyright © 2006, 2007, 2008 Fluendo Embedded S.L.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import pgm

from pgm.graph.group import Group
from pgm.graph.image import Image
from pgm.utils import image as image_utils
from pgm.widgets import const

class SlicedImage(Group):

    def __init__(self, orientation=const.VERTICAL, top_file=None,
                 bottom_file=None, body_file=None):
        self._size = (0,0)
        Group.__init__(self)

        # invisble image used to handle mouse related signals, mainly.
        self._invisible = Image()
        self.add(self._invisible)
        self._invisible.size = self.size

        self._body = Image()
        self.add(self._body)
        self._body.bg_color = (255, 0, 0, 0)
        self._body.layout = pgm.IMAGE_FILLED
        self._body.interp = pgm.IMAGE_NEAREST
        self._body.connect("pixbuf-loaded", self._body_loaded)
        self._body_loaded = False

        self._bottom = Image()
        self.add(self._bottom)
        self._bottom.layout = pgm.IMAGE_SCALED
        self._bottom.layout = pgm.IMAGE_FILLED
        self._bottom.bg_color = (0, 255, 0, 0)
        self._bottom.interp = pgm.IMAGE_NEAREST
        self._bottom.connect("pixbuf-loaded", self._bottom_loaded)
        self._bottom_loaded = False

        self._top = Image()
        self.add(self._top)
        self._top.layout = pgm.IMAGE_SCALED
        self._top.layout = pgm.IMAGE_FILLED
        self._top.bg_color = (0, 0, 255, 0)
        self._top.interp = pgm.IMAGE_NEAREST
        self._top.connect("pixbuf-loaded", self._top_loaded)
        self._top_loaded = False

        self._orientation = orientation
        self.top_file = top_file
        self.bottom_file = bottom_file
        self.body_file = body_file
        
    def connect(self, signal_name, callback, *args, **kw):
        # Forward signal connections to self._invisible
        return self._invisible.connect(signal_name, callback, *args, **kw)

    def orientation__set(self, orientation):
        self._orientation = orientation
        self._compute_layout()

    def orientation__get(self):
        return self._orientation

    def size__set(self, size):
        self._size = size
        self._compute_layout()

    def size__get(self):
        return self._size

    def width__set(self, width):
        self._size = (width, self._size[1])
        self._compute_layout()

    def width__get(self):
        return self._size[0]

    def height__set(self, height):
        #Group.height__set(self, height)
        self._size = (self._size[0], height)
        self._compute_layout()
        
    def width__get(self):
        return self._size[0]

    def _compute_layout(self):
        if self._top_loaded and self._body_loaded and self._bottom_loaded:
            self._top_layout()
            self._body_layout()
            self._bottom_layout()
            self._top.visible = True
            self._body.visible = True
            self._bottom.visible = True

    def _bottom_loaded(self, img):
        self._bottom_loaded = True
        self._compute_layout()

    def _top_loaded(self, img):
        self._top_loaded = True
        self._compute_layout()

    def _body_loaded(self, img):
        self._body_loaded = True
        self._compute_layout()

    def _bottom_layout(self):
        if self._orientation == const.VERTICAL:
            self._bottom.alignment = pgm.IMAGE_BOTTOM_CENTER
            self._bottom.width = self.width

            y = self._body.height + self._body.y
            self._bottom.position = (0, y, 0)
            self._bottom.height = image_utils.get_height_from_par(self._bottom)
        else:
            self._bottom.alignment = pgm.IMAGE_RIGHT
            self._bottom.height = self.height
            x = self._body.width + self._body.x
            self._bottom.position = (x, 0, 0)
            self._bottom.width = image_utils.get_width_from_par(self._bottom)

    def _top_layout(self):
        self._top.position = (0, 0, 0)

        if self._orientation == const.VERTICAL:
            self._top.alignment = pgm.IMAGE_TOP_CENTER
            self._top.width = self.width

            self._top.height = image_utils.get_height_from_par(self._top)
        else:
            self._top.alignment = pgm.IMAGE_LEFT
            self._top.height = self.height

            self._top.width = image_utils.get_width_from_par(self._top)

    def _body_layout(self):
        if self._orientation == const.VERTICAL:
            self._body.width = self.width

            # assume that self._bottom.height == self._top.height
            self._body.height = self.height - self._top.height*2.0# - self._bottom.height
            self._body.position = (0, self._top.height, 0)
        else:
            self._body.height = self.height

            # assume that self._bottom.width == self._top.width
            self._body.width = self.width - self._top.width*2.0# - self._bottom.width
            self._body.position = (self._top.width, 0, 0)

    def top_file__set(self, top_file):
        if top_file is not None:
            self._top.set_from_file(top_file)

    def bottom_file__set(self, bottom_file):
        if bottom_file is not None:
            self._bottom.set_from_file(bottom_file)

    def body_file__set(self, body_file):
        if body_file is not None:
            self._body.set_from_file(body_file)


if __name__ == "__main__":
    import os, os.path

    def on_key_press(viewport, event):
        if event.type == pgm.KEY_PRESS:
            # quit on q or ESC
            if event.keyval == pgm.keysyms.q or \
               event.keyval == pgm.keysyms.Escape:
                pgm.main_quit()
            
            elif event.keyval == pgm.keysyms.f:
                viewport.fullscreen = not viewport.fullscreen

            elif event.keyval == pgm.keysyms.h:
                widget.width += 0.1

            elif event.keyval == pgm.keysyms.n:
                widget.width -= 0.1

            elif event.keyval == pgm.keysyms.g:
                widget.height += 0.1

            elif event.keyval == pgm.keysyms.b:
                widget.height -= 0.1

    def on_delete(viewport, event):
        pgm.main_quit()

    # OpenGL viewport creation
    factory = pgm.ViewportFactory('opengl')
    gl = factory.create()
    gl.title = 'Sliced image widget'

    # Canvas and image drawable creation
    canvas = pgm.Canvas()

    # Bind the canvas to the OpenGL viewport
    gl.set_canvas(canvas)
    gl.show()

    dir = "/home/ben/dev/elisa/elisa/plugins/bad/raval_frontend"
    top = "theme/selector-left.png"
    bottom = "theme/selector-right.png"
    body = "theme/selector-body.png"

    widget = SlicedImage(orientation=const.HORIZONTAL)
    widget.top_file = os.path.join(dir, top)
    widget.bottom_file = os.path.join(dir, bottom)
    widget.body_file = os.path.join(dir, body)
    widget.width = canvas.width/2.0
    widget.height = canvas.height/2.0
    widget.x = (canvas.width - widget.width)/2.0
    widget.y = (canvas.height - widget.height)/2.0
    widget.visible = True
    widget.canvas = canvas

    # Let's start a mainloop
    gl.connect('key-press-event',
               on_key_press)
    gl.connect('delete-event', on_delete)
    pgm.main()
