#include "button.hpp"

struct LedData {
  unsigned long timeStamp;
  byte startPin   {5};
  byte Num        {0};
  byte prevNum    {1};
  byte maxNum     {6};
  int direction  {-1};
  bool on         {false};
  bool offReady   {true};
};

// Globale Konstanten
constexpr byte potiPin   {A0};     
constexpr byte buttonPin {12};

// Globale Variablen/Objekte
Button onOffButton {buttonPin};     // Erzeuge Buttonobjekt für Pin 12 angeschlossen ist
LedData ledData;

// Forward-Deklaration(en) Funktion(en)
void runningLight(int, LedData&);
void ledsOff(LedData&);
void initLedPins(LedData&);

void setup() {
  Serial.begin(115200);
  onOffButton.begin();        // Initialisiert den Button-Pin: Default ist Active Low (INPUT_PULLUP)
  initLedPins(ledData);
}

void loop() {
  if (onOffButton.tic() != ButtonState::P_NONE) {
    ledData.on ^= true;
  }
  switch(ledData.on) {
    case true:
      ledData.offReady = false;
      runningLight(map(analogRead(potiPin), 0, 1023, 1000, 5), ledData);
      break;
    case false:
      ledsOff(ledData);
      break;
  }
}

void initLedPins(LedData& leds) {
  for ( byte pin=0 ; pin < leds.maxNum; ++pin) {
    pinMode(pin,OUTPUT);
  }
}

void runningLight( int speed, LedData& leds) {
  if (millis() - leds.timeStamp > speed) {
    leds.timeStamp = millis();
    digitalWrite(leds.startPin + leds.Num, HIGH); 
    digitalWrite(leds.startPin + leds.prevNum, LOW); 
    leds.prevNum = leds.Num;
    leds.Num -= leds.direction;
    if ((leds.Num == leds.maxNum -1) || (!leds.Num)) {
      leds.direction *= -1;
    }    
  }
}

void ledsOff(LedData& leds) {
  if (!leds.offReady) {
    Serial.println("Switch LEDs off");
    for ( int i = leds.startPin; i < leds.startPin + leds.maxNum; ++i) {
      digitalWrite(i, LOW);
    }
    leds.Num = 0;
    leds.prevNum = 1;
    leds.direction = -1;
    leds.offReady = true;
  }
}