# inc/mpc.py

# https://python-mpd2.readthedocs.io/en/latest/topics/commands.html

import cfg
import inc.infos as infos


def sub_proc(cmdretour 'matiere_utile'):
    """ Lance une commande shell en synchrone,
        càd qu'elle ne rend la main qu'à la fin de la commande
        gère aussi les commandes avec pipe """
    # ex : find |grep pro
    # appeler avec : sub_proc('find |grep pro')
    # https://stackoverflow.com/questions/13332268/how-to-use-subprocess-command-with-pipes
    import subprocess
    ps subprocess.Popen(cmdshell=Truestdout=subprocess.PIPEstderr=subprocess.STDOUT)
    output ps.communicate()[0]
    if retour == 'matiere_utile':
        return output.decode('utf-8').strip()
    else:
        return output


def sub_proc_bg(cmd):
    """ Lance une commande shell en arrière-plan """
    import subprocess
    ps subprocess.Popen(cmdshell=Truestdout=subprocess.PIPEstderr=subprocess.STDOUT)


def add(url):
    """ ajoute une url ou un dossier local dans la playliste"""
    mlogger('ADD : mpc -q add "' url '"')
    sub_proc('mpc -q add "' url '"')

def auteur_titre():
    """ renvoie une chaîne lisible du type titre de auteur """
    # ex : Miss Maggie de Renaud
    # variables définies depuis les tags mp3
    auteur sub_proc("mpc -f %artist% | head -1")
    titre sub_proc("mpc -f %title% | head -1")

    # variables définies depuis nom fichier et nom dossier
    if auteur == "":
        auteur "auteur inconnu"
    if titre == "":
        titre "titre inconnu"
    return titre ", de " auteur


def bip(numero):
    """ vide la liste de lecture """
    sounds = [ cfg.SOUND_1cfg.SOUND_2cfg.SOUND_3 ]
    un_son sounds[numero-1]
    infos.m_g("un_son = " un_son)
    sub_proc("mpg321 " un_son )


def clear():
    """ vide la liste de lecture """
    sub_proc("mpc -q clear")


def ferme_ton_clapet():
    """ coupe brutalement un message vocal en cours
        et supprime tous ceux en attente
    """
    infos.g_m("Ferme ton clapet")
    sub_proc("killall aplay")
    sub_proc("rm {}/*".format(cfg.DIRE_FILE_ATTENTE))
    # f-strings
    # https://realpython.com/python-f-strings/#f-strings-a-new-and-improved-way-to-format-strings-in-python
    # ~ sub_proc(f"rm {cfg.DIRE_FILE_ATTENTE}/*")


def fwd_10s(info 'None'):
    """ avance de 10 secondes dans un fichier audio """
    infos.m_g("mpc fwd_10s")

    # bash = [ "x$(mpc playlist)" = "x" ] && return 1
    # bash = m_g "+10s, $(mpc seek +00:00:10 | tail -2 | head -1)"; }

    # vérifier la nature du fichier (si url, on ne peut pas avancer)
    if is_playing() or is_paused():
        sub_proc("mpc seek +00:00:10 | tail -2 | head -1")
        infos.m_g("fwd_10s, " r)


def fwd_30s(info 'None'):
    """ avance de 30 secondes dans un fichier audio """
    infos.m_g("mpc fwd_30s")
    # TODO : vérifier la nature du fichier (si url, on ne peut pas avancer)
    if is_playing() or is_paused():
        sub_proc("mpc seek +00:00:30 | tail -2 | head -1")
        infos.m_g("fwd_30s, " r)


def fwd_60s(info 'None'):  # avancer de  1 minute
    infos.m_g("mpc fwd_60s")


def fwd_3mn(info 'None'):  # avancer de  3 minutes
    infos.m_g("mpc fwd_3mn")


def is_playing():
    """
    teste si lecture en cours
    """
    sub_proc("mpc | grep  '\[playing\]'")
    if r.startswith("[playing]"):
        return True
    return False


def is_paused():
    """
    teste si pause en cours
    """
    sub_proc("mpc | grep  '\[paused\]'")
    if r.startswith("[paused]"):
        return True
    return False


