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

class RatioConstrainer(Widget):
    """
    DOCME

    *Warning*: setting the width will not be taken into account: width is
               computed using the height and the aspect_ratio

    @ivar aspect_ratio: DOCME
    @type aspect_ratio: float
    """

    def __init__(self):
        super(RatioConstrainer, self).__init__()
        self._aspect_ratio = 2.0

    def _set_aspect_ratio(self, aspect_ratio):
        self._aspect_ratio = aspect_ratio
        self._update_ratio()

    def _get_aspect_ratio(self):
        return self._aspect_ratio

    aspect_ratio = property(fget=_get_aspect_ratio, fset=_set_aspect_ratio)

    def _update_ratio(self):
        if self.is_mapped:
           self._resize_width()

    def _resize_width(self):
        parent = self.parent
        if parent != None:
            factor = self._aspect_ratio/parent.absolute_width
        else:
            factor = self._aspect_ratio

        self.width = self.absolute_height*factor

    def do_mapped(self):
        self._update_ratio()

    def do_resized(self, previous_width, previous_height):
        if not self.is_mapped:
            return

        if self._almost_equal(self.absolute_width, \
                              self._aspect_ratio*self.absolute_height):
            return

        self._resize_width()

    def _almost_equal(self, float1, float2):
        return abs(float1-float2) <= 1e-6

    def set_focus(self):
        # Overridden from elisa.plugins.pigment.widgets.widget.Widget
        for child in self:
            # There should only be one child anyway
            if isinstance(child, Widget) and child.set_focus():
                return True
            return False
        return False

class Square(RatioConstrainer):
    """
    Widget that is constrained to be square, that is having an aspect ratio of
    1:1. One can change its size as usual by setting its width or height. It
    will automatically resize itself to stay visually square.

    Be careful, if the square is part of a group then its properties width and
    height might not be equal but still it will render visually square because
    these values are relative to the parent group.

    When both width and height are changed at the same time the height has
    priority over the width.
    """

    def __init__(self):
        super(Square, self).__init__()
        self._aspect_ratio = 1.0

if __name__ == '__main__':
    import pgm
    from elisa.plugins.pigment.graph.image import Image

    i = Image()
    i.visible = True

    s = Square.demo()
    s.size = (100.0, 100.0)
    s.add(i)

    g = Widget()
    g.add(s)
    g.visible = True

    try:
        __IPYTHON__
    except NameError:
        pgm.main()
