#include "debouncer.h"

const uint16_t LED_OFF_TIME_DELAY_ms = 2000;  // milliseconds. For testing.
//const uint16_t LED_OFF_TIME_DELAY_ms = 30000;  // milliseconds.

struct ButtonLed
{
  Debouncer button;
  byte button_pin;
  byte led_pin;
};

const ButtonLed BUTTONS_LEDS[] = 
{
  { Debouncer(5, 50, LED_OFF_TIME_DELAY_ms), 5, 11 },
  { Debouncer(4, 50, LED_OFF_TIME_DELAY_ms), 4, 10 },
  { Debouncer(3, 50, LED_OFF_TIME_DELAY_ms), 3, 9 },
  { Debouncer(2, 50, LED_OFF_TIME_DELAY_ms), 2, 8 }
};

void setup()
{
  for (const auto& button_led : BUTTONS_LEDS)
  {
    pinMode(button_led.button_pin, INPUT_PULLUP);
    pinMode(button_led.led_pin, OUTPUT);
    digitalWrite(button_led.led_pin, LOW);
  }
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
	uint16_t timestamp = millis();

  //
  // TASK 1: Read the buttons and set their corresponding LEDs.
  //

  for (const auto& button_led : BUTTONS_LEDS)
  {
    button_led.button.Update();
    if (button_led.button.Fall())
    {
      digitalWrite(button_led.led_pin, HIGH);
    }
    else if (button_led.button.RepeatCount() == 1)
    {
      digitalWrite(button_led.led_pin, LOW);
    }
  }

  //
  // TASK 2: Blink the inbuilt LED.
  //

  const uint16_t LED_BLINK_INTERVAL = 500;
  static uint16_t led_blink_previous_timestamp = timestamp;
  static bool led_state = false;
  if (timestamp - led_blink_previous_timestamp >= LED_BLINK_INTERVAL)
  {
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    led_blink_previous_timestamp += LED_BLINK_INTERVAL;
  }
}