#!./bin/python3

import threading
import time

from handler import EVENT_LEFT
from handler.listhandler import BaseListHandler
from handler.lib.pymplb import MPlayer

class FileListHandler(BaseListHandler):

    def __init__(self, config, display):
        super().__init__(config, display)
        self._mplayer = None
        self._mplayer_watcher = None
        self.is_playing = False
        self._last_event = time.time()


    def setPlaylistItem(self, item):
        '''
        Called with the selected item.
        '''
        super().setPlaylistItem(item)

        if self._mplayer is None:
            self._mplayer = MPlayer()
            self.setItems(self.getPlaylistItems(item))
            self._mplayer_watcher = threading.Thread(target=self._watch_mplayer, daemon=True)
            self._mplayer_watcher.start()

        self.is_playing = False


    def getPlaylistItems(self, item):
        raise NotImplementedError()


    def update(self, text=None, highlight=-1, title=None, img=None):
        '''
        Called when the handler should update the display.
        '''
        super().update(title=[
            "",
            "Playlist:",
            self.item["name"],
            "[play]" if self.is_playing else "[stop]"
        ], img=self.item.get("img"))


    def itemSelected(self, item):
        self._mplayer.loadfile(item["path"])
        self.is_playing = True


    def stop(self):
        '''
        Called when the handler should stop.
        '''
        if self._mplayer is not None:
            self._mplayer.quit()
            self._mplayer = None
            self._mplayer_watcher = None


    def emitEvent(self, event):
        '''
        Called when an event has happened.
        '''

        # Clock the time so the thread can hold off if there
        # was a recent user event

        self._last_event = time.time()

        if event == EVENT_LEFT and self.is_playing:
            self._mplayer.stop()
            self.is_playing = False
            return

        super().emitEvent(event)


    def _watch_mplayer(self):
        '''
        Thread to watch mplayer and advance the playlist.
        '''

        while self._mplayer_watcher is not None:

            try:
                time.sleep(0.5)

                if self._mplayer:
                    playing_path = self._mplayer.p_path

                    # Only do something in the thread if the last user
                    # input is at least 3 seconds ago

                    if time.time() - self._last_event > 3:

                        # Advance to the next item if we are playing music

                        if self.is_playing and playing_path == "(null)":
                            self.nextItem()

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