"""
Larve et pious

"""

import os # importe le module operating system
rep_courant = os.getcwd() # la méthode getcwd() donne le répertoire courant
#print(rep_courant) # affiche le chemin d'accès du répertoire courant

os.chdir("...") # A MODIFIER, c'est un exemple !!!
#os.chdir("... chemin du dossier dans lequel vous enregistrez ...") # modifie le repertoire courant
# Exemple : os.chdir("C:/MP/Informatique/Jeux")

import tkinter as tk
from PIL import Image,ImageTk
from chasse import *
from math import inf
from tkinter import messagebox

LIGHTGREY = '#eee'      # couleur cases blanches
DARKGREY = '#666'       # couleur cases noires
SIZE = 50               # taille des cases en pixels
CANVAS_OFFSET = 15      # décalage de la grille par rapport au canevas de dessin
LARVE = 1               # joueur 1
PIOUS = 0               # joueur 0


FICHIER_PIOU1 = 'images/piou_rouge.png'
FICHIER_PIOU2 = 'images/piou_jaune.png'
FICHIER_PIOU3 = 'images/piou_bleu.gif'
FICHIER_PIOU4 = 'images/piou_vert.gif'

FICHIER_LARVE = 'images/larve.png'


# definition des mouvements
NW = (-1,-1)
NE = (1, -1)
SW = (-1, 1)
SE = (1, 1)
map_names = { LARVE : 'larve', PIOUS : 'pious'}

INITIAL = ((3,0) ,[(0,7),(2,7),(4,7),(6,7)])

MIN_DEPTH = 1          # profondeur minimale de recherche pour min-max
MAX_DEPTH = 10         # profondeur maximale de recherche pour min-max


class Setting_frame(tk.LabelFrame) :
    def __init__(self, master, width, height) :
        super().__init__(master, text = 'options de jeu', width=width, height=height)

        # choix de ce que contrôle l'IA
        label1 = tk.Label(self, text="L'IA contôle ...")
        label1.grid(row=0, column=0, columnspan=2, pady=5)

        vals = [PIOUS, LARVE]
        etiqs = ['... les pious', '... la larve']
        self.iactl = tk.IntVar()

        self.rb0 = tk.Radiobutton(self, variable=self.iactl, text=etiqs[0],
                                  value=vals[0])
        self.rb1 = tk.Radiobutton(self, variable=self.iactl, text=etiqs[1],
                                  value=vals[1])
        
        self.rb0.grid(row=1, column = 0, columnspan=2,pady=5)
        self.rb1.grid(row=2, column = 0, columnspan=2,pady=5)
        
        self.iactl.set(PIOUS)

        # Choix du joueur qui commence
        self.human_play_first = tk.IntVar()
        self.chkbox = tk.Checkbutton(self,
                       variable = self.human_play_first,
                       text = 'Humain joue en premier')
        self.chkbox.grid(row=3, column=0, columnspan=2,pady = 10)
        self.human_play_first.set(0)

        label2 = tk.Label(self,text = " Profondeur de recherche pour min-max") 
        label2.grid(row=4,column=0, columnspan=2, pady = 5)
        self.minmax_depth = tk.StringVar()
        self.minmax_depth.set('6')
        self.depth_choice = tk.Spinbox(self,
                                 textvariable = self.minmax_depth,
                                  from_ = MIN_DEPTH,
                                  to = MAX_DEPTH,
                                  increment = 1)
        
        self.depth_choice.grid(row=5, column = 0, columnspan=2, pady=10)

        self.heuristic_actuelle = tk.StringVar()

        self.heuristic_minmax = tk.StringVar()
        tk.Label(self, text = 'heuristique position  :').grid(row=6, column=0)
        tk.Label(self, textvariable = self.heuristic_actuelle).grid(row=6, column=1)
        tk.Label(self, text = ' heuristique min-max :').grid(row=7, column=0)
        tk.Label(self, textvariable = self.heuristic_minmax).grid(row=7, column=1)
        self.heuristic_actuelle.set('--')
        self.heuristic_minmax.set('--')

    def get(self) :
        """ return settings dict """
        settings = { 'minmax_depth' : int(self.minmax_depth.get()),
                     'ia_cntl' : self.iactl.get(),
                     'human_play_first' :self.human_play_first.get()  }
        return settings
    
