# mod/zik.py

# équivalent bash = /run/user/1000/gvfs/sftp:host=192.168.1.12/opt/jk2019/tout/inc/mod/zik.sh

# one-liner pour vérifier favoris :
# x="-----------------------"; echo "$x"; nl /m/playlists/zik_memo; echo "$x"; nl /m/memo/zik/py_memo_zik.txt; echo "$x"
import cfg
import inc.infos as infos
import inc.mpc as mpc
import mod.commun as commun


def add_fav():  # ajouter l'élément courant à la playlist courante
    pass


def az_sort():  # ordonné
    pass


def az_shuf():  # mélangé
    infos.m_g("zik az_shuf")
    # infos.pdrNew(["", "Lecture au hasard"])

    mpc.stop()
    infos.pdrNew(["", "Lecture au hasard"])

    mp3_az(cfg.MOUNT_USB, "shuf")


def taches_courantes():  # aide module succincte
    pass


def change_fav():  # Change la liste de favoris en cours
    pass


def chg_type():  # changer type de musique
    infos.m_g("zik chg_type")


def favoris_bannis(file_relative, operation, num_favori):
    """ gère les favoris et les bannis
        qui sont en fait deux listes de mémoire

        file_relative : chemin de fichier .mp3 relatif à /m/music
        operation :
    """
    SEP = ","

    def add_ban_fav(file_relative):
        """ ajoute le favori si absent du fichier playlist favoris """
        # rappel : /m/playlists/py_zik_fav_1.m3u
        playlist_fav = "{}/{}_{}.m3u".format(cfg.PLAYLISTS_PATH, cfg.ZIK_FAV, num_favori)
        ligne_presente = False
        nb_favoris = 0
        len_lignes = 0
        if commun.file_exists(playlist_fav):
            with open(playlist_fav, "r") as f:
                lignes = f.readlines()
            len_lignes = len(lignes)
            for ligne in lignes:
                if ligne.strip() == file_relative:
                    ligne_presente = True
                    break

        if ligne_presente == False:
            with open(playlist_fav, "a") as f:
                f.write("\n" + file_relative)
            nb_favoris = len_lignes + 1
            return nb_favoris, "Ajout favoris {} de {}".format(num_favori, file_relative)
        else:
            # TODO : remplacer le bip par un énoncé du nombre de favoris présents
            #        et éventuellement un check de la présence des fichiers pointés
            mpc.bip(2)
            return len_lignes, "Favori '{}' déjà présent dans '{}'".format(file_relative, playlist_fav)

    def del_ban_fav(file_relative):
        """ supprime le favori, si présent, du fichier playlist favoris """
        playlist_fav = "{}/{}_{}.m3u".format(cfg.PLAYLISTS_PATH, cfg.ZIK_FAV, num_favori)
        ligne_presente = False
        len_lignes = 0
        if commun.file_exists(playlist_fav):
            with open(playlist_fav, "r") as f:
                lignes = f.readlines()
            len_lignes = len(lignes)
            reecrire = []
            for ligne in lignes:
                ligne_stripped = ligne.strip()
                if ligne_stripped == file_relative:
                    ligne_presente = True
                else:
                    reecrire.append(ligne_stripped)

        if ligne_presente == True:
            with open(playlist_fav, "w") as f:
                f.write("\n".join(reecrire))
            return len(reecrire), "Suppression des favoris de {}".format(file_relative)
        else:
            mpc.bip(2)
            return len_lignes, "{} déjà absent des favoris".format(file_relative)

    ################################################
    #               favoris / bannis               #
    ################################################
    if operation == "add_fav":
        return add_ban_fav(file_relative)
    elif operation == "del_fav":
        return del_ban_fav(file_relative)


# gestion des favoris et des bannis
def fav_add():
    """ ajoute ce type de ligne au fichier favoris :
        type1/S/Joe Satriani/Surfing with the alien/02 - Ice nine.mp3 """
    infos.pdrNew([ "", "ajout aux favoris"])
    nb_favoris, r = favoris_bannis(mpc.mpc_file(), "add_fav", 1)
    zlogger("fav_add, {} favoris, {}".format(nb_favoris, r))


