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

"""
Player instances access and global players control
"""

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


from elisa.core import log, player
from elisa.core.utils import classinit

from elisa.core.player_engine_registry import PlayerEngineRegistry


class PlayerRegistry(log.Loggable):
    """
    The PlayerRegistry has responsability to create and hold
    L{elisa.core.player.Player} instances. Additionally it can perform
    global actions on all the players at the same time.

    Player instances are identified by their name, which must be unique, this
    is the responsability of the developer.

    @ivar _players:                 currently instantiated players
    @type _players:                 list of L{elisa.core.player.Player} 

    @type _player_engine_registry: the L{elisa.core.player_engine_registry.PlayerEngineRegistry}
    """

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

    def __init__(self):
        log.Loggable.__init__(self)
        self._players = []
        self._simple_player = None
        self._id_counter = 0
        self._player_engine_registry = PlayerEngineRegistry()

    def initialize(self):
        """
        """
        self._player_engine_registry.initialize()
        self._simple_player = self.create_player()
        self._simple_player.videosink = None
        self.info("Initializing")

    def deinitialize(self):
        """
        """
        self._player_engine_registry.deinitialize()

    def create_player(self):
        """
        Returns a new player instance.

        @rtype:      L{elisa.core.player.Player}
        """

        self.debug("Creating new player")
        self._id_counter += 1
        p = player.Player(self._player_engine_registry)
        p.name = "player_%s" % self._id_counter
        self._players.append(p)
        return p

    def remove_player(self, player_instance):
        """
        Remove player_instance Player

        @param player_instance: Player instance to remove
        @type player_instance:  L{Player}
        """
        for i in self._players:
            if i == player_instance:
                self._players.remove(i)
                break

    def _global_action(self, method_name, *params):
        for player_instance in self._players:
            method = getattr(player_instance, method_name)
            method(*params)

    def play_sound(self, uri):
        """
        Play the sound located at L{uri}. If the simple audio player is already
        playing, the playback is stopped. The playback of the other players is
        B{not} touched in any way.

        @param uri:     the uri of the sound to play
        @type uri:      L{elisa.core.media_uri.MediaUri}
        """
        self._simple_player.uri = uri
        self._simple_player.play(trigger_message = False)

    def play_all(self):
        """
        Set all players into playing mode.
        """
        self._global_action("play")

    def pause_all(self):
        """
        Pause all players.
        """
        self._global_action("pause")

    def stop_all(self):
        """
        Stop all currently instantiated players.
        """
        self._global_action("stop")

    def mute_all(self):
        """
        Mute all players.
        """
        self._global_action("muted__set", True)

    def unmute_all(self):
        """
        Unmute all players.
        """
        self._global_action("muted__set", False)
