# -*- 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.

from elisa.core.media_uri import MediaUri
from elisa.core.resource_manager import NoMatchingResourceProvider
from elisa.core import common
import os, platform

if platform.system() == 'Windows':
    from win32com.shell import shellcon, shell

class MediaDirectoryHelper(object):

    def __init__(self):
        self.media_dir = {}

        try:
            if platform.system() == 'Windows':
                self.media_dir = self.get_windows_media_directory()
            else:
                self.media_dir = self.get_linux_media_directory()
        except Exception, e:
            # if retrieving default directories fails log the error and go on
            path = common.application.log_traceback()
            common.application.warning("Retrieving default media directories " \
                                       "failed. Error logged at %s" % path)

        self.refresh_directory_list()

    def get_linux_media_directory(self):
        try:
            from elisa.extern.coherence import xdg
        except ImportError:
            return {}

        media_dir = {}
        xdg_mapping = {'audio': 'music',
                       'images': 'pictures',
                       'videos': 'video'}
        home = os.path.expanduser("~")

        xdg_content = xdg.xdg_content()
        if xdg_content is None:
            return {}

        for d in xdg_content:
            directory_path = d[0]
            if os.path.normpath(directory_path) == home:
                directory_path = None

            key = xdg_mapping.get(d[2], d[2])
            media_dir[key] = directory_path

        return media_dir

    def get_windows_media_directory(self):
        """
        return in a dict the multimedia directories in default encoding
        """

        media_dir = {}

        try:
            not_uri = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, 0, 0)
            mydocs = MediaUri({'scheme': 'file', 'path': not_uri}).path
        except:
            # in worst case what?
            mydocs = ''

        try:
            music_dir = shell.SHGetFolderPath(0, shellcon.CSIDL_MYMUSIC, 0, 0)
            media_dir['music'] = MediaUri({'scheme': 'file', \
                                           'path': music_dir}).path
        except:
            media_dir['music'] = mydocs

        try:
            pictures_dir = shell.SHGetFolderPath(0, shellcon.CSIDL_MYPICTURES, 0, 0)
            media_dir['pictures'] = MediaUri({'scheme': 'file', \
                                              'path': pictures_dir}).path
        except:
            media_dir['pictures'] = mydocs

        try:
            video_dir = shell.SHGetFolderPath(0, shellcon.CSIDL_MYVIDEO, 0, 0)
            media_dir['video'] = MediaUri({'scheme': 'file', \
                                           'path': video_dir}).path
        except:
            media_dir['video'] = mydocs

        return media_dir

    def get_directories(self, media_type):

        directories = common.application.config.get_option(media_type,
                                                           section='directories', default=[])
        #do not display empty directories in the config
        if "" in directories:
            index = directories.remove("")
        if '*default*' in directories and media_type in self.media_dir:
            index = directories.index('*default*')
            probed_directory_path = self.media_dir[media_type]
            if probed_directory_path:
                directories[index] = probed_directory_path
            else:
                directories.remove('*default*')
        return directories

    def refresh_directory_list(self, media_type=None):
        self.directories = {}
        self.all_directories = []
        if media_type == 'music' or media_type == None:
            self.directories['music'] = self.get_directories('music')
            self.all_directories.extend(self.get_directories('music'))
        if media_type == 'video' or media_type == None:
            self.directories['video'] = self.get_directories('video')
            self.all_directories.extend(self.get_directories('video'))
        if media_type == 'pictures' or media_type == None:
            self.directories['pictures'] = self.get_directories('pictures')
            self.all_directories.extend(self.get_directories('pictures'))

    def toggle_directory_installation(self, uri, media_type):
        if uri.path in self.directories[media_type]:
            self.remove_directory(uri, media_type)
        else:
            self.add_directory(uri, media_type)
        self.refresh_directory_list()

    def add_directory(self, uri, media_type):
        #music case
        config = common.application.config
        if media_type in self.media_dir.keys() and uri.path == self.media_dir[media_type]:
            conf_uri = '*default*'
        else:
            conf_uri = uri.path

        dir = self.get_directories(media_type)

        if conf_uri not in dir:
            dir.append(conf_uri)
            config.set_option(media_type, dir, section='directories')

        if media_type in ('music', 'pictures', 'video'):
            resource_manager = common.application.resource_manager
            # FIXME: hardcoded for the media scanner we have
            # FIXME: we can not cancel it after it was added
            scanner_uri = MediaUri("media_scanner://localhost/queue")
            try:
                resource_manager.put(uri, scanner_uri, section=media_type)
            except NoMatchingResourceProvider:
                # media scanner not running
                pass

    def remove_directory(self, uri, media_type):
        config = common.application.config
        if media_type in self.media_dir.keys() and uri.path == self.media_dir[media_type]:
            conf_uri = '*default*'
        else:
            conf_uri = uri.path

        dir = self.get_directories(media_type)

        update = False
        if conf_uri in dir:
            dir.remove(conf_uri)
            update = True
        if uri.path in dir:
            dir.remove(uri.path)
            update = True
        if update == True:
            config.set_option(media_type, dir, section='directories')

    def is_a_media_source(self, uri):
        """
        Test whether a given URI is listed as a known media source.
        All media types are searched.

        @param uri: the URI of a source
        @type uri:  L{elisa.core.media_uri.MediaUri}

        @return: C{True} if the URI is a known media source, C{False} otherwise 
        @rtype:  C{bool}
        """
        for media_type, directories in self.directories.iteritems():
            if uri.path in directories:
                return True
        return False