// Forum: https://forum.arduino.cc/t/switch-case-in-a-loop/1235008/7
// This Wokwi project: https://wokwi.com/projects/393511027935392769


#include <Arduino.h>

// Define LED pin connections
const int PumpPins[] = {2, 3, 4, 5, 6, 7};
const int AnzahlPumpen = 6;
int chronoON = 10000;
int chronoOFF = 3500;

// Define operation modes
enum Mode { ALL_ZUSAMMEN, NACHEINANDER_01, NACHEINANDER_02, NACHEINANDER_03 };
const int numModes = 4;

// Declare functions
void AllePumpenEinschalten(int AnzahlPumpen);
void EinePumpeNacheinanderEinschalten(int AnzahlPumpen);
void ZweiPumpenNacheinanderEinschalten(int AnzahlPumpen);
void DreiPumpenNacheinanderEinschalten(int AnzahlPumpen);
int ModeBeantragen(int AnzahlPumpen);
void ModeAnzeigen();

// Array of function pointers for mode selection
void (*modeFunctions[])(int) = {AllePumpenEinschalten, EinePumpeNacheinanderEinschalten, ZweiPumpenNacheinanderEinschalten, DreiPumpenNacheinanderEinschalten};
const char* ModeBeschreibung[] = {"-- ALLE PUMPEN GLEICHZEITICH TESTEN --", "-- EINE PUMPE NACHEINANDER TESTEN --", "-- ZWEI PUMPEN NACHEINANDER TESTEN --", "-- DREI PUMPEN NACHEINANDER TESTEN --"};

void setup() {
  // Initialize LED pins as outputs
  for (int i = 0; i < AnzahlPumpen; i++) {
    pinMode(PumpPins[i], OUTPUT);
  }
  Serial.begin(9600); // Start serial communication
}

void loop() {
  int AnzahlPumpenEingeschaltet;
  bool RichtigeAnzahlPumpen = false;
  
  // Request number of LEDs to light (with validation)
  while (!RichtigeAnzahlPumpen) {
    Serial.println("Wieviel Pumpen wollen Sie testen (min 1 - max 6): ");
    while (!Serial.available()) {} // Wait for user input
    AnzahlPumpenEingeschaltet = Serial.parseInt(); // Read user input as integer
    if (AnzahlPumpenEingeschaltet > 0 && AnzahlPumpenEingeschaltet <= AnzahlPumpen) {
      Serial.print(AnzahlPumpenEingeschaltet); // Inform user about the chosen number of LEDs
      Serial.println(" Pumpen werden getestet.");
      RichtigeAnzahlPumpen = true; // Exit loop if valid input received
    }
    else {
      Serial.println("Bitte geben Sie eine Nummer zwischen 1 et 6 ein. ");
    }
  }
  int GewaeltMode = ModeBeantragen(AnzahlPumpenEingeschaltet); // Request and validate mode choice
  Serial.print(AnzahlPumpenEingeschaltet);
  Serial.print(" Pumpen werden getestet, in Modus: ");
  Serial.println(ModeBeschreibung[GewaeltMode]); // Inform user about the chosen mode
  modeFunctions[GewaeltMode](AnzahlPumpenEingeschaltet); // Process the chosen mode (execute the corresponding function)
}

int ModeBeantragen(int AnzahlPumpen) {
  int mode;
  bool RichtigeMode = false;
  while (!RichtigeMode) {
    ModeAnzeigen();
    Serial.println("Wählen Sie bitte einen Ziffer (Test). ");
    while (!Serial.available()) {} // Attendre l'entrée de l'utilisateur
    mode = Serial.parseInt(); // Lire l'entrée de l'utilisateur comme un entier

    if (mode >= 0 && mode < numModes) {
      RichtigeMode = true;
    } else {
      Serial.println("Bitte einen Ziffer zwischen 0 & 3 eingeben. ");
    }
  }
  return mode;
}

void AllePumpenEinschalten(int AnzahlPumpen) {
  int count = 0;
  while(true){
    for (int i = 0; i < AnzahlPumpen; i++) {
      digitalWrite(PumpPins[i], HIGH);
    }      
    delay(chronoON);
    for (int i = 0; i < AnzahlPumpen; i++ ){
      digitalWrite(PumpPins[i], LOW);
    }
    delay(chronoOFF);
    count++;
    Serial.print("All Pumps had been turned on/off: ");
    Serial.print(count);
    Serial.println(" times");
    if (Serial.available()){
      char userInput = Serial.read();
      if (userInput == 'b'){
        break;
      }
    }
  }
}