class Playing_LARVE(tk.Frame) :    
    def __init__(self, master, width, height,action) :
        super().__init__(master, width=width, height=height)        

        self.map_button_to_moves = {}
        
        self.btn1 = tk.Button(self,text="NW", command = lambda  : action( (LARVE, NW)))
        
        self.btn2 = tk.Button(self,text="NE", command = lambda  : action( (LARVE, NE)))
        

        self.lbl1 = tk.Label(self,text='Mouvement')
        self.btn3 = tk.Button(self,text="SW", command = lambda  : action( (LARVE, SW)))
        self.btn4 = tk.Button(self,text="SE", command = lambda  : action( (LARVE, SE)))

        self.map_button_to_moves[self.btn1] = NW
        self.map_button_to_moves[self.btn2] = NE
        self.map_button_to_moves[self.btn3] = SW
        self.map_button_to_moves[self.btn4] = SE
        
        self.btn1.grid(row=0, column=0)
        self.btn2.grid(row=0, column=2)
        self.lbl1.grid(row=1, column=1)
        self.btn3.grid(row=2, column=0)
        self.btn4.grid(row=2, column=2)

    def disable_moves(self,moves) :
        """ désactive les boutons de mouvement de la larve qui ne sont pas dans les mouvements """
        for btn in self.map_button_to_moves :
            if self.map_button_to_moves[btn] not in moves :
                btn.configure(state='disabled')
            else :
                btn.configure(state='normal')
        
    def all_off(self):
        self.disable_moves( ())

    def all_on(self) :
        for btn in self.map_button_to_moves : btn.configure(state='normal')
       
class Playing_PIOUS(tk.Frame) :
    
    def __init__(self, master, width, height, action) :
        super().__init__(master, width=width, height=height)

        self.map_button_to_moves = {}
        
        self.btn1 = tk.Button(self,text="NO", command = lambda  : action((PIOUS, (0, NW))))
        self.map_button_to_moves[self.btn1] = (0, NW) 

        self.btn2 = tk.Button(self,text="NE", command = lambda  : action((PIOUS, (0, NE))))
        self.map_button_to_moves[self.btn2] = (0, NE)
        
        self.lbl1 = tk.Label(self,text='1')
        
        self.btn3 = tk.Button(self,text="NO", command = lambda  : action((PIOUS, (1, NW))))
        self.map_button_to_moves[self.btn3] = (1, NW) 
        self.btn4 = tk.Button(self,text="NE", command = lambda  : action((PIOUS, (1, NE))))
        self.map_button_to_moves[self.btn4] = (1, NE) 
        self.lbl2 = tk.Label(self,text='2')

        self.btn5 = tk.Button(self,text="NO", command = lambda  : action((PIOUS, (2, NW))))
        self.map_button_to_moves[self.btn5] = (2, NW) 
        self.btn6 = tk.Button(self,text="NE", command = lambda  : action((PIOUS, (2, NE))))
        self.map_button_to_moves[self.btn6] = (2, NE) 
        self.lbl3 = tk.Label(self,text='3')

        self.btn7 = tk.Button(self,text="NO", command = lambda  : action((PIOUS, (3, NW))))
        self.map_button_to_moves[self.btn7] = (3, NW) 
        self.btn8 = tk.Button(self,text="NE", command = lambda  : action((PIOUS, (3, NE))))
        self.map_button_to_moves[self.btn8] = (3, NE) 
        self.lbl4 = tk.Label(self,text='4')
     
        self.btn1.grid(row=0, column=0)
        self.lbl1.grid(row=1, column=1)
        self.btn2.grid(row=0, column=2)
        
        self.btn3.grid(row=0, column=3)
        self.lbl2.grid(row=1, column=4)        
        self.btn4.grid(row=0, column=5)
        
        self.btn5.grid(row=0, column=6)
        self.lbl3.grid(row=1, column=7)        
        self.btn6.grid(row=0, column=8)
        
        self.btn7.grid(row=0, column=9)
        self.lbl4.grid(row=1, column=10)
        self.btn8.grid(row=0, column=11)

        for i in [0,2,3,5,6,8,9,11]:
            self.columnconfigure(i, minsize=45)
            
    def disable_moves(self,moves) :
        """ désactive les boutons de mouvement des oiseaux qui ne sont pas dans les mouvements """
        for btn in self.map_button_to_moves :
            if self.map_button_to_moves[btn] not in moves :
                btn.configure(state='disabled')
            else :
                btn.configure(state='normal')
        
    def all_off(self):
        self.disable_moves( ())

    def all_on(self) :
        for btn in self.map_button_to_moves : btn.configure(state='normal')
        
       
