# -*- 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: Benjamin Kampmann <benjamin@fluendo.com>

from elisa.core import common

from elisa.plugins.poblesec.base.list_switcher import ListSwitcherController

from elisa.plugins.poblesec.base.hierarchy import HierarchyController

from elisa.plugins.database.photo_controller import PhotoVerticalWithPreview, \
    PhotoCoverflow, PhotoGrid
from elisa.plugins.database.photo_controller import GenericPhotosController

from elisa.plugins.poblesec.base.preview_list import \
    MenuItemPreviewListController, DoubleLineMenuItemPreviewListController
from elisa.plugins.poblesec.base.coverflow import \
    ImageWithReflectionCoverflowController
from elisa.plugins.poblesec.base.grid import GridItemGridController

from elisa.plugins.database.music_controller import GenericTracksDbController, \
                                              DBTracksViewMode

from elisa.plugins.database.photo_controller import PhotosController, \
                                              PhotoViewMode
                                              
from elisa.plugins.database.video_controller import VideoController, \
                                              MovieViewMode, MovieController
from elisa.plugins.database.tvshows_controllers import TVEpisodeViewMode, \
     EpisodeListControllerMixin

from elisa.plugins.poblesec.link import Link, \
                                        LinksMenuController

from elisa.plugins.database.models import MusicTrack, File, Image, Movie, TVEpisode
from storm.expr import Desc

from twisted.internet import defer

# i18n
from elisa.core.utils.i18n import install_translation
_ = install_translation('database')


def music_playlists_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/music/playlists'
    link.label = _('Playlists')
    controller.model.append(link)
    return defer.succeed(None)

def movie_playlists_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/movie/playlists'
    link.label = _('Playlists')
    controller.model.append(link)
    return defer.succeed(None)

def tv_playlists_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/tv/playlists'
    link.label = _('Playlists')
    controller.model.append(link)
    return defer.succeed(None)

def last_played_tracks_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/music/tracks_played'
    link.label = _('Recently Played Tracks')
    link.controller_args = {'limit': 20, 'order_by': 'last_played'}
    controller.model.append(link)
    return defer.succeed(None)

def most_played_tracks_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/music/tracks_played'
    link.label = _('Most Played Tracks')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def recently_added_tracks_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/music/tracks_added'
    link.label = _('Recently Added Tracks')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def unplayed_movie_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/movie/video_unplayed'
    link.label = _('Unwatched Movies')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def last_played_movie_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/movie/video_played'
    link.label = _('Last Watched Movies')
    link.controller_args = {'limit': 20, 'order_by': 'last_played'}
    controller.model.append(link)
    return defer.succeed(None)

def most_played_movie_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/movie/video_played'
    link.label = _('Most Watched Movies')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def recently_added_movie_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/movie/video_added'
    link.label = _('Recently Added Movies')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def unplayed_tv_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/tvepisode/video_unplayed'
    link.label = _('Unwatched TV Episodes')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def last_played_tv_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/tvepisode/video_played'
    link.label = _('Last Watched TV Episodes')
    link.controller_args = {'limit': 20, 'order_by': 'last_played'}
    controller.model.append(link)
    return defer.succeed(None)

def most_played_tv_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/tvepisode/video_played'
    link.label = _('Most Watched TV Episodes')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def recently_added_tv_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/tvepisode/video_added'
    link.label = _('Recently Added TV Episodes')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

"""
Not used
def recently_added_photos_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/photo/photos_added'
    link.label = _('Recently Added Photos')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def last_played_photos_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/photo/photos_played'
    link.label = _('Recently Viewed Photos')
    link.controller_args = {'limit': 20,  'order_by' : 'last_played'}
    controller.model.append(link)
    return defer.succeed(None)

def most_played_photos_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/photo/photos_played'
    link.label = _('Most Viewed Photos')
    link.controller_args = {'limit': 20}
    controller.model.append(link)
    return defer.succeed(None)

def pictures_playlists_decorator(controller):
    link = Link()
    link.controller_path = '/poblesec/database/pictures/playlists'
    link.label = _('History')
    controller.model.append(link)

    return defer.succeed(None)
"""

