"""
Projet NSI - Jeu narratif

Ce programme permet de jouer à une histoire interactive
inspirée des livres dont vous êtes le héros.

Organisation actuelle :
- les textes sont stockés dans un dictionnaire
- les transitions sont stockées dans une liste de couples
- l'interface graphique permet d'afficher le texte et de choisir

Objectif du projet :
améliorer progressivement la structure (fichiers, graphe, objets...)
"""

import tkinter as tk


# Les textes des différentes scènes.
# Chaque texte contient aussi les choix proposés au joueur.
scenes = {
    0: "Tu te réveilles dans une grotte sombre.\n\n"
       "Explorer le tunnel (1)\n"
       "Sortir (2)",

    1: "Le tunnel devient étroit.\n\n"
       "Continuer (3)\n"
       "Revenir (0)",

    2: "Tu arrives dehors.\n\n"
       "Cabane (4)\n"
       "Forêt (5)",

    3: "Une créature surgit !",
    4: "Tu trouves une cabane.",
    5: "Tu te perds dans la forêt..."
}


# Les transitions représentent les déplacements possibles.
# Chaque couple (a, b) signifie que l'on peut aller de a vers b.
# Il n'y a volontairement aucune information textuelle ici.
transitions = [
    (0, 1),
    (0, 2),
    (1, 3),
    (1, 0),
    (2, 4),
    (2, 5)
]


def get_suivants(sommet):
    """
    Renvoie la liste des sommets accessibles depuis le sommet donné.

    Cette fonction parcourt toute la liste des transitions.
    Cette méthode est simple mais peu efficace, et pourra être améliorée.
    """
    result = []

    for depart, arrivee in transitions:
        if depart == sommet:
            result.append(arrivee)

    return result


class Jeu:
    """
    Cette classe gère uniquement l'affichage et les interactions avec le joueur.

    Elle ne contient pas la logique de stockage des données.
    """

    def __init__(self, root):
        self.root = root
        self.root.title("Jeu narratif")

        # On fixe une taille de fenêtre pour un affichage plus confortable
        self.root.geometry("800x600")

        # La scène actuelle (on commence au chapitre 0)
        self.courant = 0

        # On essaie de charger une image de fond.
        # Si le fichier n'existe pas, le programme continue sans image.
        try:
            self.image_fond = tk.PhotoImage(file="images/fond.png")

            # Le canvas permet d'afficher une image et du texte par-dessus
            self.canvas = tk.Canvas(root, width=800, height=600)
            self.canvas.pack(fill="both", expand=True)

            # Affichage de l'image en fond
            self.canvas.create_image(400, 300, image=self.image_fond)

            # Texte affiché au centre
            self.zone_texte = self.canvas.create_text(
                400, 200,
                text="",
                width=600,
                fill="white",
                font=("Georgia", 16),
                justify="center"
            )

            # Zone pour les boutons
            self.frame_boutons = tk.Frame(root, bg="black")
            self.canvas.create_window(400, 450, window=self.frame_boutons)

            # On mémorise qu'on utilise le canvas
            self.utilise_canvas = True

        except:
            # Version simple si aucune image n'est disponible
            self.zone_texte = tk.Label(
                root,
                text="",
                wraplength=500,
                justify="left",
                font=("Arial", 12)
            )
            self.zone_texte.pack(padx=20, pady=20)

            self.frame_boutons = tk.Frame(root)
            self.frame_boutons.pack()

            self.utilise_canvas = False

        # Affichage initial
        self.afficher_scene()

    def afficher_scene(self):
        """
        Met à jour l'affichage :
        - texte de la scène
        - boutons correspondant aux choix possibles
        """

        texte = scenes[self.courant]

        # Affichage du texte selon le mode utilisé
        if self.utilise_canvas:
            self.canvas.itemconfig(self.zone_texte, text=texte)
        else:
            self.zone_texte.config(text=texte)

        # On supprime les anciens boutons avant d'en créer de nouveaux
        for widget in self.frame_boutons.winfo_children():
            widget.destroy()

        # On récupère les scènes accessibles depuis la scène actuelle
        succ = get_suivants(self.courant)

        # S'il n'y a aucun successeur, la partie est terminée
        if len(succ) == 0:
            bouton = tk.Button(
                self.frame_boutons,
                text="Fin du jeu",
                command=self.root.quit
            )
            bouton.pack()
            return

        # Pour chaque destination possible, on crée un bouton
        for i in range(len(succ)):
            destination = succ[i]

            bouton = tk.Button(
                self.frame_boutons,
                text=f"Choix {destination}",
                command=self.creer_commande(destination)
            )
            bouton.pack(fill="x")

    def creer_commande(self, destination):
        """
        Crée la fonction appelée lorsqu'on clique sur un bouton.

        Cette fonction modifie la scène actuelle puis met à jour l'affichage.
        """
        def commande():
            self.courant = destination
            self.afficher_scene()

        return commande


# Lancement du programme
if __name__ == "__main__":
    root = tk.Tk()
    app = Jeu(root)
    root.mainloop()
