(#Importation des librairies necesaire
from playsound import playsound
from pathlib import Path
from tkinter import ttk
import tkinter as tk
import configparser
import threading
import requests
import zipfile
import shutil
import os



#Créer la fenetre parent "root"
print("Creation du prossesus root")
root = tk.Tk()
root.withdraw()



# Obtenir la resolution
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()


#Créer la fenetre de Chargement
win_loading = tk.Toplevel(root)
win_loading.title("load")
win_loading.geometry(f"400x200+{(screen_width // 2) - 200}+{(screen_height // 2) - 100}")
win_loading.overrideredirect(True)
win_loading.configure(bg="black")



var_launcher_path = os.getcwd()

username = os.getlogin()
Launcher_save_dir = os.path.join(var_launcher_path, "saves")
Launcher_version_dir = os.path.join(var_launcher_path, "versions")
save_appdata_local = fr"C:\Users\{username}\AppData\Local\UNDERTALE"




def verification():
    print("verification...")
    
    if os.path.isdir(Launcher_version_dir):
        print("Dosssier version found")
    else:
        print("dossier version not found")
        os.makedirs(Launcher_version_dir)
        verification()

    if os.path.isdir(Launcher_save_dir):
        print("Dosssier save found")
    else:
        print("dossier save not found")
        os.makedirs(Launcher_save_dir)
        verification()
        
    if os.path.isdir(save_appdata_local):
        print("local UNDERTALE found")
    else:
        print("Local not found never played undertale yet?")
        os.makedirs(save_appdata_local)
        verification()





verification()
print("end of verification")



try:
    last_time_save = os.path.getmtime(os.path.join(save_appdata_local, "file0"))
except:
    pass







#Mis en place de l'image de chargement -Aaron was here 🤠
imagepath = tk.PhotoImage(file = os.path.join(var_launcher_path, "loading.png")).subsample(4, 4)
image_loading = tk.Label(win_loading, image= imagepath)
image_loading.pack()










# Creation de la fenetre du menu
win_menu = "Fenetre principale"
def start_win_menu():
    global win_menu
    global root
    global list_winmenu_versions_installed
    global combobox_winmenu_versionslist
    global button_win_newversion_continue
    global main_update
    global combobox_winmenu_saveslist
    global combobox_winmenu_versionslist
    win_loading.destroy()
   
    
    win_menu = tk.Toplevel(root)
    win_menu.protocol("WM_DELETE_WINDOW", quit_app)
    
    win_menu.title("Undertale Launcher v1.0")
    win_menu.geometry(f"800x500+{(screen_width // 2) - 400}+{(screen_height // 2) - 250}")
    win_menu.resizable(True, True)
    win_menu.configure(background="#000000") 
    



    #title
    label_winmenu_title = tk.Label(  
        win_menu, 
        text="Undertale Launcher", 
        font=("System",50), 
        background="#000000",
        foreground="#FFFFFF"
    )     
    label_winmenu_title.pack()




    #Frame Versions
    frame_winmenu_version = tk.Frame(win_menu)  # Placement d'une frame en bas de la fenetre
    frame_winmenu_version.place(
        relx=0.25,
        rely=0.5,
        relwidth=0.4,
        relheight=0.65,
        anchor="center"
        )
    frame_winmenu_version.configure(background="#FFFFFF")



    frame_winmenu_version2 = tk.Frame(frame_winmenu_version)  # Placement d'une frame en bas de la fenetre
    frame_winmenu_version2.place(
        relx=0.5,
        rely=0.5,
        relwidth=0.96,
        relheight=0.96,
        anchor="center"
        )
    frame_winmenu_version2.configure(background="#000000")


    


    #widjet version
    label_winmenu_title_save = tk.Label(
        frame_winmenu_version,
        text="Versions",
        fg="white",
        bg="black",
        font=("System", 18)
        )
    label_winmenu_title_save.pack(pady=10)


    combobox_winmenu_versionslist = ttk.Combobox(frame_winmenu_version)
    combobox_winmenu_versionslist.pack(pady=10)
    combobox_winmenu_versionslist.set("New version")

    
    
    


    button_winmenu_suprrversion = tk.Button(
        frame_winmenu_version,
        text="Delete",
        bg="black",
        fg="#ff0000",
        command= delete_version,
        )

    

    button_winmenu_suprrversion.place(
        relx=0.12,
        rely=0.9,
        anchor="center"
        )
    


    button_winmenu_renameversion = tk.Button(frame_winmenu_version, text="Rename", bg="black",fg="blue", command=win_rename_version)
    button_winmenu_renameversion.place(relx=0.37, rely=0.9, anchor="center")
    
    button_winmenu_newversion = tk.Button(frame_winmenu_version, text="New", bg="black",fg="#05c61b", command=new_version)
    button_winmenu_newversion.place(relx=0.62, rely=0.9, anchor="center")
    
    




    #frame save
    frame_winmenu_save = tk.Frame(win_menu)  
    frame_winmenu_save.place(
        relx=0.75,
        rely=0.5,
        relwidth=0.4,
        relheight=0.65,
        anchor="center"
        )
    frame_winmenu_save.configure(background="#FFFFFF")
    

    frame_winmenu_save2 = tk.Frame(frame_winmenu_save)  
    frame_winmenu_save2.place(
        relx=0.5,
        rely=0.5,
        relwidth=0.96,
        relheight=0.96,
        anchor="center"
        )

    frame_winmenu_save2.configure(background="#000000")

    #widjets save
    

    label_winmenu_title_save = tk.Label(
        frame_winmenu_save,
        text="Saves",
        fg="white",
        bg="black",
        font=("System", 18)
        )
    label_winmenu_title_save.pack(pady=10)

    
    
    combobox_winmenu_saveslist = ttk.Combobox(frame_winmenu_save)
    combobox_winmenu_saveslist.pack(pady=10)
    combobox_winmenu_saveslist.set("New save")
    
    
    
    button_winmenu_suprrsave = tk.Button(
        frame_winmenu_save,
        text="Delete",
        bg="black",
        fg="#ff0000",
        command= delete_save,
        )

    

    button_winmenu_suprrsave.place(
        relx=0.12,
        rely=0.9,
        anchor="center"
        )
    


    button_winmenu_renamesave = tk.Button(frame_winmenu_save, text="Rename", bg="black",fg="blue", command=win_rename_save)
    button_winmenu_renamesave.place(relx=0.37, rely=0.9, anchor="center")
    
    button_winmenu_newversion = tk.Button(frame_winmenu_save, text="New", bg="black",fg="#05c61b", command=new_save)
    button_winmenu_newversion.place(relx=0.62, rely=0.9, anchor="center")
    
    button_winmenu_save = tk.Button(frame_winmenu_save, text="Save", bg="black",fg="#fbff00", command=save)
    button_winmenu_save.place(relx=0.88, rely=0.9, anchor="center")
    


    #en bas
    button_winmenu_start = tk.Button(win_menu, text="Run",background="black", foreground="green",font=("System",10), command=run_undertale)
    button_winmenu_start.place(relx= 0.5, rely=0.9, anchor="center")
    
    

    def win_save():
        win_save = tk.Toplevel(root)
        win_save.withdraw()
        
    
    
        win_save.title("yupi")
        win_save.geometry(f"800x500+{(screen_width // 2) - 400}+{(screen_height // 2) - 250}")
        win_save.configure(background="#000000") 
   


   
    
    def main_update():
        global change
        global combobox_winmenu_versionslist
        global list_winmenu_versions_installed
        global combobox_winmenu_versionslist
        global last_time_save
        list_winmenu_versions_installed = [f.name for f in Path(os.path.join(var_launcher_path, "versions")).iterdir() if f.is_dir()]
        list_winmenu_versions_installed.insert(0, "Nouvelle version")
        combobox_winmenu_versionslist["values"] = list_winmenu_versions_installed
        combobox_winmenu_versionslist["font"] = "System"
        
        
        
        if "UNDERTALE.exe" in os.popen("tasklist").read():
            button_winmenu_start["text"] = "Kill"
            button_winmenu_start["fg"] = "red"
            button_winmenu_start["command"] = lambda: os.system("taskkill /f /im UNDERTALE.exe")

            
        else:
            button_winmenu_start["text"] = "Run"
            button_winmenu_start["fg"] = "green"
            button_winmenu_start["command"] = run_undertale


        
        if os.path.isfile(os.path.join(save_appdata_local, "file0")):      
            if os.path.getmtime(os.path.join(save_appdata_local, "file0")) != last_time_save:
                print("saving...")
                last_time_save = os.path.getmtime(os.path.join(save_appdata_local, "file0"))
                saving = tk.Toplevel(root)
                saving.title("save")
                saving.geometry(f"600x150+{screen_width - 600}+{(screen_height * 0.8):.0f}")
                saving.overrideredirect(True)
                saving.attributes("-topmost", True)
                border = tk.Frame(saving)
                border.place(relx=0.5, rely=0.5, relwidth=1, relheight=1, width=-25, height=-25, anchor="center")
                border.configure(bg="black")
                saving_label = tk.Label(saving, text="* Saving...", font=("System", 20), bg="black", fg="white")
                saving_label.place(x = 15, y=35, anchor="w")
                saving.after(2500,saving.destroy)
                
       
        list_winmenu_saves_installed = [f.name for f in Path(os.path.join(var_launcher_path, "saves")).iterdir() if f.is_dir()]
        list_winmenu_saves_installed.insert(0, "Nouvelle save")
        combobox_winmenu_saveslist["values"] = list_winmenu_saves_installed      
        combobox_winmenu_saveslist["font"] = "System"
       
        
        win_menu.after(700, main_update)
        

    thread_update = threading.Thread(target=main_update, daemon=True)



    thread_update.start()


    
def quit_app():
    global root
    print("Fermeture en cours..")

    root.destroy()
    root.quit()
    
  
def sound_play(path):

    def play(path):
        playsound(path)

    threading.Thread(target=play, daemon=True, args=(path,)).start()
    


def delete_version():
    global win_menu
    print(f"la version {combobox_winmenu_versionslist.get()} va etre suprr")
    print(os.path.join(var_launcher_path, "versions", combobox_winmenu_versionslist.get()))
    shutil.rmtree(os.path.join(var_launcher_path, "versions", combobox_winmenu_versionslist.get()))
    

def delete_save():
    global win_menu
    print(f"la save {combobox_winmenu_saveslist.get()} va etre suprr")
    print(os.path.join(var_launcher_path, "saves", combobox_winmenu_saveslist.get()))
    shutil.rmtree(os.path.join(var_launcher_path, "saves", combobox_winmenu_saveslist.get()))
    

def rename_save():
    print("renaming..")
    print(f"rename {os.path.join(var_launcher_path, "saves", combobox_winmenu_saveslist.get())} to {os.path.join(var_launcher_path, "saves", Entry_winrename_namesave.get())}")
    os.rename(os.path.join(var_launcher_path, "saves", combobox_winmenu_saveslist.get()), os.path.join(var_launcher_path, "saves", Entry_winrename_namesave.get()))
    win_rename_save.destroy()

def rename_version():
    print("renaming..")
    print(f"rename {os.path.join(var_launcher_path, "saves", combobox_winmenu_saveslist.get())} to {os.path.join(var_launcher_path, "saves", Entry_winrename_nameversion.get())}")
    os.rename(os.path.join(var_launcher_path, "versions", combobox_winmenu_versionslist.get()), os.path.join(var_launcher_path, "versions", Entry_winrename_nameversion.get()))
    win_rename_version.destroy()

def win_rename_version():
    global Entry_winrename_nameversion, win_rename_version
    print("start version rename win ")
    win_rename_version = tk.Toplevel(root)
    win_rename_version.title(f"Rename version {combobox_winmenu_saveslist.get()}")
    win_rename_version.geometry(f"400x250+{(screen_width // 2) - 200}+{(screen_height // 2) - 125}")
    win_rename_version.resizable(False, False)

    frame_winrename = tk.Frame(win_rename_version, bg="black")
    frame_winrename.place(relx=0.5, rely=0.5, relwidth=1, relheight=1, height=-10, width=-10, anchor="center")

    Label_winrename_title = tk.Label(win_rename_version, text="Rename", font=("System",20))
    Label_winrename_title.pack(pady=10)
    Entry_winrename_nameversion = tk.Entry(win_rename_version)
    Entry_winrename_nameversion.pack()

    button_winrename = tk.Button(win_rename_version, text="Rename", font=("System"), command= rename_version) 
    button_winrename.pack(pady=10,side="bottom")

def win_rename_save():
    global Entry_winrename_namesave, win_rename_save
    print("start save rename win ")
    win_rename_save = tk.Toplevel(root)
    win_rename_save.title(f"Rename save {combobox_winmenu_saveslist.get()}")
    win_rename_save.geometry(f"400x250+{(screen_width // 2) - 200}+{(screen_height // 2) - 125}")
    win_rename_save.resizable(False, False)

    frame_winrename = tk.Frame(win_rename_save, bg="black")
    frame_winrename.place(relx=0.5, rely=0.5, relwidth=1, relheight=1, height=-10, width=-10, anchor="center")

    Label_winrename_title = tk.Label(win_rename_save, text="Rename", font=("System",20))
    Label_winrename_title.pack(pady=10)
    Entry_winrename_namesave = tk.Entry(win_rename_save)
    Entry_winrename_namesave.pack()

    button_winrename = tk.Button(win_rename_save, text="Rename", font=("System"), command= rename_save) 
    button_winrename.pack(pady=10,side="bottom")








    
win_newversion = "lol"

def new_version():
    global win_newversion
    global button_win_newversion_continue
    global entry_win_newversion_nameversion
    global combobox_win_newversion_versionchoice
    global root
    
    
    
    win_newversion = tk.Toplevel(root)
    win_newversion.title("New version")
    win_newversion.geometry(f"400x250+{(screen_width // 2) - 200}+{(screen_height // 2) - 125}")
    win_newversion.resizable(False, False)


    frame_win_newversion = tk.Frame(win_newversion)
    frame_win_newversion.place(rely=0.5, relx=0.5, relwidth=0.96, relheight=0.96, anchor="center")
    frame_win_newversion.configure(background="#000000")
    


    label_win_newversion_title = ttk.Label(frame_win_newversion, text="New version", font=("System", 20), background="black", foreground="white")
    label_win_newversion_title.pack()
    
    label_win_newversion_nameversion = ttk.Label(frame_win_newversion, text="Name of new version", font=("System", 10), background="black", foreground="white")
    label_win_newversion_nameversion.pack()
    
    
    entry_win_newversion_nameversion = ttk.Entry(frame_win_newversion, font=("System"))
    entry_win_newversion_nameversion.pack()
    entry_win_newversion_nameversion.insert(0, "Name of new version")
    
    label_win_newversion_versionchoice = ttk.Label(frame_win_newversion, text="Version", font=("System", 10), background="black", foreground="white")
    label_win_newversion_versionchoice.pack()

    combobox_win_newversion_versionchoice = ttk.Combobox(frame_win_newversion, values=["v1.08","v1.06","v1.001","v1.0","201406TEST18","DEMO20130523"], font=("System"))
    combobox_win_newversion_versionchoice.pack()
    combobox_win_newversion_versionchoice.set("v1.08")

    
    button_win_newversion_continue = tk.Button(frame_win_newversion, text="Install", background="#ffbb00", foreground="black", font=("System",5), command= lambda: threading.Thread(target = start_win_download).start())
    button_win_newversion_continue.pack(side="bottom", pady=10)
    
    sound_play(os.path.join(var_launcher_path, "new.wav"))


















def new_save():
    global win_newversion
    global button_win_newversion_continue
    global entry_win_newversion_nameversion
    global combobox_win_newversion_versionchoice
    global root
    
    
    
    win_newversion = tk.Toplevel(root)
    win_newversion.title("Nouvel save")
    win_newversion.geometry(f"400x250+{(screen_width // 2) - 200}+{(screen_height // 2) - 125}")
    win_newversion.resizable(False, False)
    
    
    label_win_newversion_title = ttk.Label(win_newversion, text="Creation d'une sauvegarde", font=("System", 20))
    label_win_newversion_title.pack()
    
    label_win_newversion_nameversion = ttk.Label(win_newversion, text="Nom de la save")
    label_win_newversion_nameversion.pack()
    
    
    entry_win_newversion_nameversion = ttk.Entry(win_newversion, )
    entry_win_newversion_nameversion.pack()
    entry_win_newversion_nameversion.insert(0, "nom de la save")
    def toggle():

        if label_win_newversion_versionchoic.get() == False:
            label_win_newversion_versionchoic = 0
        else:
             label_win_newversion_versionchoic = 1
    var_toggle = tk.BooleanVar()
    
    
  
    
    label_win_newversion_versionchoic = ttk.Checkbutton(win_newversion,variable=var_toggle ,text="importer la save actuelle", command=lambda: toggle)
    label_win_newversion_versionchoic.pack()
    

    def newing_save():
        
        config_save = configparser.ConfigParser()
        
        
        savedir = os.path.join(var_launcher_path, "saves", entry_win_newversion_nameversion.get())
        

        savelocal= fr"C:\Users\{username}\AppData\Local\UNDERTALE"
        
        
        config_save["Info"] = {
            "name": entry_win_newversion_nameversion.get()
        }
        
        if var_toggle.get(): 
            
            shutil.copytree(savelocal,savedir, dirs_exist_ok=False)
        else:
            os.makedirs(savedir)   
        
        with open(os.path.join(savedir, "Undertale_Launcher.ini"), "w") as f:
            config_save.write(f)
        
        main_update()
        win_newversion.destroy()
    
    button_win_newversion_continue = ttk.Button(win_newversion, text="Ok", command= newing_save)
    button_win_newversion_continue.pack(side="bottom")
    
    sound_play(os.path.join(var_launcher_path, "new.wav"))








def start_win_download():
    global entry
    global entry_win_newversion_nameversion
    global combobox_win_newversion_versionchoice
    global win_menu
    

    nom_de_version = entry_win_newversion_nameversion.get()
    version_selected = combobox_win_newversion_versionchoice.get()
    
    win_newversion.destroy()
    
    
    win_download = tk.Toplevel()
    win_download.geometry(f"500x100+{(screen_width // 2) - 250}+{(screen_height // 2) - 50}")
    win_download.resizable(False, False)
    win_download.title("Chargement 0%")
    loading = ttk.Progressbar(win_download, orient="horizontal", length=300, mode="determinate")
    
    loading.pack(side="bottom", pady=20)

    win_download.protocol("WM_DELETE_WINDOW", quit_app)



    url_download = f"https://github.com/chocolife13/----------------------------------/releases/download/{version_selected}/file.zip"
    undertale_chunk_downloaded = 0
    request_undertale_download = requests.get(url_download, stream=True)


    

    if request_undertale_download.status_code == 200:
        print("Server disponible et fichier trouvé")

        undertale_max_length_file = request_undertale_download.headers.get("content-length")
    
        print(f"le fichier fais: {undertale_max_length_file} octes")

        with open(os.path.join(var_launcher_path, "temp.zip"), "wb") as file:
            for chunk in request_undertale_download.iter_content(chunk_size=81920):
                if chunk:
                    file.write(chunk)
                    undertale_chunk_downloaded += len(chunk)
                    loading['value'] = int(f"{int(undertale_chunk_downloaded) / int(undertale_max_length_file) * 100:.0f}")
                    win_download.title(f"Chargement {int(undertale_chunk_downloaded) / int(undertale_max_length_file) * 100:.1f}%")

            file.close()
            print("fichier télécharger")
            
            zip_path = os.path.join(var_launcher_path, "temp.zip")

            ziping_path = os.path.join(var_launcher_path, "versions")
            with zipfile.ZipFile(zip_path, "r") as zip_file:
                zip_file.extractall(ziping_path)
            
            
            print("Fini")

            
            os.rename(os.path.join(var_launcher_path, "versions", version_selected), os.path.join(var_launcher_path, "versions", nom_de_version ))
            
            
            main_update()
            
            
            
    else: 
        print("serveur down")
        win_download.destroy()



def save():
    Launcher_save_dirs = os.path.join(var_launcher_path, "saves")
    save_appdata_local = fr"C:\Users\{username}\AppData\Local\UNDERTALE"
    
            

    print(f"Dossier LOCAL UNDERTALE: {save_appdata_local}")
    print(f"les Save du Launcher se trouve a {Launcher_save_dirs}")
    
            
            
    config_save = configparser.ConfigParser()
            
            
    print(f"recherche du nom de la save dans le fichier Undertale_Launcher.ini")
    
    
    if os.path.exists(os.path.join(save_appdata_local, "Undertale_Launcher.ini")):
                
        config_save.read(os.path.join(save_appdata_local, "Undertale_Launcher.ini"))
            
        #print(f"Fichier .ini ouvert :{os.path.join(save_appdata_local, "Undertale_Launcher.ini")}")
            
            
            
        nom_save_ini_local = config_save.get("Info", "name")
        print(f"sauvegarde la save de LOCAL UNDERTALE au Laucher")
                
        
        print("Supresion de tous les fichiers LOCAL UNDERTALE")
        
        try:
                
                os.remove(os.path(save_appdata_local,"file0"))
                os.remove(os.path(save_appdata_local,"undertale.ini"))
            
        except:
                print("no save found to be deleted")
        
        print("copie")
        shutil.copytree(save_appdata_local, os.path.join(Launcher_save_dirs, nom_save_ini_local), dirs_exist_ok=True)
                
        print(f"sauvegarde dans LOCAL UNDERTALE ({nom_save_ini_local})")
            
    
    
    
    
    
    else:
        print(f"Fichier .ini pas ouvert :{os.path.join(save_appdata_local, 'Undertale_Launcher.ini')}")
            
            
            
            
           






def run_undertale():
    
    if not combobox_winmenu_versionslist.get() == "Nouvelle version":

        if combobox_winmenu_saveslist.get() == "Nouvelle save":
            new_save()
        else:
            
            ########## Gestion des sauvegardes ###################
            
            Launcher_save_dirs = os.path.join(var_launcher_path, "saves")
            save_appdata_local = fr"C:\Users\{username}\AppData\Local\UNDERTALE"
            save_choiced = combobox_winmenu_saveslist.get()
            

            print(f"Dossier LOCAL UNDERTALE: {save_appdata_local}")
            print(f"les Save du Launcher se trouve a {Launcher_save_dirs}")
            print(f"jeux lancer sur la save ({save_choiced})")
            
            
            
            if os.path.isfile(os.path.join(save_appdata_local, "file0")):
                
                os.remove(os.path.join(save_appdata_local,"file0"))
                os.remove(os.path.join(save_appdata_local,"undertale.ini"))
                print("copie de la save selectioner dans le LOCAL UNDERTALE")
                shutil.copytree((os.path.join(Launcher_save_dirs, save_choiced)), save_appdata_local, dirs_exist_ok=True)
            else:
    
                shutil.copytree((os.path.join(Launcher_save_dirs, save_choiced)), save_appdata_local, dirs_exist_ok=True)
                print("no save found to be deleted")
            
            
            
            
            

           
            
            
            os.startfile(os.path.join(var_launcher_path, "versions", combobox_winmenu_versionslist.get(), "UNDERTALE.exe"))
            sound_play(os.path.join(var_launcher_path, "start.wav")) 


    else:
        new_version()
        

        



# Attente pour le loading screen
root.after(5000, start_win_menu)

# Demarrage 
root.mainloop()
