#include <TM1637Display.h>

// Initialisation des afficheurs 7 segments pour chaque joueur
TM1637Display display(11, 12); // CLK, DIO pour le joueur 1
TM1637Display display2(9, 8);  // CLK, DIO pour le joueur 2

// Boutons pour chaque joueur
int buttonPlayer1 = 5;
int buttonPlayer2 = 10;
int modeButton = 4; // Bouton pour choisir le mode de jeu

// Variables pour les compteurs de chaque joueur (en secondes)
int counterPlayer1 = 180;  // Par défaut : 3 minutes (180 secondes)
int counterPlayer2 = 180;  // Par défaut : 3 minutes (180 secondes)

// Rajouts de temps pour les modes avec incréments
int incrementPlayer1 = 0;
int incrementPlayer2 = 0;

unsigned long previousMillis = 0;  // Pour le chronométrage
const long interval = 1000;        // Intervalle d'une seconde

bool player1Turn = true;  // Indicateur pour savoir quel joueur joue
bool player2Turn = false;
bool gameStarted = false; // Indicateur pour savoir si le jeu a démarré
bool player1HasStarted = false; // Indicateur pour savoir si le joueur 1 a démarré son compteur
bool player2HasStarted = false; // Indicateur pour savoir si le joueur 2 a démarré son compteur

int gameMode = 0; // 0 = 3 min, 1 = 5 min + 2 sec, 2 = 10 min + 5 sec, 3 = 15 min + 10 sec

// Variables pour le double-clic
unsigned long lastClickTime = 0;
bool doubleClickDetected = false;
const long doubleClickInterval = 500; // Intervalle pour détecter un double-clic (500 ms)

// Variables pour le clignotement
bool gameOver = false;
bool player1Blinking = false;
bool player2Blinking = false;
unsigned long blinkInterval = 500; // Intervalle de clignotement
unsigned long lastBlinkTime = 0;
bool blinkState = false;

void setup() {
  // Configurer les broches des boutons comme entrées avec pullup
  pinMode(buttonPlayer1, INPUT_PULLUP);
  pinMode(buttonPlayer2, INPUT_PULLUP);
  pinMode(modeButton, INPUT_PULLUP);

  display.setBrightness(4); // Luminosité de 0 à 7
  display.clear();
  display2.setBrightness(4); // Luminosité de 0 à 7
  display2.clear();

  // Initialiser les deux afficheurs à 00:00
  display.showNumberDecEx(0, 0x40, true, 2, 0);  // Affiche "00"
  display2.showNumberDecEx(0, 0x40, true, 2, 0); // Affiche "00"
}

