#include <FastLED.h>

//Nombre de leds sur chaque ruban de leds
#define LED1_nombre 40
#define LED2_nombre 5
#define LED3_nombre 5
CRGB leds1[LED1_nombre];
CRGB leds2[LED2_nombre];
CRGB leds3[LED3_nombre];

//Leds allumées pour afficher le score
const byte N1[3] = {4,5,14};// Leds allumés pour produire le score 1
const byte N2[6] = {4,5,14,3,6,13};// Leds allumés pour produire le score 2
const byte N3[9] = {4,5,14,3,6,13,2,7,12}; // Leds allumés pour produire le score 3
const byte N4[12] = {4,5,14,3,6,13,2,7,12,1,8,11}; // Leds allumés pour produire le score 4


// Paramètres du jeu
const byte leds_allumees_initiales_nombre = 5;
const byte leds_allumees_initiales_couleur_joueur1[3] = {255,0,0};
const byte leds_allumees_initiales_couleur_joueur2[3] = {0,255,0};

// Initialisation des variables utilisées par le programme
byte jeu_debut;
byte jeu_etat = 0;
unsigned long jeu_temps_debut;
unsigned long jeu_temps_courant;
unsigned int jeu_temps_attente = 60;
bool joueur1_bouton = 0;
byte joueur1_score = 0;
bool joueur1_victoire = 0;
bool joueur1_tour = 0;
bool joueur2_bouton = 0;
bool joueur2_victoire = 0;
byte joueur2_score = 0;
bool joueur2_tour = 0;
float changement = 0;
float changement_on = 1;
char i;
char m;
int x;
char led_position;


//Affectation des ports ARDUINO
void setup() {
  FastLED.addLeds<WS2812B, 8, GRB>(leds1, LED1_nombre); // Guirlande de jeu déclaré et branché en pin 8
  FastLED.addLeds<WS2812B, 9, GRB>(leds2, LED2_nombre);
  FastLED.addLeds<WS2812B, 10, GRB>(leds3, LED3_nombre);
  pinMode(2, INPUT_PULLUP);// Bouton joueur 1
  pinMode(3, INPUT_PULLUP); // Bouton joueur 1=2
  attachInterrupt(0, RED, FALLING);
  attachInterrupt(1, GREEN, FALLING);
}


//Boucle principale du programme
void loop() {
  switch (jeu_etat) {
    case 0: 
	animation_initiale();
        break;
    case 1:
        animation_principale();
	break;
    case 2:
	test_joueur2();
	break;
    case 3:
	test_joueur1();
	break;
    case 4:
	victoire();
	break;
    }
}

void animation_initiale() {
   for(i=0 ; i < leds_allumees_initiales_nombre ; i++){
      leds1[i].setRGB(255,0,0);
      leds2[i].setRGB(255,0,0);
      FastLED.show();
   }
}

void animation_principale(){
   showscore();
   if (jeu_debut == 0) {
     joueur1_vers_joueur2jeu_debut();
   }
   else {
     joueur2_vers_joueur1jeu_debut();
   }
}

void test_joueur2(){
      if (led_position > 34) {
        joueur1_tour = 0;
        joueur2_vers_joueur1();
      }
      else {
        joueur1_victoire = 1;
        changement=0;
        jeu_etat = 4;
      }
}

void test_joueur1(){
      if (led_position < 5) {
        joueur2_tour = 0;
        joueur1_vers_joueur2();
      }
      else {
        joueur2_victoire = 1;
 //       byte changement = 0;
        jeu_etat = 4;
      }
}

void victoire() {
      jeu_temps_attente = 60;
      if (joueur1_victoire == 1) {
        joueur1_victoire = 0;
        joueur1_score++;
        if (joueur1_score == 5) { //limite score
          joueur1_victoireanimation();
          jeu_etat = 0;
          joueur1_score = 0;
          joueur2_score = 0;
          joueur1_tour = 0;
          joueur2_tour = 0;
          leds2off();
          leds3off();
        }
        else {
          showscore();
          jeu_debut = 1;
          jeu_etat = 1;
          joueur1_tour = 0;
        }
      }
      if (joueur2_victoire == 1) {
        joueur2_victoire = 0;
        joueur2_score++;
        if (joueur2_score == 5) { // limite score
          joueur2_victoireanimation();
          jeu_etat = 0;
          joueur1_score = 0;
          joueur2_score = 0;
          joueur1_tour = 0;
          joueur2_tour = 0;
          leds2off();
          leds3off();
        }
        else {
          showscore();
          jeu_debut = 0;
          jeu_etat = 1;
          joueur2_tour = 0;
        }
      }  
}