def fav_del():
    """ supprime ce type de ligne du fichier favoris :
        type1/S/Joe Satriani/Surfing with the alien/02 - Ice nine.mp3 """
    infos.pdrNew([ "", "suppression des favoris"])
    nb_favoris, r = favoris_bannis(mpc.mpc_file(), "del_fav", 1)
    zlogger("fav_del, {} favoris, {}".format(nb_favoris, r))


def fav_menu():
    """ lance le menu vocal fav_ban """
    explic = "utiliser les touches 1 à {} pour gérer vos favoris, " + \
        " zéro pour sortir de ce menu, " + \
        "Entrée pour valider la commande entendue"
    commun.menu_vocal("zik_fav_ban", "favoris et indésirables", explic)


def fav_play():
    """ Jouer les favoris """
    mpc.ferme_ton_clapet()
    mpd_pl_fav = cfg.ZIK_FAV + "_1"
    mpc.clear()
    mpc.load(mpd_pl_fav)
    mpc.random_off()
    mpc.play()
    msg = "Lecture des {} favoris".format(mpc.playlist_longueur())
    infos.pdrNew(msg)


def fav_play_random():
    """ Jouer les favoris dans le désordre """
    mpc.ferme_ton_clapet()
    mpd_pl_fav = cfg.ZIK_FAV + "_1"
    mpc.clear()
    mpc.load(mpd_pl_fav)
    mpc.random_on()
    mpc.play()
    msg = "Lecture des {} favoris dans le désordre".format(mpc.playlist_longueur())
    infos.pdrNew(msg)


def fwd_30s():
    """ avance de 30 secondes """
    mpc.fwd_30s()


def infos_fav():  # les favoris n comptent 15 lignes
    pass


def keepcd():  # 11 : Jouer seulement les mp3 du dossier en cours
    infos.m_g("zik Jouer seulement les chansons du dossier en cours")
    cmd = "dirname \"$(mpc -f %file% | head -1)\""
    infos.m_g("keepcd, cmd              = " + cmd)
    dossier_en_cours = mpc.sub_proc(cmd)
    infos.m_g("keepcd, dossier_en_cours = " + dossier_en_cours)
    mpc.ferme_ton_clapet()
    mpc.clear()
    mpc.add(dossier_en_cours)
    # TODO : reprendre soit au début de l'album, soit la plage en cours
    mpc.play()


def keepcdprt():  # 22 : Jouer seulement les mp3 du dossier PARENT en cours
    infos.m_g("zik Jouer seulement les chansons du dossier en amont")
    cmd = "dirname \"$(dirname \"$(mpc -f %file% | head -1)\")\""
    infos.m_g("keepcd, cmd              = " + cmd)
    dossier_en_cours = mpc.sub_proc(cmd)
    infos.m_g("keepcd, dossier_en_cours = " + dossier_en_cours + '/..')
    mpc.ferme_ton_clapet()
    mpc.clear()
    mpc.add(dossier_en_cours)
    # TODO : reprendre soit au début de l'album, soit la plage en cours
    mpc.play()


def memo_stop_module():
    """ TODO quitter module (touche 0) : mémoriser où on est """
    zik_memo("save_playlist")
    zik_memo("save_position_et_progression")
    ######################## version bash #############################
    #  if [ "x$(mpc playlist)" = "x" ]; then  # mpc queued ne fonctionne qu'en version 0.29, pas 0.28
    #   # playlist vide, on ne mémorise rien
    #   :
    #  elif [ "x$(mpc -f %position% | head -1 | cut -f1 -d':')" = "xvolume" ]; then
    #   # playlist fournie mais position indéfinie
    #   :
    #  else
    #   # on mémorise où on est dans le module musique
    #   mpc rm ${PL_ZIK_MEMO}
    #   mpc save ${PL_ZIK_MEMO}
    #   positionPlaylist=$(mpc -f %position% | head -1)
    #   positionMorceau="$(showProgSec)"
    #   echo "$(mpc status | grep "#  volume:")|${numFav}|${positionPlaylist}|${positionMorceau}" > ${fileZikPosMoment}
    #  fi
    ######################## fin     bash #############################
    infos.m_g("Mémoriser état du module zik avant stop")


