#include "button.h"

// Konstruktor
AtmButton::AtmButton(uint8_t buttonPin, uint8_t buttonLedPin) : pin(buttonPin), ledPin(buttonLedPin), pressed(false) {}

// Initialisierung des Pins & Interrupts
void AtmButton::begin() {
    pinMode(ledPin, OUTPUT);
    pinMode(pin, INPUT_PULLUP);
    ledOff();
    attachInterruptArg(digitalPinToInterrupt(pin), buttonIsrHandler, this, FALLING);
}

void IRAM_ATTR AtmButton::buttonIsrHandler(void* arg) {
    AtmButton* self = static_cast<AtmButton*>(arg);
    unsigned long current_ms = millis();
    if((false == self->pressed) && ((current_ms - self->last_pressed_ms) > self->DEBOUNCE_BUTTON_MS))
    {
      self->pressed = true;
      self->pressed_at_ms = current_ms;
      self->pressed_after_ms = current_ms - self->last_pressed_ms;
      self->last_pressed_ms = current_ms;
    }    
    self->pressed = true;
}

bool AtmButton::wasPressed() {
    if (pressed) {
        pressed = false;  // Reset des Status
        return true;
    }
    return false;
}

void AtmButton::ledOn() {
  digitalWrite(ledPin, LEDON);
  ledState = LEDON;
}

void AtmButton::ledOff() {
  digitalWrite(ledPin, LEDOFF);
  ledState = LEDOFF;
}

void AtmButton::ledToggle() {
  ledState = (LEDON == ledState) ? LEDOFF : LEDON;
  digitalWrite(ledPin, ledState);
}

bool AtmButton::iswaitingUntilPressed(unsigned long maxTimeToWaitMs, unsigned long blinkPeriodMs)
{
  /* will return as longs as waiting until the button is pressed */
  /* if blinkPeriodMs is 0 - there is no LED blinking */
  unsigned long currentMs = millis();

  if(false == activeWaiting)
  {
    activeWaiting = true;
    pressed = false;
    startWaitTime = currentMs;
    lastWaitLedToggle = currentMs;
    ledOn();
  }

  if( (true == pressed) || ((currentMs - startWaitTime) >= maxTimeToWaitMs))
  {
    ledOff();
    activeWaiting = false;
    return false;
  }

   
  if( (currentMs - lastWaitLedToggle) >= blinkPeriodMs )
  {
    lastWaitLedToggle = currentMs;
    ledToggle();
  }

  return true;  

}