void EinePumpeNacheinanderEinschalten(int AnzahlPumpen) {
  int count01 = 1;
  while(true){
    for (int i = 0; i < AnzahlPumpen; i++) {
      digitalWrite(PumpPins[i], HIGH);
      delay(chronoON);
      digitalWrite(PumpPins[i], LOW);
      Serial.print("Pump ");
      Serial.print(i+1);
      Serial.print(" had been turned on/off: ");
      Serial.print(count01);
      Serial.println(" times");
    }
    count01++;
    if (Serial.available()){
      char userInput = Serial.read();
      if (userInput == 'b'){
        break;
      }
    }
  }
}

void ZweiPumpenNacheinanderEinschalten(int AnzahlPumpen) {
  int cycleCount = 1; // Track the overall cycle number
  int pairCount = 1; // Count for each LED pair within a cycle
  while (true) {
    for (int i = 0; i < AnzahlPumpen; i += 2) {
      // Light the current pair of LEDs (i and i+1)
      if (i + 1 < AnzahlPumpen) {
        digitalWrite(PumpPins[i], HIGH);
        digitalWrite(PumpPins[i + 1], HIGH);
      } 
      else {
        digitalWrite(PumpPins[i], HIGH);
      }
      delay(chronoON); // Wait to see the LEDs lit
      digitalWrite(PumpPins[i], LOW);
      if (i + 1 < AnzahlPumpen) {
        digitalWrite(PumpPins[i + 1], LOW);
      }
      Serial.print("Pumps ");
      Serial.print(i + 1);
      if (i + 1 < AnzahlPumpen) {
        Serial.print(" & ");
        Serial.print(i + 2);
      }
      Serial.print(" turned on/off: ");
      Serial.print(cycleCount);
      Serial.println(" times");
      pairCount++; // Increment count for each LED pair
      // Reset pairCount and increment cycleCount at the end of the cycle
      if (i == AnzahlPumpen - 2) { // Check if it's the last LED pair
        pairCount = 1;
        cycleCount++;
      }
    }
    if (Serial.available()){
      char userInput = Serial.read();
      if (userInput == 'b'){
        break;
      }
    }
  }
}

void DreiPumpenNacheinanderEinschalten(int AnzahlPumpen) {
  int cycleCount = 1; // Track the overall cycle number
  int pairCount = 1; // Count for each LED pair within a cycle
  while (true) {
    for (int i = 0; i < AnzahlPumpen; i += 3) {
      // Light the current pair of LEDs (i and i+1)
      if (i + 1 < AnzahlPumpen) {
        digitalWrite(PumpPins[i], HIGH);
        digitalWrite(PumpPins[i + 1], HIGH);
        digitalWrite(PumpPins[i + 2], HIGH);
      } else {
        digitalWrite(PumpPins[i], HIGH);
      }
      delay(chronoON); // Wait to see the LEDs lit
      digitalWrite(PumpPins[i], LOW);
      if (i + 1 < AnzahlPumpen) {
        digitalWrite(PumpPins[i + 1], LOW);
        digitalWrite(PumpPins[i + 2], LOW);
      }
      Serial.print("Pumps ");
      Serial.print(i + 1);
      if (i + 1 < AnzahlPumpen) {
        Serial.print(", ");
        Serial.print(i + 2);
        Serial.print(" & ");
        Serial.print(i + 3);
      }
      Serial.print(" turned on/off: ");
      Serial.print(cycleCount);
      Serial.println(" times");
      pairCount++; // Increment count for each LED pair
      // Reset pairCount and increment cycleCount at the end of the cycle
      if (i == AnzahlPumpen - 3) { // Check if it's the last LED pair
        pairCount = 2;
        cycleCount++;
      }
    }
    if (Serial.available()){
      char userInput = Serial.read();
      if (userInput == 'b'){
        break;
      }
    }
  }
}

void ModeAnzeigen() {
  Serial.println("Welcher Test wollen Sie durchführen: ");
  for (int i = 0; i < numModes; ++i) {
    Serial.print(i);
    Serial.print(": ");
    Serial.println(ModeBeschreibung[i]);
  }
}