def menu_voc11():
    """ menu spécial zik """
    commun.menu_vocal("zik_special11", "musique")


def play_all():
    infos.pdrNew(["", "Lecture globale au hasard"])
    mp3_az(cfg.MOUNT_USB, "shuf", "non")


def mp3_az(dossier, ordre, demander = "oui"):  # joue dossier selon lettre demandée
# dossier : dossier source (/m ou bien /m_SDcard)
# ordre   : sort ou shuf
# ~ typeAction=écoute_mp3_az_$2
    chiffres_lettres = {
         "1": "A",  "2": "B",  "3": "C",  "4": "D",  "5": "E",
         "6": "F",  "7": "G",  "8": "H",  "9": "I", "10": "J",
        "11": "K", "12": "L", "13": "M", "14": "N", "15": "O",
        "16": "P", "17": "Q", "18": "R", "19": "S", "20": "T",
        "21": "U", "22": "V", "23": "W", "24": "X", "25": "Y", "26": "Z"
    }
    lettre = ""
    if demander == "oui":
        infos.pdrNew(["",
            "tapez un nombre de 1 à 26, puis Entrée " + \
            "(Entrée seul pour inclure toutes les lettres)"])
        lettre = input("")
    if lettre in chiffres_lettres.keys():
        mp3_lettre(dossier, chiffres_lettres.get(lettre), ordre)
    elif lettre == "":
        mp3_lettre(dossier, "", ordre)


def mp3_lettre(dossier, lettre, ordre):
    """ Joue dossier selon dossier source et lettre """
    mpc.ferme_ton_clapet()
    mpc.clear()

    if ordre == "shuf":
        mpc.random_on()
    else:
        mpc.random_off()

    ZIKROOT="type1"
    if lettre == "":
        # ajouter toutes les lettres
        for lettre in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
            mpc.add(ZIKROOT+ "/" + lettre)
        infos.m_g("mpc -q add " + ZIKROOT+ "/A, " + ZIKROOT+ "/B, ..., " + ZIKROOT + "/Z")
    elif lettre in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
        mpc.add(ZIKROOT+ "/" + lettre)

    # symbole note de musique ici :
    # m_g "♫ dernier élément de la playlist : $(mpc playlist | nl | tail -1)" # voir le dernier élément de la playlist
    mpc.play()
    zik_infos_go()

    # intérêt ope_en_cours : si on appuie sur 00, on obtient de l'aide pour la navigation dans la lecture
    # infos.ini_file_set(cfg.CONFIG_INI, "ope_en_cours", "lecture")


def prev_trk():
    mpc.prev_trk()
    zik_infos_go("prev")


def next_trk():
    mpc.next_trk()
    zik_infos_go("next")


def random_trk():
    """ aller à une piste de la playliste au hasard """
    infos.m_g("TODO aller à une piste de la playliste au hasard")


def rebours():
    infos.m_g("Programmer un arrêt de la musique")


def rem_fav():  # remove from favorites
    pass


def rew_10s():
    """ recule de 10 secondes """
    mpc.rew_10s()