class PlaylistsPreviewListController(LinksMenuController, MenuItemPreviewListController):
    item_widget_kwargs = {'with_artwork_box': False}


class PlayedMixin(object):
    def _load(self, result, filter, order_by, limit):
        self.filter = filter

        def got_items(models):
            self.model.extend(models)
            return self

        def get_items(result_set):
            return result_set.all()

        def set_limit(result_set, limit):
            result_set.config(limit=limit)
            return result_set

        def sort_by_count(result_set):
            result_set.order_by(Desc(File.playcount))
            return result_set

        def sort_by_date(result_set):
            result_set.order_by(Desc(File.last_played))
            return result_set

        store = common.application.store

        dfr = store.find(filter, filter.file_path == File.path,
                         File.playcount != 0, File.hidden == False)

        if order_by == "last_played":
            dfr.addCallback(sort_by_date)
        else:
            dfr.addCallback(sort_by_count)

        dfr.addCallback(set_limit, limit)
        dfr.addCallback(get_items)
        dfr.addCallback(got_items)
        return dfr

class AddedMixin(object):
    def _load(self, result, filter, limit):
        self.filter = filter

        def got_items(models):
            self.model.extend(models)
            return self

        def get_items(result_set):
            return result_set.all()

        def set_limit(result_set, limit):
            result_set.config(limit=limit)
            return result_set

        def sort_by_added(result_set):
            # this is not exactly the time it was added but last changed
            result_set.order_by(Desc(File.modification_time))
            return result_set

        store = common.application.store

        dfr = store.find(filter, filter.file_path == File.path,
                         File.hidden == False)

        dfr.addCallback(sort_by_added)

        dfr.addCallback(set_limit, limit)
        dfr.addCallback(get_items)
        dfr.addCallback(got_items)
        return dfr
        
class UnPlayedMixin(object):
    def _load(self, result, filter, limit):
        self.filter = filter

        def got_items(models):
            self.model.extend(models)
            return self

        def get_items(result_set):
            return result_set.all()

        def set_limit(result_set, limit):
            result_set.config(limit=limit)
            return result_set

        store = common.application.store

        dfr = store.find(filter, filter.file_path == File.path, \
                File.playcount == 0)

        dfr.addCallback(set_limit, limit)
        dfr.addCallback(get_items)
        dfr.addCallback(got_items)
        return dfr

class PlayedTracksController(GenericTracksDbController, PlayedMixin):
    def initialize(self, order_by=None, limit=10):
        dfr = super(PlayedTracksController, self).initialize()

        dfr.addCallback(self._load, MusicTrack, order_by, limit)
        return dfr

class AddedTracksController(GenericTracksDbController, AddedMixin):

    def initialize(self, limit=10):
        dfr = super(AddedTracksController, self).initialize()

        dfr.addCallback(self._load, MusicTrack, limit)
        return dfr

class PlayedPhotosController(GenericPhotosController, PlayedMixin):
    def initialize(self, order_by=None, limit=10):
        dfr = super(PlayedPhotosController, self).initialize()

        dfr.addCallback(self._load, Image, order_by, limit)
        return dfr

class AddedPhotosController(GenericPhotosController, AddedMixin):

    def initialize(self, limit=10):
        dfr = super(AddedPhotosController, self).initialize()

        dfr.addCallback(self._load, Image, limit)
        return dfr
    
class AddedMovieController(AddedMixin, MovieController):
    def initialize(self, limit=10):
        dfr = super(AddedMovieController, self).initialize()

        dfr.addCallback(self._load, Movie,limit)
        return dfr

class PlayedMovieController(PlayedMixin, MovieController):
     def initialize(self, order_by=None, limit=10):
        dfr = super(PlayedMovieController, self).initialize()

        dfr.addCallback(self._load, Movie, order_by, limit)
        return dfr
        
class UnPlayedMovieController(UnPlayedMixin, MovieController):
     def initialize(self, limit=10):
        dfr = super(UnPlayedMovieController, self).initialize()

        dfr.addCallback(self._load, Movie, limit)
        return dfr

