# -*- 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: Guillaume Emont <guillaume@fluendo.com>

from elisa.core.utils import defer
from elisa.core.utils.i18n import install_translation
from elisa.core.media_uri import MediaUri
from elisa.core.action import ContextualAction
from elisa.plugins.base.models.file import FileModel, DirectoryModel
from elisa.plugins.base.models.device import DeviceModel
from elisa.plugins.base.models.media import PlayableModel

_ = install_translation('dvd')

class DvdAction(ContextualAction):
    @property
    def _player_controller(self):
        frontend = self.controller.frontend
        controllers = frontend.retrieve_controllers('/poblesec/dvd_player')
        return controllers[0]

    @property
    def _main_controller(self):
        return self.controller.frontend.controller

    def _show_player(self):
        self._main_controller.show_dvd_player()
        

class PlayDvdAction(DvdAction):
    def _get_path(self, item):
        if isinstance(item, DeviceModel):
            return item.device
        elif isinstance(item, (FileModel, DirectoryModel)):
            return item.uri.path

    def _get_title(self, item):
        if hasattr(item, 'name'):
            return item.name

        return 'DVD'

    def execute(self, item):
        # FIXME: don't create a model, just use player.play() if we already
        # have item in the player
        playable_model = PlayableModel()
        playable_model.uri = MediaUri({'scheme': 'dvd',
                                      # yeah, we put the path in host, because
                                      # resindvd expects broken uris
                                      'host': self._get_path(item),
                                      'path': ''})
        playable_model.title = self._get_title(item)
        self._show_player()
        self._player_controller.player.play_model(playable_model)

        return defer.succeed(None)


class PlayDvdWithPopupAction(PlayDvdAction):
    """
    This action will display a popup showing the content of popup_title,
    popup_subtitle and popup_text, with a 'Continue' button being the actual
    playing (as defined in PlayDvdAction).

    It should not be used directly, you should inherit from it.

    The popup will be shown only once per moovida launch for each subclass.

    @cvar popup_title: title of the popup window
    @type popup_title: C{str}
    @cvar popup_subtitle: subtitle of the popup window
    @type popup_subtitle: C{str}
    @cvar popup_text: text of the popup window
    @type popup_text: C{str}
    """
    popup_title = None
    popup_subtitle = None
    popup_text = None

    # list of classes that have already shown the popup, and should not show
    # it again before the next launch
    _popup_shown = []

    def _show_popup(self, item):
        def _do_play():
            dfr = self._main_controller.hide_popup()

            def execute_action(result):
                return super(PlayDvdWithPopupAction, self).execute(item)
            return dfr.addCallback(execute_action)

        buttons = ((_('Cancel'), self._main_controller.hide_popup),
                   (_('Continue'), _do_play))
        self._main_controller.enqueue_popup(self.popup_title,
                                            self.popup_subtitle,
                                            self.popup_text,
                                            buttons)
        return defer.succeed(None)

    def execute(self, item):
        if type(self) not in self._popup_shown:
            self._popup_shown.append(type(self))
            return self._show_popup(item)
        else:
            return super(PlayDvdWithPopupAction, self).execute(item)


class PlayPhysicalDvdAction(PlayDvdWithPopupAction):
    popup_title = _("PLAYBACK INFORMATION")
    popup_subtitle = _("Experimental DVD Playback")
    popup_text = _("Currently, the DVD playback in Moovida is extremely " \
                   "experimental. Therefore, the playback experience may not " \
                   "be perfect for this DVD disc." \
                   "\n\n" \
                   "Click 'Cancel' to close this popup or click on " \
                   "'Continue' to playback this DVD disc.")


class PlayVirtualDvdAction(PlayDvdWithPopupAction):
    popup_title = _("PLAYBACK INFORMATION")
    popup_subtitle = _("Experimental 'Virtual' Disc Playback")
    popup_text = _("Currently, the DVD playback in Moovida is extremely " \
                   "experimental. Therefore, the playback experience may not " \
                   "be perfect for this 'virtual' disc." \
                   "\n\n" \
                   "Click 'Cancel' to close this popup or click on " \
                   "'Continue' to playback this virtual disc.")


class PlayVideoTsAction(PlayVirtualDvdAction):
    pass


class PlayDvdIsoAction(PlayVirtualDvdAction):
    pass


class EjectDvdAction(DvdAction):
    name = 'eject'
    def execute(self, item):
        self._player_controller.player.stop()
        self.controller.model.remove(item)
        return item.eject()