def zik_memo(operation):
    """ renvoie variables, fichier de mémorisation,
        ou effectue des opérations de mémorisation
    """
    if operation == "playlist":
        # fichier m3u pour mémoriser la playliste en cours
        zlogger("zik memo GET playlist : " + cfg.PL_ZIK_MEMO)
        return cfg.PL_ZIK_MEMO

    elif operation == "playlist_file":
        # fichier m3u pour mémoriser la playliste en cours
        f = cfg.PLAYLISTS_PATH + "/" + cfg.PL_ZIK_MEMO + ".m3u"
        zlogger("zik memo GET playlist : " + f)
        return f

    elif operation == "save_playlist":
        # sauvegarde mpd de la playlist en cours
        zlogger("zik memo --> SAVE playlist : mpc -q save " + cfg.PL_ZIK_MEMO)
        mpc.rm(cfg.PL_ZIK_MEMO)
        mpc.save(cfg.PL_ZIK_MEMO)

    elif operation == "save_position_et_progression":
        # sauvegarde dans "/m/memo/zik/py_memo_zik.txt" des :
        #   options de lecture (volume, ..., random, ...
        # X numéro de la liste des favoris (1 pour l'instant)
        # X position dans playliste
        # X progression dans morceau
        options = mpc.options_lecture() # ~ mpc_status = t[0]       # volume: 81%   repeat: off   random: off   single: off   consume: off
        numFav = 1
        posPL = mpc.playlist_position()
        posTrack = mpc.status_progression()[0]
        ligne = "{}|{}|{}|{}".format(options, numFav, posPL, posTrack)
        fichier = zik_memo("position")
        if fichier == False:
            infos.m_g("zik memo --> SAVE position et progression (" + fichier + ") impossible")
        else:
            infos.m_g("zik memo --> SAVE position et progression (" + fichier + ")")
            with open(fichier, "w") as f:
                f.write(ligne)

    elif operation == "position":
        zlogger("zik memo GET position : " + cfg.ZIK_MEMO)
        # vérif dossier enregistrements
        zm_dir = cfg.ZIK_MEMO_DIR
        if not commun.dir_exists(zm_dir):
            commun.make_dir(zm_dir)
        if not commun.dir_exists(zm_dir):
            infos.pdrNew("Problème lors de la création du dossier mémo musique")
            commun.faire_pause(3)
            return False
        return cfg.ZIK_MEMO


