# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 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: Olivier Tilloy <olivier@fluendo.com>

"""
Widgets and controller for a modal popup.
"""

from elisa.core.input_event import EventValue

from elisa.plugins.pigment.widgets.widget import Widget
from elisa.plugins.pigment.widgets.box import HBox, VBox
from elisa.plugins.poblesec.widgets.button import PanelButton

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

from elisa.plugins.pigment.pigment_controller import PigmentController

import pgm


class Popup(Widget):

    """
    Popup widget.
    DOCME
    """

    button_widget_cls = PanelButton

    def __init__(self, title, subtitle, text, buttons):
        super(Popup, self).__init__()
        self._buttons = buttons
        self._create_widgets()
        self.topbar.title.label = title
        self.contents.subtitle.label = subtitle
        self.contents.text.markup = text
        self.update_style_properties(self.style.get_items())

    def _create_widgets(self):
        self.container = VBox()
        self.container.visible = True
        self.add(self.container)
        self.set_focus_proxy(self.container)

        self.topbar = self._create_topbar()
        self.container.pack_start(self.topbar)

        self.button_bar = self._create_buttons()
        self.container.pack_end(self.button_bar)
        self.container.set_focus_proxy(self.button_bar)

        self.contents = self._create_contents()
        self.container.pack_start(self.contents, expand=True)

    def clean(self):
        self._clean_buttons()
        self._clean_contents()
        self._clean_topbar()
        return super(Popup, self).clean()

    def _create_topbar(self):
        topbar = Widget()
        topbar.visible = True
        topbar.background = Image()
        topbar.background.visible = True
        topbar.title = Text()
        topbar.title.visible = True
        topbar.add(topbar.background)
        topbar.add(topbar.title)
        return topbar

    def _clean_topbar(self):
        self.topbar.title.clean()
        self.topbar.title = None
        self.topbar.background.clean()
        self.topbar.background = None
        self.topbar.clean()
        self.topbar = None

    def _create_contents(self):
        contents = Widget()
        contents.visible = True

        contents.background = Image()
        contents.background.visible = True
        contents.add(contents.background)

        contents.subtitle = Text()
        contents.subtitle.visible = True
        contents.add(contents.subtitle)

        contents.text = Text()
        contents.text.multiline = True
        contents.text.visible = True
        contents.add(contents.text)

        return contents

    def _clean_contents(self):
        self.contents.text.clean()
        self.contents.text = None
        self.contents.subtitle.clean()
        self.contents.subtitle = None
        self.contents.background.clean()
        self.contents.background = None
        self.contents.clean()
        self.contents = None

    def _create_button(self, text, callback):
        button = self.button_widget_cls()
        button.text.label = text
        button.visible = True
        button.callback = callback
        button.connect('activated', self._clicked_cb)
        return button

    def _create_buttons(self):
        button_bar = HBox()
        button_bar.navigable = True
        button_bar.visible = True
        self.buttons = []
        for text, callback in self._buttons:
            button = self._create_button(text, callback)
            self.buttons.append(button)
            button_bar.pack_start(button, expand=True)
        return button_bar

    def _clean_buttons(self):
        for button in self.buttons:
            button.disconnect_by_func(self._clicked_cb)
        self.button_bar.clean()
        self.button_bar = None

    def _clicked_cb(self, button, *args):
        button.callback()

    def update_style_properties(self, props=None):
        if props is None:
            return

        remaining_props = {}

        for key, value in props.iteritems():
            try:
                subwidget, attribute = key.split('-', 1)
            except ValueError:
                remaining_props[key] = value
                continue
            if subwidget == 'button':
                for button in self.buttons:
                    button.update_style_properties({attribute: value})
            else:
                remaining_props[key] = value

        if len(remaining_props) > 0:
            return super(Popup, self).update_style_properties(remaining_props)

    @classmethod
    def _demo_widget(cls, *args, **kwargs):
        widget = cls('information'.upper(), 'This is not a test!',
                     'boudiou de truc de ouf', [('Yes', lambda: None),
                      ('No', lambda: None), ('File Not Found', lambda: None)])
        widget.set_name('test_popup')
        widget.position = (100.0, 30.0, 0.0)
        widget.size = (200.0, 180.0)
        return widget


class ErrorPopup(Popup):
    pass


class InformationPopup(Popup):
    pass


class ModalPopupController(PigmentController):

    """
    Popup controller.
    DOCME
    """

    def initialize(self, popup_cls, title, subtitle, text, buttons):
        dfr = super(ModalPopupController, self).initialize()
        dfr.addCallback(self._create_widgets, popup_cls, title,
                                              subtitle, text, buttons)
        dfr.addCallback(self._connect_to_signals)
        return dfr

    def _create_widgets(self, result, popup_cls, title, subtitle, text, buttons):
        background = Image()
        self.widget.add(background)
        background.visible = True
        self.widget.background = background

        popup = popup_cls(title, subtitle, text, buttons)
        self.widget.add(popup)
        popup.visible = True
        self.widget.popup = popup
        self.widget.set_focus_proxy(popup)

        self.widget.set_name('modalpopup')

        return result

    def _connect_to_signals(self, result):
        self._mouse_event_handler_ids = []
        for event in ['double-clicked', 'drag-end', 'released', 'clicked',
                      'pressed', 'drag-begin', 'drag-motion', 'scrolled', 
                      'motion', 'entered', 'left', 'pressured']:
            event_id = self.widget.background.connect(event, self._mouse_event_cb)
            self._mouse_event_handler_ids.append(event_id)

        return result

    def clean(self):
        for event_id in self._mouse_event_handler_ids:
            self.widget.background.disconnect(event_id)
        self.widget.popup.clean()
        self.widget.popup = None
        self.widget.background.clean()
        self.widget.background = None
        return super(ModalPopupController, self).clean()

    def _mouse_event_cb(self, *args):
        # Swallow the event
        return True


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

    from twisted.internet import reactor
    reactor.callWhenRunning(Popup.demo)
    reactor.run()