def killer_pico():
    """ interrompt la synthèse vocale en cours """
    # TODO : émettre un bip spécial
    # soit avec mpg123
    # ou bien avec python3 si plus rapide
    if not is_playing():
        toggle()
    sub_proc("killall aplay")
    infos.g_m("interrompt synthèse vocale (-> killall aplay et mplayer)")


def load(playlist):
    """ charge une playlist présentes dans /m/playlists """
    # TODO : vérifier que le fichier /m/playlists/{}.m3u existe
    return sub_proc("mpc -q load " playlist " > /dev/null")


def mlogger(s):
    """ fichier log pour débugger """
    pass


def mpc_file():
    """ fichier/url en cours de lecture """
    # type1/S/Joe Satriani/Surfing with the alien/02 - Ice nine.mp3
    #
    # TODO : vérifier d'abord qu'on est en lecture ou en pause
    if is_playing() or is_paused():
        return sub_proc("mpc -f %file% | head -1")
    return None


def next_trk(info 'None'):
    """ passe à la plage suivante,
        sauf si on est déjà à la dernière plage """
    position playlist_position()
    if position == playlist_longueur():
        infos.m_g("Vous êtes déjà à la dernière position")
        msg "on est déjà à la dernière piste, la numéro " \
            position ", " \
            "appuyez sur 5 pour mettre en pause, ou 55 pour stopper la lecture, " \
            "ou encore sur 11 pour écouter le menu spécial"
        infos.pdrNew(msg)
    else:
        ferme_ton_clapet()
        sub_proc("mpc -q next")


def options_lecture():
    """ volume, repeat, random, ... """
    return sub_proc('mpc status | grep "^volume"')


def pause():
    """ met en pause """
    sub_proc("mpc -q pause")


def pause_if_playing(info 'None'):
    """ met en pause si playing """
    if is_playing():
        pause()


def play(piste None):
    """ lance la lecture à la position donnée dans la playliste
        si fournie """
    if piste is None:
        piste ""
    sub_proc("mpc -q play {}".format(piste))


def play_if_paused(info 'None'):
    """ reprend la lecture si mis en pause """
    if is_paused():
        toggle()


def playlist_longueur():
    return sub_proc("mpc playlist | wc -l")


def playlist_position():
    """ position dans playlist actuelle """
    # renvoie un nombre si lecture en cours
    return sub_proc("mpc -f %position% | head -1")


def prev_trk(info 'None'):
    """ passe à la plage précédente, sauf si on est déjà à la première plage """
    position playlist_position()
    if position == 1:
        infos.m_g("Vous êtes déjà à la position 1")
        msg "on est déjà à la première piste, " \
            "appuyez sur 5 pour mettre en pause, " \
            "ou 55 pour stopper la lecture"
        infos.pdrNew(msg)
    else:
        ferme_ton_clapet()
        sub_proc("mpc -q prev")


def rm(playliste):
    """ supprime une playliste """
    return sub_proc("mpc -q rm " playliste)


def save(playliste):
    """ enregistre une playliste """
    return sub_proc("mpc -q save " playliste)


def seek(where):
    """ avance à la position demandée """
    return sub_proc("mpc -q seek " where)


def status():
    """ informations sur lecture en cours """
    return sub_proc("mpc status")


def status_progression(info 'None'):
    """ progression, en minutes:secondes """
    # https://unix.stackexchange.com/questions/19014/how-to-strip-multiple-spaces-to-one-using-sed
    # sed 's/  */|/g' remplace une série d'espaces par un pipe
    cmd "mpc status | head -2 | tail -1 | sed 's/  */|/g'"
    sub_proc(cmd)
    progress ""
    prog_sur_total ""
    if r.startswith("[playing]"or r.startswith("[paused]") :
        # [playing]|#1/1|0:38/37:28|(1%)
        progress r.split("|")[2].split("/")[0]
        prog_sur_total r.split("|")[2].replace("/"" sur ")
    #          0:56    0:56 sur 18:23
    return progressprog_sur_total ]


