# -*- 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.timing import implicit

import math

from pgm.widgets.list_ng import List

class CircularList(List):

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

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

    def compute_x(self, index):
        offset = math.pi/2.0
        a = index/self._visible_range_size*math.pi*2.0 + offset
        x = (1.0+math.cos(a))/2.0*(self._width-self._widget_width)
        return x

    def compute_y(self, index):
        offset = math.pi/2.0
        a = index/self._visible_range_size*math.pi*2.0 + offset
        y = (1.0+math.sin(a))/2.0*(self._height-self._widget_height)

        epsilon = 1.0
        max_y = 1.0
        middle = self._visible_range_size/2.0

        if index > middle-epsilon and index < middle+epsilon:
            if index > middle:
                y += 1.0-(index-middle)/epsilon*max_y
            elif index <= middle:
                y += 1.0+(index-middle)/epsilon*max_y

        return y

    def compute_z(self, index):
        epsilon = 0.5
        middle = self._visible_range_size/2.0
        if index > middle-epsilon and index < middle+epsilon:
            return 0.1
        else:
            return 0.0

    def compute_opacity(self, index):
        if index < -1 or index > self._visible_range_size:
            return 0

        middle = self._visible_range_size/2.0
        max_opacity = 255
        step = max_opacity / middle

        if index > middle:
            index = -index + 2.0*middle

        opacity = index * step

        opacity = min(opacity, 255)
        opacity = max(opacity, 0)
        return opacity

    def compute_zoom(self, index):
        epsilon = 1.0
        max_zoom = 4.0
        min_zoom = 1.0
        middle = self._visible_range_size/2.0

        if index > middle-epsilon and index < middle+epsilon:
            if index > middle:
                zoom = (epsilon-(index-middle))/epsilon*(max_zoom-min_zoom) + min_zoom
            elif index <= middle:
                zoom = (epsilon+(index-middle))/epsilon*(max_zoom-min_zoom) + min_zoom
        else:
            zoom = 1.0

        zoom = max(zoom, 1.0)
        return zoom

    def layout_widget(self, widget, position):
        zoom = self.compute_zoom(position)
        width = self._widget_width*zoom
        height = self._widget_height*zoom
        x = self.compute_x(position)-(width-self._widget_width)/2.0
        y = self.compute_y(position)-(height-self._widget_height)/2.0
        z = self.compute_z(position)
        opacity = self.compute_opacity(position)

        # update widget properties
        widget.position = (x, y, z)
        widget.size = (width, height)
        widget.opacity = opacity

    def selected_item__set(self, index):
        if index < 0 or index >= len(self.widgets):
            return

        half_size = (self.visible_range_size-1.0)/2.0
        self._selected_item = index

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

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

    def create_text(label):
        txt = Text()
        txt.label = label
        txt.font_family = "Bitstream DejaVu"
        txt.font_height = 0.225
        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.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, 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.b:
                widget.selected_item = 0

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

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

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

            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.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 = 'Circular list widget'
    gl.size = (640, 480)

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

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

    list_widget = CircularList()
    list_widget.position = (0.5, 0.0, 0.0)
    list_widget.width = 3.0
    list_widget.height = 3.0
    list_widget.visible_range_size = 8
    list_widget.visible = True
    list_widget.canvas = canvas

    files = sys.argv[1:]
    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,
               gl,
               list_widget)
    gl.connect('delete-event', on_delete)
    pgm.main()
