# -*- mode: python; coding: utf-8 -*-
#
# Pigment Python tools
#
# Copyright © 2006-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.

from pgm.timing import implicit
from pgm.widgets.grid_ng import Grid

class GridWithSelector(Grid):

    def __init__(self):
        # selector support
        self._selector = None

        Grid.__init__(self)

    def lines__set(self, lines):
        Grid.lines__set(self, lines)
        self._layout_selector()

    def visible_range_size__set(self, visible_range_size):
        Grid.visible_range_size__set(self, visible_range_size)
        self._layout_selector()

    def selected_item__set(self, index):
        lines = int(self._lines)

        if index < 0:
            index = self.selected_item % lines
        elif index >= len(self.widgets):
            column_index = None
            if index >= len(self.widgets):
                column_index = self.selected_item % lines
            else:
                column_index = index % lines
            last_column = len(self.widgets) / lines
            index = lines * last_column + column_index
            if index >= len(self.widgets):
                index = lines * (last_column - 1) + column_index

        Grid.selected_item__set(self, index)
        self._layout_selector()

    def orientation__set(self, orientation):
        Grid.orientation__set(self, orientation)
        self._layout_selector()

    def selector__set(self, selector):
        if self._selector != None:
            self.remove(self._selector)

        self.add(selector)

        self._selector = selector

        self._animated_selector = implicit.AnimatedObject(selector)
        settings = {'duration': 200,
                    'transformation': implicit.DECELERATE}
        self._animated_selector.setup_next_animations(**settings)
        self._animated_selector.mode = implicit.REPLACE

        self._layout_selector()
        self._selector.visible = True

    def selector__get(self):
        return self._selector

    def _layout_selector(self):
        if self._selector == None:
            return

        half_size = (self.visible_range_size - 1.0) / 2.0
        position = -self._animated.visible_range_start + \
                    int(self.selected_item/self._lines)
        line = self.selected_item % self.lines

        # FIXME: this is *not* awsum !1!1
        width = self._widget_width * 1.003
        height = self._widget_height * 1.003
        self._selector.size = (width, height)
            
        lower_limit = half_size
        upper_limit = -self._animated.visible_range_start + \
                      int(len(self)/self._lines) - half_size

        if (position <= lower_limit) or (position >= upper_limit):
            x = self.compute_x(position, line) - 0.01
        else:
            x = self._animated_selector.x

        y = self.compute_y(position, line) - 0.01
        z = 1.0

        if self._selector.visible and self._animated_selector.opacity != 0:
            self._animated_selector.position = (x, y, z)
        else:
            self._selector.position = (x, y, z)

    def do_drag_begin(self, x, y, z, button, time):
        super(GridWithSelector, self).do_drag_begin(x, y, z, button, time)
        self._animated_selector.opacity = 0

    def _stop_deceleration(self):
        super(GridWithSelector, self)._stop_deceleration()
        self._animated_selector.opacity = 255

        
if __name__ == "__main__":
    import pgm
    import gobject
    import gst
    import glob, sys
    from pgm.graph.text import Text
    from pgm.graph.image import Image
    from pgm.graph.group import Group

    from pgm.widgets import const

    def create_text(label):
        txt = Text()
        txt.label = label
        txt.font_family = "Bitstream DejaVu"
        txt.fg_color = (255, 255, 255, 255)
        txt.bg_color = (255, 0, 0, 255)
        txt.ellipsize = pgm.TEXT_ELLIPSIZE_END
        txt.visible = True
        return txt

    def create_img(img_file):
        img = Image()
        img.set_from_file(img_file, 512)
        img.fg_color = (255, 255, 255, 255)
        img.bg_color = (100, 200, 100, 155)
        img.bg_color = (0, 0, 0, 0)
        img.layout = pgm.IMAGE_ZOOMED
        img.visible = True
        return img

    def create_reflection(master_img):
        img = Image()
        img.set_from_image(master_img)
        img.fg_color = (255, 255, 255, 255)
        img.bg_color = (100, 100, 200, 155)
        img.bg_color = (0, 0, 0, 0)
#        img.width = -master_img.width
        img.height = master_img.height/8.0
        img.opacity = 30