# TV Episodes
class AddedTVEpisodeController(AddedMixin, EpisodeListControllerMixin):
    def initialize(self, limit=10):
        dfr = super(AddedTVEpisodeController, self).initialize()

        dfr.addCallback(self._load, TVEpisode, limit)
        return dfr

class PlayedTVEpisodeController(PlayedMixin, EpisodeListControllerMixin):
     def initialize(self, order_by=None, limit=10):
        dfr = super(PlayedTVEpisodeController, self).initialize()

        dfr.addCallback(self._load, TVEpisode, order_by, limit)
        return dfr

class UnPlayedTVEpisodeController(UnPlayedMixin, EpisodeListControllerMixin):
     def initialize(self, limit=10):
        dfr = super(UnPlayedTVEpisodeController, self).initialize()

        dfr.addCallback(self._load, TVEpisode, limit)
        return dfr


# Added Tracks 
class AddedTracksVerticalWithPreview(AddedTracksController, DoubleLineMenuItemPreviewListController):
    view_mode = DBTracksViewMode

class AddedTracksCoverflow(AddedTracksController, ImageWithReflectionCoverflowController):
    view_mode = DBTracksViewMode

class AddedTracksGrid(AddedTracksController, GridItemGridController):
    view_mode = DBTracksViewMode

class AddedTracksListSwitcherController(ListSwitcherController):
    modes = [AddedTracksVerticalWithPreview,
             AddedTracksCoverflow,
             AddedTracksGrid]
    default_mode = AddedTracksVerticalWithPreview

# Added Movie 
class AddedMovieVerticalWithPreview(AddedMovieController, MenuItemPreviewListController):
    view_mode = MovieViewMode

class AddedMovieCoverflow(AddedMovieController, ImageWithReflectionCoverflowController):
    view_mode = MovieViewMode

class AddedMovieGrid(AddedMovieController, GridItemGridController):
    view_mode = MovieViewMode

class AddedMovieListSwitcherController(ListSwitcherController):
    modes = [AddedMovieVerticalWithPreview,
             AddedMovieCoverflow,
             AddedMovieGrid]
    default_mode = AddedMovieVerticalWithPreview
    
# Played Movie
class PlayedMovieVerticalWithPreview(PlayedMovieController, MenuItemPreviewListController):
    view_mode = MovieViewMode

class PlayedMovieCoverflow(PlayedMovieController, ImageWithReflectionCoverflowController):
    view_mode = MovieViewMode

class PlayedMovieGrid(PlayedMovieController, GridItemGridController):
    view_mode = MovieViewMode

class PlayedMovieListSwitcherController(ListSwitcherController):
    modes = [PlayedMovieVerticalWithPreview,
             PlayedMovieCoverflow,
             PlayedMovieGrid]
    default_mode = PlayedMovieVerticalWithPreview
    
# UnPlayed Movie
class UnPlayedMovieVerticalWithPreview(UnPlayedMovieController, MenuItemPreviewListController):
    view_mode = MovieViewMode

class UnPlayedMovieCoverflow(UnPlayedMovieController, ImageWithReflectionCoverflowController):
    view_mode = MovieViewMode

class UnPlayedMovieGrid(UnPlayedMovieController, GridItemGridController):
    view_mode = MovieViewMode

class UnPlayedMovieListSwitcherController(ListSwitcherController):
    modes = [UnPlayedMovieVerticalWithPreview,
             UnPlayedMovieCoverflow,
             UnPlayedMovieGrid]
    default_mode = UnPlayedMovieVerticalWithPreview


# Added TVEpisode 
class AddedTVEpisodeVerticalWithPreview(AddedTVEpisodeController,
                                        DoubleLineMenuItemPreviewListController):
    view_mode = TVEpisodeViewMode

class AddedTVEpisodeCoverflow(AddedTVEpisodeController,
                              ImageWithReflectionCoverflowController):
    view_mode = TVEpisodeViewMode

class AddedTVEpisodeGrid(AddedTVEpisodeController, GridItemGridController):
    view_mode = TVEpisodeViewMode

