# -*- 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.

import math

import pgm
from pgm.widgets.list_ng import List
from pgm.timing import implicit
from pgm.utils import maths

class ListFading(List):

    def __init__(self):
        super(ListFading, self).__init__()
        self._animated.setup_next_animations(duration=500,
                                             transformation=implicit.DECELERATE)
        self.visible_range_size = 1

    def _piecewise_interpolation(self, x, y, factor):
        # specific transformation to map the list items with the given
        # segments to interpolate for
        factor += 0.5
        t = self._visible_range_size
        x = map(lambda a: t*a, x)

        # clamp after lower and upper limits
        if factor < x[0]:
            return y[0]
        elif factor > x[-1]:
            return y[-1]
        else:
            # general case: looking for the segment where factor belongs
            i = 0
            while factor > x[i+1]:
                i += 1

            # factor must be between 0.0 and 1.0
            new_factor = (factor - x[i]) / (x[i+1] - x[i])
            return maths.lerp(y[i], y[i+1], new_factor)

    def compute_height(self, index):
        return self._height

    def compute_width(self, index):
        return self._width

    def compute_x(self, index):
        return 0.0

    def compute_y(self, index):
        return 0.0

    def compute_z(self, index):
        return 0.0

    def compute_opacity(self, index):
        x = [0.0, 0.5, 1.0]
        y = [0, 255, 0]

        return self._piecewise_interpolation(x, y, index)

    def selected_item__set(self, index):
        self._stop_deceleration()
        index = maths.clamp(index, 0, len(self.widgets)-1)
        index = int(round(index))

        prev_selected = self._selected_item
        self._selected_item = index
        visible_range_start = index

        if self.animated:
            self._animated.visible_range_start = visible_range_start
        else:
            self.visible_range_start = visible_range_start

        if prev_selected != index:
            self.emit('selected-item-changed', index)

    def range_start_to_selected(self):
        selected = self.visible_range_start
        selected = int(round(selected))
        selected = maths.clamp(selected, 0, len(self.widgets)-1)
        return selected


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

    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, 1024)
        img.fg_color = (255, 255, 255, 255)
        img.bg_color = (100, 200, 100, 155)
        img.bg_color = (0, 0, 0, 0)
        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
        img.opacity = 30
#        img.x += master_img.width
        img.layout = pgm.IMAGE_SCALED
        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, 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.Down or \
                 event.keyval == pgm.keysyms.Right:
                widget.selected_item += 1

            elif event.keyval == pgm.keysyms.Up or \
                 event.keyval == pgm.keysyms.Left:
                widget.selected_item -= 1

            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.space:
                #widget.insert(0, create_text("T"))
                def test():
#                    img = create_img("/home/kaleo/dev/pigment/examples/pictures/fluendo.png")
                    """
                    list_widget.insert(0, img)
                    list_widget.pop(len(list_widget)-1)
                    """
                    img = list_widget.pop(0)
                    list_widget.append(img)
                    return True
                gobject.timeout_add(1000, test)
#                list_widget.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 = 'Test'

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

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

    list_widget = ListFading()
    list_widget.position = (0.0, 0.0, 0.0)
    list_widget.width = 4.0
    list_widget.height = 3.0
    list_widget.visible = True
    list_widget.canvas = canvas

    files = sys.argv[1:]
    print files
    print len(files)
    for file in files:
        image = create_img(file)
        list_widget.append(image)
        """
        # reflection code
        image.alignment = pgm.IMAGE_BOTTOM
        reflection = create_reflection(image)
        g = Group(canvas, pgm.DRAWABLE_MIDDLE)
        g.add(image)
        g.add(reflection)
        g.visible = True
        list_widget.append(g)
        """
    
    # Let's start a mainloop
    gl.connect('key-press-event',
               on_key_press,
               list_widget)
    gl.connect('delete-event', on_delete)
    pgm.main()
