#include "FastLED.h"

#define PIN_SENSOR A3

#define LED_TYPE WS2811
#define COLOR_ORDER RGB
#define MASTER_BRIGHTNESS 25
#define LED_PIN 11
#define LEDS_NUM 86
CRGB leds[LEDS_NUM];

static uint8_t hue;
long currentTime = 0;
long statusTime = 0;

bool lastStatus = false;
bool sensorStatus = false;
bool status = false;

long times[10];
int time = 0;
int numberOfReadings = 0;

static long onTime = 0;
static long offTime = 0;
long ledStatusTime = 0;
bool ledStatus = false;

void setup()
{
  delay(500); //power up delay

  pinMode(LED_PIN, OUTPUT);
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, LEDS_NUM);
  FastLED.setBrightness(MASTER_BRIGHTNESS);
  FastLED.clear();

  pinMode(PIN_SENSOR, INPUT);

//  Serial.begin(115200);
}

void loop()
{
  lastStatus = status;

  // Prüfe ob Taster gedrückt
  if (analogRead(PIN_SENSOR) > 100)
  {
    sensorStatus = true;
  }
  else
  {
    sensorStatus = false;
  }

  // Entprellen: Wechsel nur, wennn aktueller Status sich in 20ms nicht geändert hat
  if (sensorStatus == status)
  {
    statusTime = millis();
  }

  // If timeout, then calculate average times
  if (millis() - currentTime > 2000)
  {
    if (numberOfReadings >= 3)
    {
      onTime = 0;
      offTime = 0;
      for (int i = 0; i < time; i = i + 2)
      {
        offTime = offTime + times[i];
      }
      offTime = offTime / ((time + 1) / 2);

      for (int i = 1; i < time; i = i + 2)
      {
        onTime = onTime + times[i];
      }
      onTime = onTime / ((time + 1) / 2);
    }

    // Reset array, index of array, and status
    time = 0;
    status = false;
    currentTime = millis();
    numberOfReadings = 0;
    statusTime = millis();

  }
  else
  {
    if (millis() - statusTime > 20)
    {
      status = sensorStatus;
      statusTime = millis();
    }

    if (lastStatus != status)
    {
      // Store times in array
      times[time] = millis() - currentTime;

      numberOfReadings++;
      time++;
      if (time > 9)
      {
        time = 0;
      }
      currentTime = millis();
    }
  }

  // Calculate status of LED depending on time
  if (onTime > 0 && offTime > 0)
  {
    if (ledStatus)
    {
      // LED is currently on. If LED was on long enough, switch status to off
      if (millis() - ledStatusTime > onTime)
      {
        ledStatus = false;
        ledStatusTime = millis();
      }
    }
    else
    {
      if (millis() - ledStatusTime > offTime)
      {
        ledStatus = true;
        ledStatusTime = millis();
      }
    }
  }
  // Blink LED stripe
  if (ledStatus)
  {
    fill_solid(leds, LEDS_NUM, CHSV(255, 0, 200));
  }

  EVERY_N_MILLISECONDS(15)
  {
    if (!ledStatus)
    {
      fill_rainbow(leds, LEDS_NUM, hue, 5);
    }

    hue=hue+2;
  }

  FastLED.show();
}
