#!/usr/bin/python3

import os
import time
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont

from .locale_fix import locale_set_english

def NOOP(*args, **kwargs):
    pass


SCRIPT_PATH = Path(os.path.dirname(os.path.realpath(__file__)))

"""
Attempt to import the system's libmpv. If there is none, use the bundled binary

DISABLED because it is experimental
"""
# os.environ['LD_LIBRARY_PATH'] = os.environ.get('LD_LIBRARY_PATH', '') + ':' + str(SCRIPT_PATH.absolute() / "lib")
import mpv as mpvlib


class MPVPlayer:
    def __init__(self, config_dir=None):
        self.font = ImageFont.truetype('DejaVuSans.ttf', 40)
        self.config_dir = config_dir
        self.overlay = None
        self.mpv = self._instance_mpv()
        self.install_observers()
        self.callbacks = {
            'pause': NOOP,
            'play': NOOP,
            'quit': NOOP,
        }
        self.playing = False
        self.last_playpause = 2.0 # Seconds time.time(), initialize in the far past

    def get_time(self):
        """
        Return time position
        """
        return self.mpv.time_pos

    def play_path(self, path):
        self.mpv.play(path)
        self.pause()

    def pause(self):
        self._set_playpause()
        self.mpv.command('set', 'pause', 'yes')
        # self.mpv.wait_until_paused()

    def play(self):
        self._set_playpause()
        self.mpv.command('set', 'pause', 'no')
        # self.mpv.wait_until_playing()

    def seek_absolute(self, position):
        self.mpv.seek(position, reference='absolute', precision='exact')

    def _instance_mpv(self):
        locale_set_english() # MPV dislikes anything else and seg-faults
        kwargs = {
            'input_vo_keyboard'      : True,
            'osc'                    : True,
            'start_event_thread'     : True,
            'log_handler'            : self.my_log,
            'ytdl'                   : True,
            'input_default_bindings' : True,
            'keep_open'              : True,
        }
        if self.config_dir:
            kwargs['config_dir'] = self.config_dir

        mpv = mpvlib.MPV(**kwargs)
        mpv.loop_playlist = 'inf'
        return mpv

    def set_on_play(self, callback):
        self.callbacks['play'] = callback

    def set_on_pause(self, callback):
        self.callbacks['pause'] = callback

    def set_on_quit(self, callback):
        self.callbacks['quit'] = callback

    def my_log(self, loglevel, component, message):
        print(f"[{loglevel}] {component}: {message}")
        
    def show_message(self, text:str):
        """
        Text is an string containing the message to show
        If text is None → Hide the message box
        """
        if text is None:
            self._overlay_remove()
            return

        self._overlay_create()

        img = Image.new('RGBA', (400, 150),  (255, 255, 255, 0))
        d = ImageDraw.Draw(img)
        d.text((10, 10), text, font=self.font, fill=(0, 255, 255, 128))

        self.overlay.update(img, pos=(0, 0))

    def _overlay_create(self):
        if not self.overlay:
            self.overlay = self.mpv.create_image_overlay()

    def _overlay_remove(self):
        if self.overlay:
            self.overlay.remove()
            self.overlay = None

    def install_observers(self):
        self.mpv.observe_property('core-idle', self._on_play_pause)
        self.mpv.observe_property('shutdown', self._on_quit)

    def _set_playpause(self):
        self.last_playpause = time.time()

    def _on_quit(self, name, value):
        if value:
            self.callbacks['quit'](name, value)

    def _on_play_pause(self, name, is_paused):
        sensitivity = 0.2 # Seconds
        now = time.time()
        if now > self.last_playpause + sensitivity:
            if not is_paused:
                self.callbacks['play'](name, self.playing)
            else:
                self.callbacks['pause'](name, self.playing)
