# -*- 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 elisa.plugins.pigment.widgets.widget import Widget
from elisa.plugins.pigment.graph.image import Image

import pgm
from elisa.plugins.pigment.animation.animation import SMOOTH
from elisa.plugins.pigment.animation.implicit import AnimatedObject

class LongLoadingImage(Widget):
    """
    Widget providing facilities for displaying a temporary quickly loaded
    image while a bigger one is being loaded.

    Display L{quick_image} and then L{image} when it is finished loading.

    @ivar image:               image that can take time to load
    @type image:               L{pgm.graph.image.Image}
    @ivar quick_image:         image quick to load
    @type quick_image:         L{pgm.graph.image.Image}

    @cvar time_before_quick:   DOCME
    @type time_before_quick:   float
    """

    time_before_quick = 0.0

    def __init__(self):
        Widget.__init__(self)

        # image creation
        self._image = Image()
        self.add(self._image)
        self._image.x, self._image.y = (0.0, 0.0)
        self._image.width, self._image.height = (1.0, 1.0)
        self._image.bg_color = (0, 0, 0, 0)
        self._image.opacity = 0
        self._image.layout = pgm.IMAGE_SCALED
        self._image.visible = False
        self._image_loaded_id = self._image.connect("file-loaded",
                                                    self._image_loaded)

        attributes = ('opacity',)
        self._animated_image = AnimatedObject(self._image, attributes)

        # quick image initialisation
        self._quick_image = None
        self._quick_image_loaded_id = 0

    def image__get(self):
        return self._image

    image = property(image__get)

    def _image_loaded(self, image):
        # fade in the image
        self._animated_image.update_animation_settings(end_callback=None)
        self._animated_image.stop_animations()

        self._image.opacity = 0
        self._image.visible = True

        settings = {'attribute': 'opacity',
                    'duration': 300,
                    'transformation': SMOOTH,
                    'end_callback': lambda c: self._hide_quick_image(),
                   }

        self._animated_image.setup_next_animations(**settings)
        self._animated_image.opacity = 255

    def _create_quick_image(self):
        # Quick image is created on demand
        if self._quick_image == None:
            self._quick_image = Image()
            self.add(self._quick_image)
            self._quick_image.x, self._quick_image.y = (0.0, 0.0)
            self._quick_image.width, self._quick_image.height = (1.0, 1.0)
            self._quick_image.z = -0.001
            self._quick_image.bg_color = (0, 0, 0, 0)
            self._quick_image.layout = pgm.IMAGE_SCALED
            self._quick_image.visible = False
            self._quick_image_loaded_id = \
                  self._quick_image.connect("file-loaded",
                                            self._quick_image_loaded)

    def quick_image__get(self):
        # FIXME : fake the emission of the signal 'file-loaded' because there
        # is no notification when a set_from_image is done and, in our use case,
        # quick_image__get is used to set a clone. Pigment needs a signal to
        # notify changes to the master image.
        self._create_quick_image()
        self._quick_image_loaded(self._quick_image)
        return self._quick_image

    quick_image = property(quick_image__get)

    def _quick_image_loaded(self, image):
        self._show_quick_image()

    def _show_quick_image(self):
        if self._quick_image != None:
            self._quick_image.opacity = 255
            self._quick_image.visible = True

    def _hide_quick_image(self):
        if self._quick_image != None:
            self._quick_image.visible = False
            if self._quick_image_loaded_id:
                self._quick_image.disconnect(self._quick_image_loaded_id)
                self._quick_image_loaded_id = 0
            self._quick_image.clean()
            self._quick_image = None

    def clear(self):
        self._animated_image.stop_animations()
        if self._quick_image != None:
            self._quick_image.clear()
        self._image.clear()

    def clean(self):
        self.clear()

        self._image.disconnect(self._image_loaded_id)
        self._image_loaded_id = 0

        if self._quick_image_loaded_id:
            self._quick_image.disconnect(self._quick_image_loaded_id)

        if self._image:
            self._image.clean()
            self._image = None
        if self._quick_image:
            self._quick_image.clean()
            self._quick_image = None

        if self._animated_image is not None:
            self._animated_image.stop_animations()
            self._animated_image = None

        return super(LongLoadingImage, self).clean()

