# -*- coding: utf-8 -*-
# Elisa - Home multimedia server
# Copyright (C) 2006-2008 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 Elisa with Fluendo's plugins.
#
# The GPL part of Elisa is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Elisa" in the root directory of this distribution package
# for details on that license.

"""
Find a usable Player Engine with the PlayerEngineRegistry
"""

__maintainer__ = 'Benjamin Kampmann <benjamin@fluendo.com>'


from elisa.core import log, common
from elisa.core.utils import classinit
from elisa.core.plugin_registry import PluginNotFound, ComponentNotFound

#import pygst
#pygst.require('0.10')
import gst

class NoEngineFound(Exception):
    pass


class PlayerEngineRegistry(log.Loggable):
    """
    The PlayerEngineRegistry has the responsability to create
    L{elisa.base_components.player_engine.PlayerEngine} instances
    given URI schemes.
    """

    # Allows property fget/fset/fdel/doc overriding
    __metaclass__ = classinit.ClassInitMeta
    __classinit__ = classinit.build_properties

    def __init__(self):
        log.Loggable.__init__(self)
        self._engines_by_scheme = {}
        # FIXME: This should be configurable
        self._audiosink = 'autoaudiosink'
        self._audiosettings = {}


    def initialize(self):
        self.info("Initializing")
        self._load_providers()

    def _load_providers(self):
        """ Ask the plugin registry to create all the providers
        components defined in section 'general' of the config
        """

        # FIXME: the default value is just temporary. Remove it soon!
        application = common.application
        engine_names = application.config.get_option('player_engines',
                                                        section='general',
                                                        default=['base:playbin_engine'])

        plugin_registry = application.plugin_registry

        for name in engine_names:
            try:
                engine_class = plugin_registry.get_component_class(name)
            except (PluginNotFound, ComponentNotFound), error:
                # the class could not be found
                self.warning("Could not find the class for the player engine"
                             " component %s" % name)
                continue

            schemes = engine_class.uri_schemes
            for key, value in schemes.iteritems():
                if key in self._engines_by_scheme.keys():
                    before_engine_class = plugin_registry.get_component_class(
                                                self._engines_by_scheme[key])

                    if before_engine_class.uri_schemes[key] > value:
                        self.debug("Replacing %s with %s for scheme %s" %
                                  ( self._engines_by_scheme[key], name, key) )

                        self._engines_by_scheme[key] = name
                else:
                    self.debug("Adding %s for scheme %s" % (name, key))
                    self._engines_by_scheme[key] = name

    def deinitialize(self):
        pass

    def create_engine_for_scheme(self, scheme):
        """
        Create a B{new} player engine instance for the given URI scheme.

        @param scheme:  the uri scheme that the new engine has to support
        @type scheme:   string

        @raise:         L{elisa.core.player_engine_registry.NoEngineFound}
                        if no engine is found

        @rtype:         L{elisa.base_components.player_engine.PlayerEngine} or
                        None
        """
        self.debug("Creating new engine for %s" % scheme)

        if scheme not in self._engines_by_scheme.keys():
            raise NoEngineFound()

        plugin_registry = common.application.plugin_registry
        component = self._engines_by_scheme[scheme]

        return plugin_registry.create_component(component)
