# 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_relativeoperationnum_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_PATHcfg.ZIK_FAVnum_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_favorifile_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_relativeplaylist_fav)

    def del_ban_fav(file_relative):
        """ supprime le favori, si présent, du fichier playlist favoris """
        playlist_fav "{}/{}_{}.m3u".format(cfg.PLAYLISTS_PATHcfg.ZIK_FAVnum_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_favorisfavoris_bannis(mpc.mpc_file(), "add_fav"1)
    zlogger("fav_add, {} favoris, {}".format(nb_favorisr))


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_favorisfavoris_bannis(mpc.mpc_file(), "del_fav"1)
    zlogger("fav_del, {} favoris, {}".format(nb_favorisr))


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(dossierordredemander "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(dossierchiffres_lettres.get(lettre), ordre)
    elif lettre == "":
        mp3_lettre(dossier""ordre)


def mp3_lettre(dossierlettreordre):
    """ 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
        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(optionsnumFavposPLposTrack)
        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
            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([""msgmsgmsg])
    commun.faire_pause(5True)      # 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)")