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

from elisa.core.common import application
from elisa.core.media_uri import MediaUri
from elisa.core.components.model import Model
from elisa.core.utils.i18n import install_translation
from elisa.core.action import ContextualAction

from elisa.plugins.base.utils import get_and_cache_image

from elisa.plugins.poblesec.actions import Action
from elisa.plugins.poblesec.base.list import BaseListController, \
                                             GenericListViewMode
from elisa.plugins.poblesec.base.preview_list import \
    MenuItemPreviewListController
from elisa.plugins.poblesec.base.coverflow import \
    ImageWithReflectionCoverflowController
from elisa.plugins.poblesec.base.grid import GridItemGridController
from elisa.plugins.poblesec.base.list_switcher import ListSwitcherController

from elisa.plugins.youtube.models import YoutubeVideoModel, \
                                         YoutubeVideoListModel
from elisa.plugins.youtube.actions import SearchAction

from twisted.internet import defer


_ = install_translation('youtube')
_p = install_translation('poblesec')


class YoutubeVideoFeedModel(Model):

    def __init__(self):
        super(Model, self).__init__()
        self.title = None
        self.uri = None


def youtube_decorator(controller):
    controller.append_plugin('youtube', _('YouTube'), '/poblesec/youtube')
    return defer.succeed(None)


class YoutubeOpenAction(ContextualAction):
    # An all-in-one default action for the youtube controller

    def _run_action(self, item):
        return item.run()

    def _open_feed(self, item):
        browser = self.controller.frontend.retrieve_controllers('/poblesec/browser')[0]
        return browser.history.append_controller(self.controller.path,
                                                 item.title, uri=item.uri)

    def _play_video(self, item):
        def play_video(playable_model):
            player = self.controller.frontend.retrieve_controllers('/poblesec/video_player')[0]
            player.player.play_model(playable_model)
            main = self.controller.frontend.retrieve_controllers('/poblesec')[0]
            main.show_video_player()

        if item.playable_model is not None:
            # We already know the real URL of the playable video, no need to
            # query the resource manager.
            dfr = defer.succeed(item.playable_model)
        else:
            playable_model, dfr = \
                application.resource_manager.get(item.playable_uri, item)

        dfr.addCallback(play_video)
        return dfr

    def execute(self, item):
        if isinstance(item, Action):
            return self._run_action(item)
        elif isinstance(item, YoutubeVideoFeedModel):
            return self._open_feed(item)
        elif isinstance(item, YoutubeVideoModel):
            return self._play_video(item)


class YoutubeController(BaseListController):

    start_uri = MediaUri('http://gdata.youtube.com/feeds/')

    def initialize(self, videos=None, uri=start_uri):
        if videos:
            self.item_widget_kwargs = {'with_artwork_box': True}
        self.videos = videos
        self.uri = uri
        return super(YoutubeController, self).initialize()

    def populate_model(self):
        if self.videos is not None:
            return defer.succeed(self.videos)

        if self.uri == self.start_uri:
            # Search + list of the feeds
            model = [SearchAction(self)]
            feeds_root = 'http://gdata.youtube.com/feeds/api/standardfeeds/'
            feeds = [(_('Top rated'), 'top_rated'),
                     (_('Top favorites'), 'top_favorites'),
                     (_('Most viewed'), 'most_viewed'),
                     (_('Most popular'), 'most_popular'),
                     (_('Most recent'), 'most_recent')]
            for title, feed in feeds:
                feed_model = YoutubeVideoFeedModel()
                feed_model.title = title
                feed_model.uri = MediaUri(feeds_root + feed)
                model.append(feed_model)
            return defer.succeed(model)

        if self.uri.get_param('time') or self.uri.filename == 'most_recent':
            self.item_widget_kwargs = {'with_artwork_box': True}
            resource, dfr = application.resource_manager.get(self.uri)
            dfr.addCallback(lambda resource: resource.videos)
            return dfr
        else:
            model = []
            times = [(_('Today'), 'today'),
                     (_('This Week'), 'this_week'),
                     (_('This Month'), 'this_month'),
                     (_('All Time'), 'all_time')]
            for title, time in times:
                feed_model = YoutubeVideoFeedModel()
                feed_model.title = title
                feed_model.uri = MediaUri(self.uri)
                feed_model.uri.set_param('time', time)
                model.append(feed_model)
            return defer.succeed(model)

    def create_actions(self):
        return YoutubeOpenAction(self), []

    def clean(self):
        self.uri = None
        self.videos = None
        return super(YoutubeController, self).clean()


class YoutubeViewMode(GenericListViewMode):

    """
    Implementation of the common view modes API.
    """

    def get_label(self, item):
        return defer.succeed(item.title)

    def get_default_image(self, item):
        return 'elisa.plugins.poblesec.glyphs.small.video'

    def get_image(self, item, theme):
        if isinstance(item, YoutubeVideoModel):
            # Get a thumbnail for the video
            thumbnail_uri = item.thumbnails[0].references[0]
            try:
                return item.thumbnail_file
            except AttributeError:
                return get_and_cache_image(thumbnail_uri)
        else:
            return None

    def get_preview_image(self, item, theme):
        if isinstance(item, YoutubeVideoModel):
            try:
                return item.thumbnail_file
            except AttributeError:
                return None
        else:
            return None


class YoutubePreviewListController(YoutubeController, MenuItemPreviewListController):
    view_mode = YoutubeViewMode
    item_widget_kwargs = {'with_artwork_box': False}


class YoutubeCoverflowController(YoutubeController, ImageWithReflectionCoverflowController):
    view_mode = YoutubeViewMode


class YoutubeGridController(YoutubeController, GridItemGridController):
    view_mode = YoutubeViewMode


class YoutubeListSwitcherController(ListSwitcherController):
    modes = [YoutubePreviewListController,
             YoutubeCoverflowController,
             YoutubeGridController]
    default_config = {'view_mode': 'preview_list'}


def use_me_hook(frontend):
    """
    'Use me' hook that takes the user to the Video/Internet/Youtube section.

    @param frontend: the current frontend (poblesec)
    @type frontend:  L{elisa.plugins.pigment.pigment_frontend.PigmentFrontend}

    @return:         a deferred fired when the action is complete
    @rtype:          L{twisted.internet.defer.Deferred}
    """
    browser = frontend.retrieve_controllers('/poblesec/browser')[0]
    paths = [('/poblesec/internet_menu', _p('INTERNET MEDIA'), {}),
             ('/poblesec/video/internet', _p('Videos'), {}),
             ('/poblesec/youtube', _('YouTube'), {})]
    return browser.navigate(paths)
