#!/usr/bin/python3

from subprocess import Popen, PIPE, call
from threading import Thread
import time

# Declarations
# ============

# Default configuration for mplayer control thread
default_config = {
    "streaming_url"    : "http://localhost:9092",
    "per_artist_path"  : "/artist",
    "default_url"      : "",
}

# Queue for player commands
cmd_queue        = []

# Command object
class Cmd(object):
    def __init__(self, name, param={}):
        self.name  =  name
        self.param =  param

# Command names for the queue

# Stream per artist
# Expected parameter: name - Name of the artist
CMD_NEW_ARTIST_STREAM  = "New Artist Stream" 

# Stop current stream
CMD_STOP_STREAM        = "Stop Stream"

# Internal
# ========

# Internal reference to mplayer process
_player_instance = None

# Internal mplayer control table
_mplayer_control = {
    "step-backward" : "\x1B[B",
    "backward"      : "\x1B[D", 
    "forward"       : "\x1B[C", 
    "step-forward"  : "\x1B[A",
    "volume-down"   : "9", 
    "volume-off"    : "m", 
    "volume-up"     : "0",
    "stop"          : "q", 
    "pause"         : " ", 
    "play"          : " ",
}

# Internal config
_config = None

def run():
    global _player_instance, _config, _mplayer_control

    while True:
        try:

            # Read the next command

            cmd = cmd_queue.pop()

        except IndexError:

            # If nothing is in the queue wait for a second and try again

            time.sleep(1)

        else:
            if cmd.name == CMD_STOP_STREAM:

                # Stop the current stream

                _stopPlayer()

            if cmd.name == CMD_NEW_ARTIST_STREAM:

                # Stop any current stream

                _stopPlayer()

                #  Start a new player with the given artist playlist

                _player_instance = Popen(["mplayer", "-slave", _config["streaming_url"] + 
                    _config["per_artist_path"] + "/" + cmd.param["name"]], stdin=PIPE)

def _stopPlayer():
    '''
    Stop A running player instance.
    '''
    global _player_instance, _mplayer_control

    if _player_instance is not None:
        _player_instance.stdin.write(bytes(_mplayer_control["stop"], "UTF-8"))
        _player_instance.stdin.flush()
        _player_instance.terminate()
        _player_instance = None

# Main API
# ========

def start(config=None):
    '''
    Start the new mplayer control thread.
    '''
    global _config, _player_instance

    c = default_config.copy()
    if config is not None:
        c.update(config)

    _config = c

    playerThread = Thread(target=run, args=())
    playerThread.daemon = True
    playerThread.start()

    # Start default playlist if defined

    d = config["default_url"]
    if d != "":
        _player_instance = Popen(["mplayer", "-slave", d], stdin=PIPE)