class Grid(tk.Canvas):
    def __init__(self, master, images, width, height) :
        
        super().__init__(master,
                         width=width,
                         height = 8*SIZE+10,
                         bd=5,
                         bg="#fff")
        
        self.bird_images, self.LARVE_image = images
        
        for i in range(8) :
            for j in range(8) :
                if (i+j)%2 : color = LIGHTGREY
                else :color = DARKGREY
                self.create_rectangle(CANVAS_OFFSET+i*SIZE,
                                             CANVAS_OFFSET+j*SIZE,
                                             CANVAS_OFFSET+(i+1)*SIZE,
                                             CANVAS_OFFSET+(j+1)*SIZE,
                                             fill = color )

        # crée les images et les place en dehors du canevas
        x,y = -100, -100
        self.larve = self.create_image(x,y,anchor = tk.CENTER, image = self.LARVE_image)
        self.pious = [self.create_image(x,y,anchor = tk.CENTER,image = im) for im in self.bird_images]

    def place_creatures(self, config) :
        larve, pious = config

        xl, yl = larve
        x = CANVAS_OFFSET + xl*SIZE +5
        y = CANVAS_OFFSET + yl*SIZE +5

        self.moveto(self.larve,x, y)
        
        for i,(xl, yl) in enumerate(pious):
            x = CANVAS_OFFSET + xl*SIZE 
            y = CANVAS_OFFSET + yl*SIZE 
            self.moveto(self.pious[i],x, y)
           
    def move_LARVE(self, move) :
        dx, dy = move
        self.move(self.larve, dx*SIZE, dy*SIZE)

    def move_bird(self, move) :
        i, (dx, dy) = move
        self.move(self.pious[i], dx*SIZE, dy*SIZE)
     

