#from __future__ import unicode_literals
# -*- coding: utf-8 -*-
from __future__ import division

class Forme():
    """forme a affecter a une creature, decor ou autre..."""
    def __init__(self, formeCases = "H", parent=None):
        
        self.formeDef = []           #coord relatives par rapport a la case (0,0) definissant la forme (vide si forme 1*1)
        
        #les anneaux sont utilises pour les rotations (coordonnees relatives a la case centrale)
        #attention: il est important que les cases soient enregistrees dans le sens de la rotation (sens des aiguilles d'une montre)
        self.formeCases = formeCases   # "C" ou "H" pour carre ou hexagone        

    def anneau(self, distance=0):
        """renvoie la liste des cases situees a [distance] cases du centre, dans l'ordre des aiguilles d'une montre"""
        anneau = {}
        if self.formeCases == "H":
             anneau[1] = [(0,-1),(1,-0.5),(1,0.5), \
                          (0,1),(-1,0.5),(-1,-0.5)]
             anneau[2] = [(0,-2),(1,-1.5),(2,-1),(2,0),(2,1),(1,1.5), \
                          (0,2),(-1,1.5),(-2,1),(-2,0),(-2,-1),(-1,-1.5)]
             anneau[3] = [(0,-3),(1,-2.5),(2,-2),(3,-1.5),(3,-0.5),(3,0.5),(3,1.5),(2,2),(1,2.5), \
                          (0,3),(-1,2.5),(-2,2),(-3,1.5),(-3,0.5),(-3,-0.5),(-3,-1.5),(-2,-2),(-1,-2.5)]
             anneau[4] = [(0,-4),(1,-3.5),(2,-3),(3,-2.5),(4,-2),(4,-1),(4,0),(4,1),(4,2),(3,2.5),(2,3),(1,3.5), \
                          (0,4),(-1,3.5),(-2,3),(-3,2.5),(-4,2),(-4,1),(-4,0),(-4,-1),(-4,-2),(-3,-2.5),(-2,-3),(-1,-3.5)]
             anneau[5] = [(0,-5),(1,-4.5),(2,-4),(3,-3.5),(4,-3),(5,-2.5),(5,-1.5),(5,-0.5),(5,0.5),(5,1.5),(5,2.5),(4,3),(3,3.5),(2,4),(1,4.5), \
                          (0,5),(-1,4.5),(-2,4),(-3,3.5),(-4,3),(-5,2.5),(-5,1.5),(-5,0.5),(-5,-0.5),(-5,-1.5),(-5,-2.5),(-4,-3),(-3,-3.5),(-2,-4),(-1,-4.5)]
             
        elif self.formeCases == "C":
             anneau[1] = [(0,-1),(1,-1),(1,0),(1,1),\
                          (0,1),(-1,1),(-1,0),(-1,-1)]
             anneau[2] = [(0,-2),(1,-2),(2,-2),(2,-1),(2,0),(2,1),(2,2),(1,2),\
                          (0,2),(-1,2),(-2,2),(-2,1),(-2,0),(-2,-1),(-2,-2),(-1,-2)]
             anneau[3] = [(0,-3),(1,-3),(2,-3),(3,-3),(3,-2),(3,-1),(3,0),(3,1),(3,2),(3,3),(2,3),(1,3),\
                          (0,3),(-1,3),(-2,3),(-3,3),(-3,2),(-3,1),(-3,0),(-3,-1),(-3,-2),(-3,-3),(-2,-3),(-1,-3)]
             anneau[4] = [(0,-4),(1,-4),(2,-4),(3,-4),(4,-4),(4,-3),(4,-2),(4,-1),(4,0),(4,1),(4,2),(4,3),(4,4),(3,4),(2,4),(1,4),\
                          (0,4),(-1,4),(-2,4),(-3,4),(-4,4),(-4,3),(-4,2),(-4,1),(-4,0),(-4,-1),(-4,-2),(-4,-3),(-4,-4),(-3,-4),(-2,-4),(-1,-4)]
             anneau[5] = [(0,-5),(1,-5),(2,-5),(3,-5),(4,-5),(5,-5),(5,-4),(5,-3),(5,-2),(5,-1),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5),(4,5),(3,5),(2,5),(1,5),\
                          (0,5),(-1,5),(-2,5),(-3,5),(-4,5),(-5,5),(-5,4),(-5,3),(-5,2),(-5,1),(-5,0),(-5,-1),(-5,-2),(-5,-3),(-5,-4),(-5,-5),(-4,-5),(-3,-5),(-2,-5),(-1,-5)]
             
        if distance > 0:
             retour = anneau[distance]
        elif distance == 0:
             retour = anneau
             
        return retour
        
             
    def __repr__(self):
        """renvoie la liste des cases occupees par la forme"""
        retour = str(self.listeCases((0,0)))
        return retour
    
    def ajouterCase(self, coordRelatives):
        """ajoute une case a la liste des cases occupees de la forme"""
        ajoutee = False
        if not coordRelatives in self.formeDef:
            for distance in self.anneau(0):
                if coordRelatives in self.anneau(distance):
                     self.formeDef.append(coordRelatives)
                     ajoutee = True
        if not ajoutee:
            print("case non prise en charge (trop eloignee du centre)")
    
    def definirForme(self, formeDef):
        """utilise une forme pre-definie"""
        self.formeDef = []
        if formeDef:
            if len(formeDef)>0:
                for coordRelatives in formeDef:
                    self.ajouterCase(coordRelatives)
        
    def retirerCase(self, coordRelatives):
        """retire une case a la liste des cases occupees de la forme"""
        if coordRelatives in self.formeDef:
            self.formeDef.remove(coordRelatives)    

    def pivoter(self, nbRotations = 1):
        """pivote si possible la forme dans le sens '+' ou '-' et renvoie la liste des cases qui seront occupees"""
        sens = 1
        if nbRotations < 0: sens = -1
        formeDefPivote = []
        tmp = self.formeDef

        if self.formeCases == "H":
            k = 1
        else:
            k = 2  #on avance de deux cases sur l'anneau dans le cas de cases carrees
        
        if len(self.formeDef) > 0:
            for i in range(0,abs(nbRotations)):
                for coord in tmp:
                    #on trouve dans quel anneau se situe cette case
                    distance = 0
                    i = 0
                    while distance == 0 and i <= len(self.anneau(0)):
                        i += 1
                        if coord in self.anneau(i):
                            distance = i
                    #si on a trouve la case, on la deplace selon les conditions de la rotation        
                    if distance > 0:
                        #position actuelle dans la liste des cases de l'anneau
                        position = self.anneau(distance).index(coord) 

                        #le pivot entraine un deplacement dans la liste des cases de l'anneau egal a sa distance au centre
                        nouvellePosition = position + k*sens*distance    
    
                        #retour au debut/a la fin de l'anneau si on atteint la fin/ le debut
                        if nouvellePosition >= len(self.anneau(distance)):   
                            nouvellePosition -= len(self.anneau(distance))
                        elif nouvellePosition < 0:
                            nouvellePosition += len(self.anneau(distance))
                        
                        #on retrouve les nouvelles coordonnees relatives a partir de la position dans l'anneau  
                        nouvellesCoord = self.anneau(distance)[nouvellePosition]
                        #on ajoute cette position a la nouvelle definition de forme
                        formeDefPivote.append((nouvellesCoord[0], nouvellesCoord[1]))
                    else:
                        print("{} non trouvee dans les anneaux".format(coord))
                tmp = formeDefPivote
                formeDefPivote = []
                
            formeDefPivote = tmp    
            return formeDefPivote                     

    def listeCases(self, coordCibles, nbRotations = 0):
        """renvoie la liste des cases occupees par la forme en cours"""
        retour = [coordCibles]
        if nbRotations != 0:
            formeEnCours = self.pivoter(nbRotations)
        else:
            formeEnCours = self.formeDef
        if len(formeEnCours) > 0:
            for coordRelatives in formeEnCours:
                retour.append((coordCibles[0]+coordRelatives[0], coordCibles[1]+coordRelatives[1]))       
        return retour
