# -*- 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.
#
# Authors: Anna Wojdel <awojdel@fluendo.com>
#          Olivier Tilloy <olivier@fluendo.com>

from elisa.plugins.pigment.widgets.widget import Widget
from elisa.plugins.pigment.widgets.box import HBox, VBox
from elisa.plugins.pigment.widgets.size_enforcer import RatioConstrainer

from elisa.plugins.pigment.graph.image import Image
from elisa.plugins.pigment.graph.text import Text

from elisa.plugins.poblesec.widgets.background import WidgetWithBackground

import pgm


class GenericInfoScreen(HBox):

    """
    A generic information screen that displays various information/options.
    This base class defines an interface that subclasses should implement.

    @ivar artwork_ratio: aspect ratio of the artwork widget returned by the
                         create_artwork method
    @type artwork_ratio: C{float}
    """

    def create_widgets(self):
        self.left_panel = self._create_left_panel()
        self.pack_start(self.left_panel)
        self.right_panel = self._create_right_panel()
        self.pack_start(self.right_panel)
        self.set_focus_proxy(self.right_panel)

    def _create_left_panel(self):
        left_panel = VBox()
        left_panel.visible = True
        left_panel.artwork = self.create_artwork()
        left_panel.pack_start(left_panel.artwork, expand=True)
        left_panel.caption = self.create_caption()
        left_panel.pack_start(left_panel.caption)
        return left_panel

    def do_mapped(self):
        super(GenericInfoScreen, self).do_mapped()
        self._update_artwork_ratio()

    def _set_artwork_ratio(self, artwork_ratio):
        self._artwork_ratio = artwork_ratio
        if self.is_mapped:
            self._update_artwork_ratio()

    def _get_artwork_ratio(self):
        return self._artwork_ratio

    artwork_ratio = property(fget=_get_artwork_ratio, fset=_set_artwork_ratio)

    def _update_artwork_ratio(self):
        width = self.left_panel.artwork.absolute_height/self.absolute_width* \
                self._artwork_ratio
        self.left_panel.width = width

    def create_artwork(self):
        """
        Create the artwork widget displayed top-left of the screen.
        Subclasses should implement this method.

        @return: the artwork widget
        @rtype:  L{elisa.plugins.pigment.graph.node.Node}
        """
        raise NotImplementedError()

    def create_caption(self):
        """
        Create the caption widget displayed bottom-left of the screen.
        Subclasses should implement this method.

        @return: the caption widget
        @rtype:  L{elisa.plugins.pigment.graph.node.Node}
        """
        raise NotImplementedError()

    def _create_right_panel(self):
        right_panel = VBox()
        right_panel.visible = True
        right_panel.title = self.create_title()
        right_panel.pack_start(right_panel.title)
        right_panel.contents = self.create_contents()
        right_panel.pack_start(right_panel.contents, expand=True)
        return right_panel

    def create_title(self):
        """
        Create the title widget displayed top-right of the screen.
        Subclasses should implement this method.

        @return: the title widget
        @rtype:  L{elisa.plugins.pigment.graph.node.Node}
        """
        raise NotImplementedError()

    def create_contents(self):
        """
        Create the contents widget displayed at the right of the screen.
        Subclasses should implement this method.

        @return: the contents widget
        @rtype:  L{elisa.plugins.pigment.graph.node.Node}
        """
        raise NotImplementedError()


class InfoScreen(GenericInfoScreen):
    """
    Specialised info screen using:
    - a text with a background for the title
    - an image with a background as the artwork
    - a vertical box with a background for the caption
    """

    def create_artwork(self):
        artwork = WidgetWithBackground(foreground=Image())
        artwork.visible = True
        return artwork

    def create_caption(self):
        caption = WidgetWithBackground(foreground=VBox())
        caption.visible = True
        self.pack_captions(caption)
        return caption

    def create_title(self):
        title = WidgetWithBackground(foreground=Text())
        title.visible = True
        return title

    def pack_captions(self, caption):
        """
        Layout captions, typically L{elisa.plugins.pigment.graph.text.Text},
        into C{caption}.

        Subclasses should implement this method.

        @param caption: widget to pack captions in
        @type caption:  L{elisa.plugins.pigment.widgets.box.VBox}
        """
        raise NotImplementedError()

class TextInfoScreen(InfoScreen):
    """
    Specialised info screen using a vertical box for the content packed with:
    - a text with a background called the summary
    - a horizontal box placeholder for buttons
    """

    def create_contents(self):
        contents = VBox()
        contents.visible = True

        contents.summary = WidgetWithBackground(foreground=Text())
        contents.summary.visible = True
        contents.pack_end(contents.summary, expand=True)
        return contents

    def _create_right_panel(self):
        right_panel = InfoScreen._create_right_panel(self)
        footer = HBox()
        footer.navigable = True
        footer.visible = True
        self.pack_buttons(footer)

        right_panel.footer = footer
        right_panel.pack_end(footer)
        return right_panel

    def pack_buttons(self, footer):
        """
        Layout buttons into C{footer}.

        Subclasses should implement this method.

        @param footer: widget to pack buttons in
        @type footer:  L{elisa.plugins.pigment.widgets.box.VBox}
        """
        raise NotImplementedError()



class SampleInfoScreen(GenericInfoScreen):

    """
    A sample implementation of an information screen.
    """

    def create_artwork(self):
        artwork = WidgetWithBackground(foreground=Image())
        artwork.visible = True
        return artwork

    def create_caption(self):
        caption = WidgetWithBackground(foreground=Text())
        caption.visible = True
        return caption

    def create_title(self):
        title = WidgetWithBackground(foreground=Text())
        title.visible = True
        return title

    def create_contents(self):
        contents = WidgetWithBackground(foreground=Text())
        contents.visible = True
        return contents

    @classmethod
    def _demo_widget(cls, *args, **kwargs):
        widget = cls()
        widget.set_name('demo')
        widget.left_panel.caption.foreground.label = '¡Viva la revolución!'
        widget.right_panel.title.foreground.label = 'TITLE'
        widget.right_panel.contents.foreground.label = \
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " \
            "Curabitur porttitor eros. Fusce eu odio. Class aptent taciti " \
            "sociosqu ad litora torquent per conubia nostra, per inceptos " \
            "himenaeos. Donec convallis mollis felis. Class aptent taciti " \
            "socios quad litora torquent per conubia nostra, per inceptos " \
            "himenaeos. Suspendisse orci nisl, bibendum eget, vehicula non, " \
            "eleifend a, nulla. Nunc in velit eu odio varius vehicula. Nulla" \
            " facilisi. Cras ac orci sed nisi sagittis placerat. Maecenas " \
            "pulvinar eros sed turpis. In hac habitasse platea dictumst. " \
            "Aliquam erat volutpat. Quisque tristique lacus non tortor. " \
            "Nulla facilisi."
        return widget


if __name__ == '__main__':
    # absolute import required in order to make styling work
    from elisa.plugins.poblesec.widgets.info_screen import SampleInfoScreen

    widget = SampleInfoScreen.demo()

    try:
        __IPYTHON__
    except NameError:
        pgm.main()
