#!./bin/python3

import time
import threading

import pygame # type: ignore
from display import Display
from typing import Dict
from pymplb import MPlayer

class Player(Display):
    '''
    Player object which interacts with mplayer.
    '''
    def __init__(self, config, pydsp):
        super().__init__({
            "dimx"     : config.get("dimx"),
            "dimx"     : config.get("dimy"),
            "playlist" : config.get("dimy"),
            "fontsize" : config.get("fontsize"),
        }, pydsp)

        self.playing = False # Flag if the player is playing
        self._playingItem = None
        self._playingPlaylist = None # Current playing order

        self._data = [] # Current playlist

        self._player = MPlayer() # Reference to mplayer control object

        threading.Thread(target=self._updateFromPlayer, daemon=True).start()

    def _updateFromPlayer(self):
        '''
        Thread to update the player display from the state of mplayer.
        '''
        font = pygame.font.Font('freesansbold.ttf', int(self._fontsize))

        while True:

            try:
                time.sleep(0.5)

                if self.playing:
                    player_playing = self._player.p_path

                    # Update playlist display if the current song has changed
                    # and the item can be found in the current playlist

                    if player_playing != self._playingItem.get("path"):

                        for i, item in enumerate(self._data):
                            if item.get("path") == player_playing:
                                self._selection_pointer = i
                                self._current_item = item
                                self.update()

                    # Start the playlist again if the player ran out of items

                    if player_playing == "(null)":
                        for item in self._playingPlaylist:
                            self._player.loadfile(item["path"], 1)

            except Exception as e:
                print("Error update from player:", e)


    def setPlaylist(self, data: Dict):
        '''
        Set the playlist for this player.
        '''
        self._bgImg = None
        self._selection_pointer = 0
        self._data = data

    def getPlaylist(self) -> Dict:
        '''
        Return the playlist for this display.
        '''
        return self._data

    def togglePlay(self):
        '''
        Toggle playing the selected item.
        '''
        if not self._current_item:
            return

        if self._player.p_path == self._current_item["path"]:

            # Stop what is currently playing

            self.playing = False
            self._player.stop()

        else:
            ci = self._current_item["path"]

            self._playingPlaylist = []

            # Build up the playlist in mplayer in the correct order

            add = 0
            for item in self._data:

                if item == self._current_item:
                    self.playing = True
                    self._playingItem = item
                    self._player.loadfile(item["path"])
                    self._playingPlaylist.append(item)
                    add = 1

                elif add == 1:
                    self._player.loadfile(item["path"], 1)
                    self._playingPlaylist.append(item)

            for item in self._data:

                if item != self._current_item:
                    self._player.loadfile(item["path"], 1)
                    self._playingPlaylist.append(item)

                else:
                    break
