#include <LiquidCrystal_I2C.h>
#include  "variables.h"
#include "configJeu.h"
int J1, J2;
int seuilActionBas = 15;
int seuilActionHaut = 1000;

struct Coordonnees{ int colonne;  int ligne;  };

struct Perso
{
Coordonnees Position{0,0};
int Vitesse = 100;
unsigned long CompteurVitesse=0;
};

struct Mechant
{
Coordonnees Position{14,1};
int Vitesse = 300;
unsigned long CompteurVitesse=0;
byte CompteurPosition = 1;
};

struct Clef
{
Coordonnees Position{14,2};
};
LiquidCrystal_I2C lcd(0x27, 20, 4);
Perso perso;
Mechant mechant;
Clef clef;
Coordonnees obtenirDeplacement(Direction direction) {
    switch (direction) {
        case DROITE:       return {1, 0};
        case GAUCHE:       return {-1, 0};
        case HAUT:         return {0, -1};
        case BAS:          return {0, 1};
        case HAUTDROITE:  return {1, -1};
        case HAUTGAUCHE:  return {-1, -1};
        case BASDROITE:   return {1, 1};
        case BASGAUCHE:   return {-1, 1};
        default:           return {0, 0}; // Pas de mouvement
    }
}

void deplacementLosange(Mechant &mechant) {
    const Direction pattern[] = {BASDROITE, BASGAUCHE, HAUTGAUCHE, HAUTDROITE};
    static byte index = 0;
    Coordonnees deplacement = obtenirDeplacement(pattern[index]);
    mechant.Position.colonne += deplacement.colonne;
    mechant.Position.ligne += deplacement.ligne;
    index = (index + 1) % 4;
}

void deplacementCarre(Mechant &mechant) {
    const Direction pattern[] = {DROITE, BAS,BAS,GAUCHE,GAUCHE,HAUT, HAUT,DROITE};
    static byte index = 0;
    Coordonnees deplacement = obtenirDeplacement(pattern[index]);
    mechant.Position.colonne += deplacement.colonne;
    mechant.Position.ligne += deplacement.ligne;
    index = (index + 1) % 8;
}

void deplacementAngle(Mechant &mechant) {
    const Direction pattern[] = {DROITE, BAS, BAS, GAUCHE,DROITE,HAUT,HAUT,GAUCHE};
    static byte index = 0;
    Coordonnees deplacement = obtenirDeplacement(pattern[index]);
    mechant.Position.colonne += deplacement.colonne;
    mechant.Position.ligne += deplacement.ligne;
    index = (index + 1) % 8;
}

void deplacementZigzag(Mechant &mechant) {
    const Direction pattern[] = {DROITE, GAUCHE, GAUCHE, DROITE};
    static byte index = 0;
    Coordonnees deplacement = obtenirDeplacement(pattern[index]);
    mechant.Position.colonne += deplacement.colonne;
    mechant.Position.ligne += deplacement.ligne;
    index = (index + 1) % 4;
}



void setup() 
{
initialise();
}

void loop() { 
  /* CONTROLE DES MOUVEMENTS SUR LES AXES DU JOYSTICK */
if (millis() > (perso.CompteurVitesse+perso.Vitesse))
{deplacementJoystick();}

if (millis() > (mechant.CompteurVitesse+mechant.Vitesse))
{mechantDeplacement();}

}


void effacerCase()
{
 lcd.print(" ");
}
void mechantDeplacement() {
    // Effacer l'ancienne position
    lcd.setCursor(mechant.Position.colonne, mechant.Position.ligne);
    effacerCase();

    // Déplacement en fonction du type
    switch (typeDeplacementMechant) {
        case LOSANGE:
            deplacementLosange(mechant);
            break;
        case CARRE:
            deplacementCarre(mechant);
            break;
        case ANGLE:
            deplacementAngle(mechant);
            break;
        case ZIGZAG:
            deplacementZigzag(mechant);
            break;
    }

    // Afficher à la nouvelle position
    lcd.setCursor(mechant.Position.colonne, mechant.Position.ligne);
    lcd.write(3);

    // Mettre à jour le compteur de vitesse
    mechant.CompteurVitesse = millis();
}



void droite()
{
  perso.Position.colonne++;
  if (perso.Position.colonne > 19) {perso.Position.colonne = 19;} //on n'accepte le déplacement 
                                 //que dans les limites de l'écran
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne);
  lcd.write(0);
  lcd.setCursor(perso.Position.colonne-1,perso.Position.ligne);
 effacerCase();
    }

void gauche()
{
  perso.Position.colonne--;
  if (perso.Position.colonne < 0) {perso.Position.colonne =0;}
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne);
  lcd.write(0);
  lcd.setCursor(perso.Position.colonne+1,perso.Position.ligne);
  effacerCase();
  }

void bas()
{
  perso.Position.ligne++;
  if (perso.Position.ligne > 3) {perso.Position.ligne=3;}
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne);
  lcd.write(0);
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne-1);
  effacerCase();
}

void haut()
{
    perso.Position.ligne--;
    if (perso.Position.ligne < 0) {perso.Position.ligne=0;} 
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne);
  lcd.write(0);
  lcd.setCursor(perso.Position.colonne,perso.Position.ligne+1);
  effacerCase();
  }

void initialise()
{
    lcd.init();
  lcd.backlight();
  lcd.createChar(0, persoGraphique);
  lcd.createChar(1, coeurGraphique);  
  lcd.createChar(3, mechantGraphique);  
  lcd.createChar(4, clefGraphique);  

  lcd.setCursor(perso.Position.colonne,perso.Position.ligne);
  lcd.write(0);

  lcd.setCursor(19,3); // on se positionne en bas à droite
  lcd.write(1); // on affiche un objet "coeur"

  lcd.setCursor(mechant.Position.colonne,mechant.Position.ligne);
  lcd.write(3);
  lcd.setCursor(clef.Position.colonne,clef.Position.ligne);
  lcd.write(4);
}

void deplacementJoystick()
{ 
  J1 = analogRead(0); J2 = analogRead(1);

if (J1 < seuilActionBas) {bas();perso.CompteurVitesse = millis();}
if (J1 > seuilActionHaut) {haut();perso.CompteurVitesse = millis();}
if (J2 < seuilActionBas) {droite();perso.CompteurVitesse = millis();}
if (J2 >seuilActionHaut) {gauche();perso.CompteurVitesse = millis();}
}