class App(tk.Tk) :
    
    def __init__(self) :
        super().__init__()

        self.title("Oiseaux et larve")
        self.geometry("700x600")

        # Chargement des images 
        bird_image1 = ImageTk.PhotoImage(Image.open(FICHIER_PIOU1),master=self)
        bird_image2 = ImageTk.PhotoImage(Image.open(FICHIER_PIOU2),master=self)
        bird_image3 = ImageTk.PhotoImage(Image.open(FICHIER_PIOU3),master=self)
        bird_image4 = ImageTk.PhotoImage(Image.open(FICHIER_PIOU4 ),master=self)
    
        LARVE_image = ImageTk.PhotoImage(Image.open(FICHIER_LARVE),master=self)

        dessins = (bird_image1,bird_image2,bird_image3,bird_image4),LARVE_image
        
        self.plateau = Grid(self, images = dessins, width=8*SIZE+10, height=8*SIZE+10 )
        
        self.plateau.place_creatures(INITIAL)
        self.plateau.grid(column = 0, row = 1)


        self.settings_frame=Setting_frame(self,width=250, height = 300)
        self.settings_frame.grid(column = 1, row = 1)
        self.settings_frame.grid_propagate(0)

        self.playing_LARVE_frame = Playing_LARVE(self, width =200, height = 80,action = self.human_play)
        self.playing_LARVE_frame.grid(row = 0, column = 0)
        self.playing_LARVE_frame.grid_propagate(0)
        self.playing_LARVE_frame.all_off()

        self.playing_PIOUS_frame = Playing_PIOUS(self, width =400, height = 80,action = self.human_play)
        self.playing_PIOUS_frame.grid(row = 2, column = 0)
        self.playing_PIOUS_frame.grid_propagate(0)
        self.playing_PIOUS_frame.all_off()

        self.control_frame = tk.Frame(self, width=250, height=80)
        self.control_frame.grid(row=2,column=1)
        self.control_frame.grid_propagate(0)

        start_button = tk.Button(self.control_frame,text='Jouer', command= self.start, width=10, height=2)
        start_button.pack()



    def start(self) :
        # print(' on joue')
        
        # récupération des paramètres de jeu
        self.settings = self.settings_frame.get()

        # détermination du premier joueur
        if self.settings['human_play_first'] :
            first_player = 1 - self.settings['ia_cntl']
        else :
            first_player = self.settings['ia_cntl']

        # position initiale du jeu
        self.position = (first_player, INITIAL)
        
        # inactivation des boutons
        if self.settings['ia_cntl'] == PIOUS :
            self.playing_LARVE_frame.disable_moves(mouvements_larve(INITIAL))
            self.playing_PIOUS_frame.all_off()
        else :
            self.playing_PIOUS_frame.disable_moves(mouvements_pious(INITIAL))
            self.playing_LARVE_frame.all_off()
        
        if not self.settings['human_play_first'] :
            self.ia_play2()

    def human_win(self) :
        messagebox.showinfo(title=None, message=" Vous avez gagné !")
        self.reset()
    def human_defeat(self) :
        messagebox.showinfo(title=None, message=" Vous avez perdu !")
        self.reset()
    
    def reset(self) :
        self.playing_PIOUS_frame.all_off()
        self.playing_LARVE_frame.all_off()
        self.plateau.place_creatures(INITIAL)

    def ia_play2(self) :
        n = self.settings['minmax_depth']
 
        player, config = self.position
        moves = mouvements(self.position) 

        if moves == [] :
            self.human_win()
            return

        if player == LARVE :
            # On cherche à maximiser les mouvements
            s = -inf
            for move in moves :
                score = minmax(deplacer(self.position, move), n-1)
                if score > s : 
                    s = score
                    best = move
            self.plateau.move_LARVE(best)

        else :
            s = +inf
            for move in moves :
                score = maxmin(deplacer(self.position, move), n-1)
                if score < s : 
                    s = score
                    best = move
            self.plateau.move_bird(best)

        self.settings_frame.heuristic_minmax.set(str(s))
        self.position = deplacer(self.position, best)   
        
        # On désactive les boutons
        _, config = self.position
        if player == LARVE :
            self.playing_PIOUS_frame.disable_moves(mouvements_pious(config))
        else :
            self.playing_LARVE_frame.disable_moves(mouvements_larve(config))
        print("L'IA joue à la place de ", map_names[player], )
        self.plateau.update_idletasks()
        self.settings_frame.heuristic_actuelle.set(str(heuristique(self.position)))
 
        moves = mouvements(self.position) 
        if moves == [] :
            self.human_defeat()

    def human_play(self,btn) :
        role, move = btn

        player, config = self.position
        
        if role == LARVE :
            self.plateau.move_LARVE(move)
            new_config = deplacer_larve(config, move)
            self.position = (PIOUS, new_config)
        else :
            self.plateau.move_bird(move)
            new_config = deplacer_piou(config, move)
            self.position = (LARVE,new_config)
        self.plateau.update_idletasks()
                
        self.ia_play2()
       

fenetre = App()

ia_control = PIOUS

fenetre.mainloop()



    
    