def reprendre():  # on reprend la musique quittée
    """ reprendre la lecture de la musique quittée
        2 fichiers/playlist utilisés :
        - /m/playlists/py_zik_memo.m3u
        - /m/memo/zik/py_zik_memo.txt """

    def init_reprendre():
        """ initialisation variables musique """
        # TODO : contrôler que tout est bien là :
        # - la musique à lire
        # - les lieux de mémorisations
        infos.ini_set("py_current_module", "zik")

    def reprendre_la_musique():
        """ rependre où on s'était arrêté """
        # 1. récupérer la playliste sauvegardée
        if commun.file_exists(zik_memo("playlist_file")):
            mpc.ferme_ton_clapet()
            mpc.load(zik_memo("playlist"))
        else:
            infos.m_g("Fichier absent {}".format(zik_memo("playlist_file")))
            infos.m_g("Pas de playliste memo zik trouvée")
            # zik_memo("save_playlist")
            return False

        # 2. récupérer les positions et progression sauvegardées
        fichier_memo_zik = zik_memo("position")
        if commun.file_exists(fichier_memo_zik):
            zlogger(fichier_memo_zik + " existe")
            # position dans playliste et progression dans morceau
            t = commun.file_stripped(fichier_memo_zik)[0].split("|")
            mpc_status = t[0]       # volume: 81%   repeat: off   random: off   single: off   consume: off
            numFav = t[1]           # 1
            positionPlaylist = t[2] # 1:45
            positionMorceau = t[3]  # 1211
            zlogger("rep_l_m : fichier playlist = " + zik_memo("playlist_file"))
            zlogger("rep_l_m : playlist         = " + zik_memo("playlist"))
            zlogger("rep_l_m : numFav           = " + numFav)
            zlogger("rep_l_m : positionPlaylist = " + positionPlaylist)
            zlogger("rep_l_m : positionMorceau  = " + positionMorceau)
            if mpc_status.find("random: on") > 0:
                mode_random = True
            else:
                mode_random = False

            mpc.play(positionPlaylist)
            mpc.seek(positionMorceau)
            return True

        else:
            infos.m_g(fichier_memo_zik + " n'existe pas")
            numFav = 1
            positionPlaylist = 1
            positionMorceau = 0
            infos.m_g("Pas de positions mémorisées dans playliste trouvée")
            mpc.play()
            return True

        # mpc.play(positionPlaylist)
        # mpc.seek(positionMorceau)
        # return True

    def verif_dir_music():
        """ si le dossier /m/music n'existe pas, on quitte
        """
        # https://wiki.archlinux.org/index.php/Music_Player_Daemon#Configure_the_location_of_files_and_directories
        # ou bien envisager de copier /etc/mpd.conf vers ~/.config/mpf.conf
        # et de modifier music_directory en /m au lieu de /m/music
        # sudo service mpd stop
        # sudo service mpd start

        # vérif clé usb montée
        if commun.m_is_mounted() == False:
            infos.pdrNew("Problème, la clé u s b ne semble pas reconnue, " + \
                "veuillez redémarrer ou vérifier votre clé.")
            return False

        # vérif /m/music existe
        dossier = cfg.M_MUSIC + "/type1"
        if not commun.dir_exists(dossier):
            # proposer déplacer fichiers au bon endroit
            msg = "Le dossier musique est absent de la clé u s b"
            infos.pdrNew(msg)
            msg = "Si vous voulez quand même écouter votre musique, " + \
                "vous pouvez autoriser le programme à créer " + \
                "les dossiers nécessaires, et y déplacer vos chansons"
            infos.pdrNew(msg)
            msg = "Appuyer sur 321 puis Entrée pour procéder."
            infos.pdrNew(msg)
            choix_user = input()
            if choix_user == "321":
                mpc.ferme_ton_clapet()
                cmd = "find /m -iname '*.mp3' | wc -l"
                nb_mp3 = int(mpc.sub_proc(cmd))
                msg = "{} fichiers m p 3 ont été trouvés sur la clé".format(nb_mp3)
                infos.pdrNew(msg)
                cmd = "mkdir -p /m/music/type1/A"
                mpc.sub_proc(cmd)
                cmd = "find /m -iname '*.mp3' | grep -v /m/music | cut -f3 -d'/' | sort | uniq > /tmp/forcer_chansons.txt"
                mpc.sub_proc(cmd)
                with open("/tmp/forcer_chansons.txt", "r") as f:
                    lignes = f.readlines()
                for ligne in lignes:
                    cmd = 'cd /m; mv "' + ligne.strip() + '" /m/music/type1/A'
                    infos.m_g(cmd)
                    mpc.sub_proc(cmd)
            else:
                return False

    ################################################
    #                  reprendre zik               #
    ################################################
    mpc.ferme_ton_clapet()
    if verif_dir_music() == False:
        return 0

    init_reprendre()

    mpc.clear()
    # commenter ci-dessous pour ne pas reprendre_directement la lecture
    mpc.update()  # important quand on change de clé usb !
    infos.m_g("mpc -q update")
    msg = "lancement de la musique sur clé u s b"
    infos.pdrNew(["", msg, msg, msg])
    commun.faire_pause(5, True)      # pause de 2s
    resultat = reprendre_la_musique()


def trk_first():
    infos.m_g("zik trk_first")
    mpc.trk_first()


def trk_last():
    infos.m_g("zik trk_last")
    mpc.trk_last()


def zik_fav3():
    pass


def zik_nfo1():
    """ appui sur touche / : annoncer titre de auteur """
    # ex : "vous écoutez Matrice de Gérard Manset"
    msg = "vous écoutez " + mpc.auteur_titre()
    infos.pdrNew(msg)


def zik_infos_go(choix = None):
    """ copier zik_infos_go () de zik.sh """
    if choix is None:
        infos.m_g(mpc.auteur_titre())
    elif choix in ("prev", "next"):
        infos.m_g(choix + " : " + mpc.auteur_titre())


def zik_infos_non_vides():  # renvoie infos mp3 si présentes, sinon nom de fichier si absentes
    return ("TODO zik_infos_non_vides")


def zik_nfo():  # "il vous reste 3 minutes 12 pour ce morceau"
    pass


def zik_nfo2():  # "élément 8 sur 15"
    pass


def zik_nfo3():  # "vous êtes à 3 mn 12 sur 10 mn 30"
    pass


def zik_nfo4():  # "la durée totale du livre est de 2 heures 38"
    pass


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


if __name__ == "__main__":
    print("Bienvenue dans le module zik (musique)")