class AddedTVEpisodeListSwitcherController(ListSwitcherController):
    modes = [AddedTVEpisodeVerticalWithPreview,
             AddedTVEpisodeCoverflow,
             AddedTVEpisodeGrid]
    default_mode = AddedTVEpisodeVerticalWithPreview
    
# Played TVEpisode
class PlayedTVEpisodeVerticalWithPreview(PlayedTVEpisodeController,
                                         DoubleLineMenuItemPreviewListController):
    view_mode = TVEpisodeViewMode

class PlayedTVEpisodeCoverflow(PlayedTVEpisodeController,
                               ImageWithReflectionCoverflowController):
    view_mode = TVEpisodeViewMode

class PlayedTVEpisodeGrid(PlayedTVEpisodeController, GridItemGridController):
    view_mode = TVEpisodeViewMode

class PlayedTVEpisodeListSwitcherController(ListSwitcherController):
    modes = [PlayedTVEpisodeVerticalWithPreview,
             PlayedTVEpisodeCoverflow,
             PlayedTVEpisodeGrid]
    default_mode = PlayedTVEpisodeVerticalWithPreview
    
# UnPlayed TVEpisode
class UnPlayedTVEpisodeVerticalWithPreview(UnPlayedTVEpisodeController,
                                           DoubleLineMenuItemPreviewListController):
    view_mode = TVEpisodeViewMode

class UnPlayedTVEpisodeCoverflow(UnPlayedTVEpisodeController,
                                 ImageWithReflectionCoverflowController):
    view_mode = TVEpisodeViewMode

class UnPlayedTVEpisodeGrid(UnPlayedTVEpisodeController, GridItemGridController):
    view_mode = TVEpisodeViewMode

class UnPlayedTVEpisodeListSwitcherController(ListSwitcherController):
    modes = [UnPlayedTVEpisodeVerticalWithPreview,
             UnPlayedTVEpisodeCoverflow,
             UnPlayedTVEpisodeGrid]
    default_mode = UnPlayedTVEpisodeVerticalWithPreview


# Played Tracks
class PlayedTracksVerticalWithPreview(PlayedTracksController, DoubleLineMenuItemPreviewListController):
    view_mode = DBTracksViewMode

class PlayedTracksCoverflow(PlayedTracksController, ImageWithReflectionCoverflowController):
    view_mode = DBTracksViewMode

class PlayedTracksGrid(PlayedTracksController, GridItemGridController):
    view_mode = DBTracksViewMode

class PlayedTracksListSwitcherController(ListSwitcherController):
    modes = [PlayedTracksVerticalWithPreview,
             PlayedTracksCoverflow,
             PlayedTracksGrid]
    default_mode = PlayedTracksVerticalWithPreview

# Added Photos 
class AddedPhotosVerticalWithPreview(AddedPhotosController, MenuItemPreviewListController):
    view_mode = PhotoViewMode

class AddedPhotosCoverflow(AddedPhotosController, ImageWithReflectionCoverflowController):
    view_mode = PhotoViewMode

class AddedPhotosGrid(AddedPhotosController, GridItemGridController):
    view_mode = PhotoViewMode

class AddedPhotosListSwitcherController(ListSwitcherController):
    modes = [AddedPhotosVerticalWithPreview,
             AddedPhotosCoverflow,
             AddedPhotosGrid]
    default_mode = AddedPhotosGrid

# Played Photos
class PlayedPhotosVerticalWithPreview(PlayedPhotosController, MenuItemPreviewListController):
    view_mode = PhotoViewMode

class PlayedPhotosCoverflow(PlayedPhotosController, ImageWithReflectionCoverflowController):
    view_mode = PhotoViewMode

class PlayedPhotosGrid(PlayedPhotosController, GridItemGridController):
    view_mode = PhotoViewMode

class PlayedPhotosListSwitcherController(ListSwitcherController):
    modes = [PlayedPhotosVerticalWithPreview,
             PlayedPhotosCoverflow,
             PlayedPhotosGrid]
    default_mode = PlayedPhotosGrid