void joueur1_vers_joueur2jeu_debut() { 
  joueur1_tour = 0;
  float changement=0;
  for (i = 0; i < LED1_nombre; i++) { // Jeu en cours - Cas quand rouge commence premier echange
    leds1off();
    if (i < 5) {
      leds1[i].setRGB(255, 0, 0); // Rouge si led entre 1 et 5
    }
    if (i >= 5 && i < 10) {
      leds1[i].setRGB(255, 255, 0); //Jaune  si led entre 5 et 10
    }
    if (i >= 10 && i < 30) {
      leds1[i].setRGB(0, 255, 0); //Vert si led entre 10 et 30
    }
    if (i >= 30 && i < 35) {
      leds1[i].setRGB(255, 255, 0); //Jaune si led entre 30 et 35
    }
    if (i > 34) {
      leds1[i].setRGB(255, 0, 0);// Rouge si supérieur à 34
    }
    FastLED.show();
    if (joueur2_bouton == 1) {
      led_position = i;
      i = LED1_nombre;
      jeu_etat = 2;
      joueur2_bouton = 0;
      
 
    }
    pause();
    if (i == 39) {
      joueur1_victoire = 1;
      jeu_etat = 4;
    float changement = 0;
    }
  }
}

void joueur1_vers_joueur2() {
  if (jeu_temps_attente == 0) { //Vitesse de départ. Plus Le chiffre est negatif, -10 ou -30 par exemple, plus le jeu va vite
  }
  else {
    jeu_temps_attente = jeu_temps_attente - 2 ; // Plus le chiffre est negatif, plus le jeu accelerera entre chaque echange
  }
  for (i = led_position; i < LED1_nombre; i++) {
    leds1off();
    if (i < 5) {
      leds1[i].setRGB(255, 0, 0);// Rouge si led entre 1 et 5
    }
    if (i >= 5 && i < 10) {
      leds1[i].setRGB(255, 255, 0); //Jaune si led entre 5 et 10
    }
    if (i >= 10 && i < 30) {
      leds1[i].setRGB(0, 255, 0);// vert si led entre 10 et 30
    }
    if (i >= 30 && i < 35) {
      leds1[i].setRGB(255, 255, 0);// Jaune si led entre 30 et 35
    }
    if (i > 34) {
      leds1[i].setRGB(255, 0, 0); //Rouge si led entre 35 et 40
    }
    FastLED.show();
    if (joueur2_bouton == 1) {
      led_position = i;
      i = LED1_nombre;
      jeu_etat = 2;
      joueur2_bouton = 0;
      changement+=changement_on;
    }
    pause();
    if (i == 39) {
      joueur1_victoire = 1;
      float changement = 0;
      jeu_etat = 4;
    }
  }
}




void joueur2_vers_joueur1jeu_debut() {  // Jeu en cours - Cas quand vert commence premier echange
  joueur2_tour = 0;
  float changement=0;
  
  for (i = 39; i > -1; i = i - 1) {
    leds1off();
    if (i < 5) {
      leds1[i].setRGB(255, 0, 0); // Rouge si led entre 1 et 5
    }
    if (i >= 5 && i < 10) {
      leds1[i].setRGB(255, 255, 0); // Jaunne si led entre 5 et 10
    }
    if (i >= 10 && i < 30) {
      leds1[i].setRGB(0, 255, 0);// Vert si led entre 10 et 30
    }
    if (i >= 30 && i < 35) {
      leds1[i].setRGB(255, 255, 0);// Jaune si led entre 30 et 35
    }
    if (i > 34) {
      leds1[i].setRGB(255, 0, 0);// Rouge si led entre 1 et 5
    }
    FastLED.show();
    if (joueur1_bouton == 1) {
      led_position = i;
      i = -1;
      jeu_etat = 3;
      changement+=changement_on;
      joueur1_bouton = 0;
      
    }
    pause();
    if (i == 0) {
      joueur2_victoire = 1;
      float changement = 0;
      jeu_etat = 4;
    }
  }
}



void joueur2_vers_joueur1() {
  if (jeu_temps_attente == -20) {
  }
  else {
    jeu_temps_attente = jeu_temps_attente - 4;
  }
  for (i = led_position; i > -1; i = i - 1) {
    leds1off();
     if (i < 5) {
      leds1[i].setRGB(255, 0, 0);// Rouge si led entre 1 et 5
    }
    if (i >= 5 && i < 10) {
      leds1[i].setRGB(255, 255, 0); //Jaune si led entre 5 et 10
    }
    if (i >= 10 && i < 30) {
      leds1[i].setRGB(0, 255, 0);// vert si led entre 10 et 30
    }
    if (i >= 30 && i < 35) {
      leds1[i].setRGB(255, 255, 0);// Jaune si led entre 30 et 35
    }
    if (i > 34) {
      leds1[i].setRGB(255, 0, 0); //Rouge si led entre 35 et 40
       }  
    FastLED.show();
    if (joueur1_bouton == 1) {
      led_position = i;
      i = -1;
      jeu_etat = 3;
      changement+=changement_on;
      joueur1_bouton = 0;
    }
    pause();
    if (i == 0) {
      joueur2_victoire = 1;
      float changement = 0;
      jeu_etat = 4;
    }
  }
}

