# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006-2008 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 Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

from pgm.graph.group import Group
from pgm.graph.text import Text # FIXME: should be replaced with Rectangle
from pgm.graph.image import Image
from pgm.timing import implicit
import gst
import os
import pgm
from twisted.internet import reactor

class Dock(Group):

    def __init__(self, canvas, layer,
                 width, height,
                 background_image):

        Group.__init__(self, canvas, layer)

        # build the background
        self._background = Image()
        self._background.set_from_file(background_image)
        self._background.layout = pgm.IMAGE_FILLED
        self._background.alignment = pgm.IMAGE_LEFT
        self._background.opacity = 255
        self._background.bg_color = (0, 0, 0, 0)
        self.add(self._background)
        self._background.position = (0.0, 0.0, 0.0)
        self._background.size = (width, height)

        self._background.visible = True
        
        self._show = None

        self._animated_group = implicit.AnimatedObject(self)
        self._animated_group.mode = implicit.REPLACE
        self._animated_group.setup_next_animations(duration = 500,
                                                   transformation = implicit.DECELERATE)

    def show(self, time_to_show=-1):
        """
        Show the player dock for the next seconds
        @time_to_show: duration before the dock disappears (in seconds)
                       if set to -1 the dock will not disappear
        """
        if self._animated_group.opacity != 255:
            self._animated_group.opacity = 255

        if time_to_show > 0:
            if self._show != None and self._show.active():
                self._show.reset(time_to_show)
            else:
                self._show = reactor.callLater(time_to_show, self.hide)

    def _cancel_timer(self):
        if self._show != None and self._show.active():
            self._show.cancel()

    def hide(self):
        """
        Hide the dock
        """
        self._cancel_timer()
        if self._animated_group.opacity != 0:
            self._animated_group.opacity = 0

    def is_visible(self):
        # FIXME: we should override visible__get() here, but it doesn't work...
        #        the progress bar is not visible anymore if we do so.
        return self._animated_group.opacity == 255


    def image_from_path(self, path):
        self._background.set_from_file(path)

    def connect(self, signal, *args):
        self._background.connect(signal, *args)







LEFT, RIGHT, TOP, BOTTOM = 0, 1, 2, 3
EXTENDED, FIXED, OPTIMISED = 0, 1, 2

class OldDock(Group):

    def __init__(self, canvas, layer):
        # group containing the dock's widgets
        Group.__init__(self, canvas, layer)
        self._thickness = 0.25
        self._stick = TOP
        self._layout = EXTENDED
        self._opened_value = 0.0

        self._animated_group = implicit.AnimatedObject(self)
        self._animated_group.setup_next_animations(duration = 500)

        # background of the dock
        # FIXME: should be replaced with Rectangle
        self._background = Image()
#        self._background.label = ""
        self._background.bg_color = (20, 20, 20, 255)
        self.add(self._background)

        # default values
