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

from elisa.core.utils import defer, caching
from elisa.core.media_uri import MediaUri

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.poblesec.actions import OpenControllerAction

from elisa.plugins.rss.models import RssItemModel, RssFeedModel

from twisted.internet import task

import os


class RssReaderController(BaseListController):

    def initialize(self, feed=None, feed_list=[], rss_feed_class=RssFeedModel,
                   media_filter=None):
        """
        @param feed:           the feed to display
        @type feed:            L{elisa.plugins.rss.models.RssFeedModel}
        @param feed_list:      a list of feed information in tuple of
                               (name, uri, icon, [etc. whatever needed])
        @type feed_list:       tuple of C{str}
        @param rss_feed_class: the class of the RSS feed
        """
        self.feed = feed
        self.feed_list = feed_list
        self.rss_feed_class = rss_feed_class
        self.media_filter = media_filter
        return super(RssReaderController, self).initialize()

    def populate_model(self):
        if self.feed is not None:
            def filter_feed_items(model):
                for item in self.feed.items:
                    if item.type.startswith(self.media_filter):
                        model.append(item)
                    yield None

            def feed_loaded(result):
                if self.media_filter is not None:
                    model = []
                    dfr = task.coiterate(filter_feed_items(model))
                    dfr.addCallback(lambda result: model)
                    return dfr
                else:
                    return self.feed.items

            dfr = self.feed.load()
            dfr.addCallback(feed_loaded)
            return dfr

        else:
            def iterate_feeds(model):
                for feed in self.feed_list:
                    feed_model = self.rss_feed_class()
                    feed_model.name = feed[0]
                    feed_model.uri = MediaUri(feed[1])
                    model.append(feed_model)
                    yield None

            model = []
            dfr = task.coiterate(iterate_feeds(model))
            dfr.addCallback(lambda result: model)
            return dfr

    def item_activated(self, item):
        if isinstance(item, RssFeedModel):
            action = OpenControllerAction(self, None)
            return action.open_controller(self.path, item.name, feed=item,
                                          rss_feed_class=self.rss_feed_class,
                                          media_filter=self.media_filter)
        elif isinstance(item, RssItemModel):
            poblesec = self.frontend.retrieve_controllers('/poblesec')[0]

            if item.video_model is not None:
                player = poblesec.video_player.player
                poblesec.show_video_player()
                player.play_model(item.video_model)
                return defer.succeed(None)

            elif item.track_model is not None:
                player = poblesec.music_player.player
                poblesec.show_music_player()
                player.play_model(item.track_model)
                return defer.succeed(None)

            elif item.image_model is not None:
                def iterate_images(playlist):
                    for image in self.model:
                        image_model = image.image_model
                        if image_model is not None:
                            playlist.append(image_model)
                        yield None

                def enqueue_and_play(playlist):
                    player = poblesec.slideshow_player.player
                    player.set_playlist(playlist)
                    poblesec.show_slideshow_player()
                    player.start_slideshow(playlist.index(item.image_model))

                playlist = []
                dfr = task.coiterate(iterate_images(playlist))
                dfr.addCallback(lambda result: playlist)
                dfr.addCallback(enqueue_and_play)
                return dfr

        # This should not happen if the feed was correctly formed and parsed.
        msg = 'The item does not contain a valid media model.'
        return defer.fail(TypeError(msg))


class RssReaderViewMode(GenericListViewMode):

    def get_label(self, item):
        if isinstance(item, RssFeedModel):
            return defer.succeed(item.name)
        elif isinstance(item, RssItemModel):
            return defer.succeed(item.title)

    def get_default_image(self, item):
        if isinstance(item, RssFeedModel):
            resource = 'elisa.plugins.poblesec.glyphs.small.devices_shares'
        elif isinstance(item, RssItemModel):
            if item.type.startswith('image'):
                resource = 'elisa.plugins.poblesec.glyphs.small.pictures'
            elif item.type.startswith('audio'):
                resource = 'elisa.plugins.poblesec.glyphs.small.music'
            elif item.type.startswith('video'):
                resource = 'elisa.plugins.poblesec.glyphs.small.video'
            else:
                resource = None
        return resource

    def get_image(self, item, theme):
        if isinstance(item, RssItemModel):
            if not(item.thumbnails):
                return None

            thumbnail_uri = item.thumbnails[0].references[0]
            try:
                thumbnail_file = item.thumbnail_file
            except AttributeError:
                thumbnail_file = caching.get_cached_image_path(thumbnail_uri)
                item.thumbnail_file = thumbnail_file

            if os.path.exists(thumbnail_file):
                return defer.succeed(thumbnail_file)
            else:
                cache_path = caching.get_pictures_cache_path()
                return caching.get_and_cache_to_file(thumbnail_uri, cache_path)
        else:
            return None

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


class RssReaderPreviewListController(RssReaderController, MenuItemPreviewListController):
    view_mode = RssReaderViewMode


class RssReaderCoverflowController(RssReaderController, ImageWithReflectionCoverflowController):
    view_mode = RssReaderViewMode


class RssReaderGridController(RssReaderController, GridItemGridController):
    view_mode = RssReaderViewMode


class RssReaderListSwitcherController(ListSwitcherController):
    modes = [RssReaderPreviewListController,
             RssReaderCoverflowController,
             RssReaderGridController]
    default_config = {'view_mode': 'preview_list'}