void loop() {
  unsigned long currentTime = millis();

  // Gestion du double clic
  if (digitalRead(modeButton) == LOW) {
    if (currentTime - lastClickTime < doubleClickInterval) {
      // Double clic détecté
      doubleClickDetected = true;
      resetGame();  // Appeler la fonction reset en cas de double-clic
    }
    lastClickTime = currentTime;
    delay(300); // Anti-rebond
  }

  // Si le jeu est terminé, gérer le clignotement
  if (gameOver) {
    handleBlinking(currentTime);
    return; // Sortir de la boucle tant que le jeu n'est pas réinitialisé
  }

  if (!gameStarted && !doubleClickDetected) {
    // Choix du mode de jeu
    if (digitalRead(modeButton) == LOW) {
      delay(300); // Anti-rebond
      gameMode++;
      if (gameMode > 3) gameMode = 0; // Revenir au premier mode après le quatrième

      // Ajuster les compteurs et les incréments selon le mode sélectionné
      switch (gameMode) {
        case 0:
          counterPlayer1 = 180; // 3 minutes
          counterPlayer2 = 180;
          incrementPlayer1 = 0;
          incrementPlayer2 = 0;
          break;
        case 1:
          counterPlayer1 = 300; // 5 minutes
          counterPlayer2 = 300;
          incrementPlayer1 = 2; // +2 secondes
          incrementPlayer2 = 2;
          break;
        case 2:
          counterPlayer1 = 600; // 10 minutes
          counterPlayer2 = 600;
          incrementPlayer1 = 5; // +5 secondes
          incrementPlayer2 = 5;
          break;
        case 3:
          counterPlayer1 = 900; // 15 minutes
          counterPlayer2 = 900;
          incrementPlayer1 = 10; // +10 secondes
          incrementPlayer2 = 10;
          break;
      }

      // Afficher le temps initial sélectionné
      displayTime(counterPlayer1, display);
      displayTime(counterPlayer2, display2);
    }

    // Commencer le jeu lorsque l'un des boutons est pressé
    if (digitalRead(buttonPlayer1) == LOW || digitalRead(buttonPlayer2) == LOW) {
      gameStarted = true;
      previousMillis = millis(); // Réinitialiser le chronomètre
    }
  } else if (!doubleClickDetected) {
    unsigned long currentMillis = millis();

    // Vérifier si le bouton du joueur 1 est pressé
    if (digitalRead(buttonPlayer1) == LOW && !player1Turn) {
      player1Turn = true;
      player2Turn = false;

      // Ajouter les secondes supplémentaires seulement si ce n'est pas le début
      if (player1HasStarted) {
        counterPlayer1 += incrementPlayer1; // Ajouter les secondes supplémentaires après le premier tour
      } else {
        player1HasStarted = true; // Marquer le compteur comme démarré
      }
    }

    // Vérifier si le bouton du joueur 2 est pressé
    if (digitalRead(buttonPlayer2) == LOW && !player2Turn) {
      player1Turn = false;
      player2Turn = true;

      // Ajouter les secondes supplémentaires seulement si ce n'est pas le début
      if (player2HasStarted) {
        counterPlayer2 += incrementPlayer2; // Ajouter les secondes supplémentaires après le premier tour
      } else {
        player2HasStarted = true; // Marquer le compteur comme démarré
      }
    }

    // Compteur pour le joueur 1
    if (player1Turn && currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (counterPlayer1 > 0) {
        counterPlayer1--;
      } else {
        // Le joueur 1 est à 0, le jeu est terminé
        gameOver = true;
        player1Blinking = true;
        return;
      }
      displayTime(counterPlayer1, display);
    }

    // Compteur pour le joueur 2
    if (player2Turn && currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      if (counterPlayer2 > 0) {
        counterPlayer2--;
      } else {
        // Le joueur 2 est à 0, le jeu est terminé
        gameOver = true;
        player2Blinking = true;
        return;
      }
      displayTime(counterPlayer2, display2);
    }
  }
}

// Fonction pour afficher le temps au format "MM:SS"
void displayTime(int seconds, TM1637Display& display) {
  int minutes = seconds / 60;
  int remainingSeconds = seconds % 60;

  // Afficher le format MM:SS avec deux chiffres pour chaque partie
  display.showNumberDecEx(minutes * 100 + remainingSeconds, 0x40, true);
}

// Fonction pour réinitialiser le jeu à l'état d'origine
void resetGame() {
  // Remettre tous les états à l'état d'origine
  gameStarted = false;
  player1Turn = true;
  player2Turn = false;
  player1HasStarted = false;
  player2HasStarted = false;
  gameMode = 0;

  // Réinitialiser les compteurs et les incréments
  counterPlayer1 = 180;
  counterPlayer2 = 180;
  incrementPlayer1 = 0;
  incrementPlayer2 = 0;

  // Réinitialiser les afficheurs
  display.clear();
  display2.clear();

  // Afficher le temps initial sur les afficheurs
  displayTime(counterPlayer1, display);
  displayTime(counterPlayer2, display2);

  doubleClickDetected = false; // Réinitialiser le double-clic détecté
  gameOver = false;            // Remettre le jeu à l'état initial
  player1Blinking = false;
  player2Blinking = false;
  blinkState = false;
}

// Fonction pour gérer le clignotement
void handleBlinking(unsigned long currentTime) {
  if (currentTime - lastBlinkTime >= blinkInterval) {
    lastBlinkTime = currentTime;
    blinkState = !blinkState;

    if (player1Blinking) {
      if (blinkState) {
        display.clear();
      } else {
        displayTime(counterPlayer1, display);
      }
    }

    if (player2Blinking) {
      if (blinkState) {
        display2.clear();
      } else {
        displayTime(counterPlayer2, display2);
      }
    }
  }
}
4-Digit Display
4-Digit Display