#        img.x += master_img.width
        img.layout = pgm.IMAGE_FILLED
        img.y += master_img.height
        img.alignment = pgm.IMAGE_TOP
        img.visible = True
        return img

    def create_video(video_uri):
        img = Image()
        img.fg_color = (255, 255, 255, 255)
        img.bg_color = (0, 0, 0, 0)
        img.alignment = pgm.IMAGE_LEFT
        img.visible = True

        # GStreamer pipeline setup
        pipeline = gst.element_factory_make('playbin')
        sink = gst.element_factory_make('pgmimagesink')
        pipeline.set_property('uri', video_uri)
        pipeline.set_property('video-sink', sink)
        sink.set_property('image', img)
        pipeline.set_state(gst.STATE_PLAYING)

        return img


    def on_key_press(viewport, event, gl, widget):
        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.Page_Up:
                widget.selected_item = 0

            elif event.keyval == pgm.keysyms.Page_Down:
                widget.selected_item = len(widget) - 1

            elif event.keyval == pgm.keysyms.h:
                widget._animated.visible_range_size += 2

            elif event.keyval == pgm.keysyms.n:
                widget._animated.visible_range_size -= 2

            elif event.keyval == pgm.keysyms.g:
                widget._animated.lines += 1.0

            elif event.keyval == pgm.keysyms.b:
                widget._animated.lines -= 1.0

            elif event.keyval == pgm.keysyms.s:
                if widget.orientation == const.VERTICAL:
                    widget.orientation = const.HORIZONTAL
                elif widget.orientation == const.HORIZONTAL:
                    widget.orientation = const.VERTICAL

            elif event.keyval == pgm.keysyms.Right:
                if widget.orientation == const.VERTICAL:
                    widget.selected_item += 1
                elif widget.orientation == const.HORIZONTAL:
                    widget.selected_item += widget.lines

            elif event.keyval == pgm.keysyms.Left:
                if widget.orientation == const.VERTICAL:
                    widget.selected_item -= 1
                elif widget.orientation == const.HORIZONTAL:
                    widget.selected_item -= widget.lines

            elif event.keyval == pgm.keysyms.Up:
                if widget.orientation == const.VERTICAL:
                    widget.selected_item -= widget.lines
                elif widget.orientation == const.HORIZONTAL:
                    widget.selected_item -= 1

            elif event.keyval == pgm.keysyms.Down:
                if widget.orientation == const.VERTICAL:
                    widget.selected_item += widget.lines
                elif widget.orientation == const.HORIZONTAL:
                    widget.selected_item += 1


            elif event.keyval == pgm.keysyms.space:
                #widget.insert(0, create_text("T"))
                def test():
#                    img = create_img("/home/kaleo/dev/pigment/examples/pictures/fluendo.png")
                    """
                    widget.insert(0, img)
                    widget.pop(len(widget)-1)
                    """
                    img = widget.pop(0)
                    widget.append(img)
                    return True
                gobject.timeout_add(1000, test)
#                grid.append(img)

            # remove the currently selected item
            elif event.keyval == pgm.keysyms.Return:
                widget.pop(widget.selected_item)

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


    # OpenGL viewport creation
    factory = pgm.ViewportFactory('opengl')
    gl = factory.create()
    gl.title = 'Grid with selector widget'

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

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

    grid = GridSelector()
    grid.position = (0.5, 0.5, 0.0)
    grid.orientation = const.HORIZONTAL
    grid.width = 3.0
    grid.height = 2.0
    grid.visible_range_size = 5
    grid.visible = True
    grid.canvas = canvas

    """
    from cairo_selector import Selector
#    color = (0.4, 0.4, 0.6)
    color = (0.9, 0.9, 0.9)
    selector = Selector(200, 200, color, 15)
    selector.position = (0.0, 0.0, 1.0)
    selector.visible = True
    grid.selector = selector
    """

    files = sys.argv[1:]
    for file in files:
        image = create_img(file)
        grid.append(image)
        """
        bg = Image()
        bg.size = image.size
        g = Group(canvas, pgm.DRAWABLE_MIDDLE)
        hmargin = 0.2
        vmargin = 0.2
        g.add(image)
        g.add(bg)
        image.width *= 1.0 - hmargin
        image.height *= 1.0 - vmargin
        image.x += (bg.width-image.width)/2.0
        image.y += (bg.height-image.height)/2.0
        g.visible = True
        
        grid.append(g)
        """
    
    # Let's start a mainloop
    gl.connect('key-press-event',
               on_key_press,
               gl,
               grid)
    gl.connect('delete-event', on_delete)
    pgm.main()
