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

from elisa.plugins.pigment.widgets.widget import Widget
from elisa.plugins.pigment.graph.image import Image
from elisa.plugins.pigment.animation import implicit

import pgm

class SwappingImage(Widget):
    """
    DOCME
    """

    def __init__(self):
        super(SwappingImage, self).__init__()

        def create_image():
            image = Image()
            self.add(image)
            image.bg_a = 0
            image.opacity = 0
            image.layout = pgm.IMAGE_ZOOMED
            image.visible = True

            attributes = ('opacity',)
            animated_image = implicit.AnimatedObject(image, attributes)
            settings = {'duration': 1000,
                        'transformation': implicit.SMOOTH}
            animated_image.setup_next_animations(**settings)
            return animated_image

        self._visible_image = create_image()
        self._hidden_image = create_image()

        self._image_loaded_id = None
        self._file_to_load = None

        self.update_style_properties(self.style.get_items())

    def clean(self):
        # FIXME: code me
        return super(SwappingImage, self).clean()

    def set_from_file(self, filename, max_size=0):
        """
        DOCME
        """
        if self._ready_to_load():
            self._load_file(filename, max_size)
        else:
            self._schedule_load_file(filename, max_size)

    def clear(self):
        """
        DOCME
        """
        self._visible_image.opacity = 0

    def _ready_to_load(self):
        return not self._visible_image.is_animated(attribute='opacity')

    def _schedule_load_file(self, filename, max_size):
        # Actual scheduling is done when the previous image was finished
        # loading and is planned for when the formerly visible image
        # has completely disappeared. At that point self._file_to_load
        # will be loaded.
        self._file_to_load = filename
        self._max_size = max_size

    def _load_file(self, filename, max_size=None):
        image = self._hidden_image.object

        if self._image_loaded_id == None:
            self._image_loaded_id = image.connect("file-loaded",
                                                  self._image_loaded)
        if max_size != None:
            image.set_from_file(filename, max_size)
        else:
            image.set_from_file(filename)

    def _image_loaded(self, image):
        # fade in the newly loaded image
        def fade_in_done(dummy):
            self._hidden_image.object.clear()
            if self._file_to_load != None:
                self._load_file(self._file_to_load, self._max_size)
                self._file_to_load = None

        self._hidden_image.object.opacity = 0
        self._hidden_image.setup_next_animations(end_callback=fade_in_done)
        self._hidden_image.opacity = 255

        # stack the visible image behind the hidden one
        self._hidden_image.object.z = 0.01
        self._visible_image.object.z = 0.0

        # swap hidden and visible image references
        self._visible_image, self._hidden_image = self._hidden_image, \
                                                  self._visible_image

        # disconnect from 'file-loaded' signal
        image.disconnect(self._image_loaded_id)
        self._image_loaded_id = None