#        self._position = TOP
#        self._thickness = 0.25
#        self._layout = EXTENDED

        # recompute properties
        self.stick = TOP
        self.thickness = self._thickness
        self.layout = self._layout

        # display the dock
        self.visible = False
        self._background.visible = True



    def stick__set(self, position):
        previous_position = self._stick
        self._stick = position

        # reorganise the dock's widgets
        if (previous_position in [TOP, BOTTOM]).__xor__ \
           (position in [TOP, BOTTOM]):
            for child in self.children:
                if child != self._background:
                    # FIXME: bug if set during implicit animation
                    #print child, child.x, child.y
                    child.x, child.y = child.y, child.x
                    #print child, child.x, child.y

        # reposition the dock
        if position == TOP:
            self._coordinate = "y"
            self._opened_value = 0.0
            self._animated_group.x = 0.0
        elif position == BOTTOM:
            self._coordinate = "y"
            self._opened_value = self._canvas.height - self.thickness
            self._animated_group.x = 0.0

        self._animated_group.y = self._opened_value

        # recompute properties
        self.thickness = self._thickness
        self.layout = self._layout

    def stick__get(self):
        return self._stick

    def layout__set(self, layout):
        self._layout = layout

        if layout == EXTENDED:
            self._background.size = (self._canvas.width,
                                     self._background.size[1])


    def layout__get(self):
        return self._layout

    def thickness__set(self, thickness):
        self._thickness = thickness

        for child in self.children:
            if child == self._background:
                child.size = (child.size[0], thickness)
            else:
                child.size = (thickness, thickness)

    def thickness__get(self):
        return self._thickness

    def open(self):
        value = self._opened_value
        self._animated_group.y = value

    def close(self):
        value = self._opened_value - self._thickness
        self._animated_group.y = value

    def add(self, item, setx=0.0, sety=0.0):
        Group.add(self, item)
        item.size = (self.thickness, self.thickness)

        if self._layout == EXTENDED:
            item.x = setx
            item.y = sety


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

    def handle_events(dock, gl, loop):
        for event in gl.get_events():
            if event.type == pgm.DELETE:
                loop.quit()

            if event.type == pgm.KEY_PRESS:
                if event.keyval == pgm.KEY_ESCAPE or event.keyval == pgm.KEY_q:
                    loop.quit()

                elif event.keyval == pgm.KEY_DOWN:
                    if dock.stick == TOP:
                        dock.open()
                    elif dock.position == BOTTOM:
                        dock.close()

                elif event.keyval == pgm.KEY_UP:
                    if dock.stick == TOP:
                        dock.close()
                    elif dock.position == BOTTOM:
                        dock.open()

                elif event.keyval == pgm.KEY_RIGHT:
                    if dock.stick == RIGHT:
                        dock.close()
                    elif dock.position == LEFT:
                        dock.open()

                elif event.keyval == pgm.KEY_LEFT:
                    if dock.stick == RIGHT:
                        dock.open()
                    elif dock.position == LEFT:
                        dock.close()

                elif event.keyval == pgm.KEY_s:
                    dock.stick = LEFT

                elif event.keyval == pgm.KEY_d:
                    dock.stick = BOTTOM

                elif event.keyval == pgm.KEY_f:
                    dock.stick = TOP

                elif event.keyval == pgm.KEY_g:
                    dock.stick = RIGHT

                elif event.keyval == pgm.KEY_i:
                    dock.stick += 0.1

                elif event.keyval == pgm.KEY_o:
                    dock.stick -= 0.1

        return True

    factory = pgm.ViewportFactory('opengl')
    gl = factory.create()
    gl.title = 'Dock widget'

    canvas = pgm.Canvas()

    gl.set_canvas(canvas)


    dock = Dock(canvas, pgm.DRAWABLE_MIDDLE)

    label = Text()
    label.label = "Dock"
    label.fg_color = (220, 220, 220, 255)
    label.bg_color = (0, 0, 0, 0)
    label.visible = True

    logo = Image()
#    logo.set_from_file("fluendo.png")
    logo.bg_color = (0, 0, 0, 0)
    logo.opacity = 255
    logo.visible = True

    video = Image()
    video.bg_a = 0
    video.visible = True

    if len(sys.argv) > 1:
        # GStreamer pipeline setup
        pipeline = gst.element_factory_make('playbin')
        sink = gst.element_factory_make('pgmimagesink')
        pipeline.set_property('uri', sys.argv[1])
        pipeline.set_property('video-sink', sink)
        sink.set_property('image', video)
        pipeline.set_state(gst.STATE_PLAYING)

    dock.add(video, 1.0)
    dock.add(label, 0.8,0.1)
    dock.add(logo, 0.0)

    # animate the logo
    animated_logo = implicit.AnimatedObject(logo)

    animated_logo.setup_next_animations(duration=500,
                                        repeat_behavior=implicit.REVERSE,
                                        repeat_count=implicit.INFINITE)
    animated_logo.opacity = 100

    # animate the video
    animated_video = implicit.AnimatedObject(video)
    animated_video.setup_next_animations(duration=1000,
                                        repeat_behavior=implicit.REVERSE,
                                        repeat_count=implicit.INFINITE,
                                        transformation=implicit.SMOOTH)
    animated_video.x = 2.0


    loop = gobject.MainLoop()
    gobject.timeout_add(5, gl.update)
    gobject.timeout_add(15, handle_events, dock, gl, loop)
    loop.run()