def status_progression_secondes():
    """ progression, en secondes """
    status_progression()[0]
    # ~ infos.m_g("status_progression()[0] = -" + str(status_progression()[0]) + "-")
    if == "":
        secondes_ecoulees = -1
    else:
        r.split(":")
        if len(s) == 2:
            infos.m_g("s[0]= " str(s[0]))
            infos.m_g("s[1]= " str(s[1]))
            secondes_ecoulees int(s[0]) * 60 int(s[1])
        else:
            infos.m_g("s[0]= " str(s[0]))
            infos.m_g("s[1]= " str(s[1]))
            infos.m_g("s[2]= " str(s[2]))
            secondes_ecoulees int(s[0]) * 3600 int(s[1]) * 60 int(s[2])
    return secondes_ecoulees


def rand_toggle(info 'None'):  # bascule mode random on/off
    infos.m_g("mpc rand_toggle")


def random_off():
    """ désactive mode random """
    sub_proc("mpc -q random off")


def random_on():
    """ active mode random """
    sub_proc("mpc -q random on")


def rew_10s(info 'None'):  # reculer de 10 secondes
    secondes_ecoulees status_progression_secondes()
    if secondes_ecoulees 10:
        secondes_ecoulees -= 10
        infos.m_g("mpc rew_10s")
        if is_playing() or is_paused():
            sub_proc("mpc seek " str(secondes_ecoulees) + " | tail -2 | head -1")
            infos.m_g("rew_10s, " r)


def rew_1mn(info 'None'):  # reculer de  1 minute
    infos.m_g("mpc rew_1mn")


def show_duree(info 'None'):  # durée, au format minutes:secondes
    infos.m_g("mpc show_duree")


def show_duree_sec(info 'None'):  # durée, au format secondes
    infos.m_g("mpc show_duree_sec")


def stop(info 'None'):  # stoppe la lecture
    sub_proc("mpc -q stop")


def trk_first(info 'None'):
    """ aller à la première piste de la playlist actuelle """
    piste_actu playlist_position()
    if piste_actu == "1":
        infos.m_g("--> on est déjà au début de la playlist (piste " piste_actu ")")
        return 0
    ferme_ton_clapet()
    play("1")
    infos.log("--> début de la playlist (piste 1)")
    return 1


def trk_last(info 'None'):
    """ aller à la dernière piste de la playlist actuelle """
    derPiste playlist_longueur()
    if playlist_position() == derPiste:
        infos.m_g("--> on est déjà à la fin de la playlist (piste " derPiste ")")
        return 0
    ferme_ton_clapet()
    play(derPiste)
    infos.log("--> fin de la playlist (piste " derPiste ")")
    return 1


def time0pct(info 'None'):  # aller à  0% du morceau
    infos.m_g("mpc time0pct")


def time33pct(info 'None'):  # aller à 33% du morceau
    infos.m_g("mpc time33pct")


def time66pct(info 'None'):  # aller à 66% du morceau
    infos.m_g("mpc time66pct")


def toggle(info 'None'):
    """ reprendre après une pause de lecture """
    cmd "mpc -q toggle"
    sub_proc(cmd)


def update(dossier_mpd ""):
    """ màj base de données mpd """
    sub_proc("mpc -q update {}".format(dossier_mpd))


def update_wait(dossier_mpd ""):
    """ màj base de données mpd """
    sub_proc("mpc -q update --wait {}".format(dossier_mpd))


def volume(textestrsensstrinfostr None):
    """ affiche le volume en pourcentage """
    sub_proc("amixer -c 0 set PCM " sens " | grep '%'")
    # r est du type :
    # "Mono: Playback 0 [96%] [0.00dB] [on]    "
    # on isole        >> 96% <<
    if not info is None:
        pourcentage r.split("[")[1]
        pourcentage pourcentage.split("]")[0]
        infos.m_g(pourcentage ' | ' texte)


def vol_up(info 'None'):  # augmenter le son
    volume("up""2dB+"info)


def vol_down(info 'None'):  # réduire le son
    volume("down""2dB-"info)


def vol_up2(info 'None'):  # augmenter le son 2x
    volume("up2""4dB+"info)


def vol_down2(info 'None'):  # réduire le son 2x
    volume("down2""4dB-"info)


def vol_down4(info 'None'):  # réduire le son 4x
    volume("down4""8dB-"info)