void showscore() {
  leds2off();
  leds3off();
  switch (joueur1_score) {
   
    case 1:
      for (i = 0; i < sizeof(N1); i++) {
        leds2[N1[i]].setRGB(0, 0, 200);// Couleur du score du joueur 1
      }
      break;
    case 2:
      for (i = 0; i < sizeof(N2); i++) {
        leds2[N2[i]].setRGB(0, 0, 200);// Couleur du score du joueur 1
      }
      break;
    case 3:
      for (i = 0; i < sizeof(N3); i++) {
        leds2[N3[i]].setRGB(0, 0, 200);// Couleur du score du joueur 1
      }
      break;
    case 4:
      for (i = 0; i < sizeof(N4); i++) {
        leds2[N4[i]].setRGB(0, 0, 200);// Couleur du score du joueur 1
      }
      break;
    
  }
  switch (joueur2_score) {
   
    case 1:
      for (i = 0; i < sizeof(N1); i++) {
        leds3[N1[i]].setRGB(255, 0, 255);// Couleur du score du joueur 2
      }
      break;
    case 2:
      for (i = 0; i < sizeof(N2); i++) {
        leds3[N2[i]].setRGB(255, 0, 255);// Couleur du score du joueur 2
      }
      break;
    case 3:
      for (i = 0; i < sizeof(N3); i++) {
        leds3[N3[i]].setRGB(255, 0, 255);// Couleur du score du joueur 2
      }
      break;
    case 4:
      for (i = 0; i < sizeof(N4); i++) {
        leds3[N4[i]].setRGB(255, 0, 255);// Couleur du score du joueur 2
      }
      break;
    
  }
  FastLED.show();
}

void joueur1_victoireanimation() {
  leds1off();
  leds2off();
  leds3off();
  for (i = 0; i < 4; i++) {
    for (m = 0; m < LED2_nombre; m++) {
      leds2[m].setRGB(0, 255, 0);
    }
    for (m = 0; m < LED3_nombre; m++) {
      leds3[m].setRGB(255, 0, 0);
    }
    FastLED.show();
    delay(500);
    for (m = 0; m < LED2_nombre; m++) {
      leds2[m].setRGB(0, 0, 0);
    }
    for (m = 0; m < LED3_nombre; m++) {
      leds3[m].setRGB(0, 0, 0);
    }
    FastLED.show();
    delay(500);
  }
}

void joueur2_victoireanimation() {
  leds1off();
  leds2off();
  leds3off();
  for (i = 0; i < 4; i++) {
    for (m = 0; m < LED3_nombre; m++) {
      leds3[m].setRGB(0, 255, 0);
    }
    for (m = 0; m < LED2_nombre; m++) {
      leds2[m].setRGB(255, 0, 0);
    }
    FastLED.show();
    delay(500);
    for (m = 0; m < LED2_nombre; m++) {
      leds3[m].setRGB(0, 0, 0);
    }
    for (m = 0; m < LED3_nombre; m++) {
      leds2[m].setRGB(0, 0, 0);
    }
    FastLED.show();
    delay(500);
  }
}

void leds2off() {
  for (m = 0; m < LED2_nombre; m++) {
    leds2[m].setRGB(0, 0, 0);
  }
}

void leds3off() {
  for (m = 0; m < LED3_nombre; m++) {
    leds3[m].setRGB(0, 0, 0);
  }
}

void leds1off() {
  for (m = 0; m < LED1_nombre; m++) {
    leds1[m].setRGB(0, 0, 0);
  }
}

void pause() {
  jeu_temps_debut = millis();
  jeu_temps_courant = millis();
  while (jeu_temps_courant - jeu_temps_debut <= jeu_temps_attente) {
    jeu_temps_courant = millis();
  }
}








//CODE INUTILE (A SUPPRIMER)

void RED() {
  if (joueur1_tour == 0) {
    switch (jeu_etat) {
      case 0:
        jeu_etat = 1;
        jeu_debut = 0;
        joueur1_tour = 1;
        break;
      case 1:
        if (jeu_debut == 1) {
          joueur1_bouton = 1;
        }
        joueur1_tour = 1;
        break;
      case 2:
        joueur1_bouton = 1;
        joueur1_tour = 1;
        break;
    }
  }
}

void GREEN() {
  if (joueur2_tour == 0) {
    switch (jeu_etat) {
      case 0:
        jeu_etat = 1;
        jeu_debut = 1;
        joueur2_tour = 1;
      case 1:
        if (jeu_debut == 0) {
          joueur2_bouton = 1;
        }
        joueur2_tour = 1;
        break;
      case 3:
        joueur2_bouton = 1;
        joueur2_tour = 1;
        break;
    }
  }
}
//fin code inutile
