#include <SD.h>
#include <TMRpcm.h>
#include <SPI.h>

#include "button.h"
#include "debounce.h"

using MainButton = Button<150, 150>;

#define SD_ChipSelectPin A0
#define MainButtonPin A3
#define CoffeeLedPin A2
#define EegLedPin A1

Debounce<20> debounce;
MainButton button;

TMRpcm tmrpcm;   // create an object for use in this sketch

unsigned long time = 0;

void setup(){
    tmrpcm.speakerPin = 9;

    Serial.begin(9600);
    Serial.println("Startshduhsd");

    if (!SD.begin(SD_ChipSelectPin)) {  // see if the card is present and can be initialized:
        Serial.println("SD fail");
    } else{
        Serial.println("SD ok");
    }

    pinMode(MainButtonPin, INPUT);
    pinMode(CoffeeLedPin, OUTPUT);
    pinMode(EegLedPin, OUTPUT);

    digitalWrite(CoffeeLedPin, HIGH);

    tmrpcm.volume(2);
}

enum class State : uint8_t {
    Idle,
    MakingCoffee,
    Slowing
};

auto state = State::Idle;
uint16_t coffeeLedTimeout = millis();
uint16_t eegLedTimeout = millis();

const uint16_t minEegLedDelay = 50;
const uint16_t maxEegLedDelay = 500;
uint16_t eegLedDelay = maxEegLedDelay;
uint16_t eegLedDelayTimeout = millis();

void loop() {
    bool buttonPressed = digitalRead(MainButtonPin);
    auto event = button.event(debounce.event(buttonPressed));

    if((uint16_t) millis() - eegLedTimeout >= eegLedDelay) {
        eegLedTimeout = millis();
        digitalWrite(EegLedPin, !digitalRead(EegLedPin));
    }

    switch(state) {
        case State::Idle:
            if(event == ButtonEvent::Press || event == ButtonEvent::LongPress) {
                tmrpcm.play("coffee.wav");
                state = State::MakingCoffee;
                coffeeLedTimeout = millis();
            }
            break;
        case State::MakingCoffee:
            if(!tmrpcm.isPlaying()) {
                state = State::Slowing;
                eegLedDelay = minEegLedDelay;
                digitalWrite(CoffeeLedPin, HIGH);
            } else {
                if((uint16_t) millis() - coffeeLedTimeout >= 500) {
                    coffeeLedTimeout = millis();
                    digitalWrite(CoffeeLedPin, !digitalRead(CoffeeLedPin));
                }
            }
            break;
        case State::Slowing:
            if(event == ButtonEvent::Press || event == ButtonEvent::LongPress) {
                tmrpcm.play("coffee.wav");
                state = State::MakingCoffee;
                coffeeLedTimeout = millis();
            }

            if((uint16_t) millis() - eegLedDelayTimeout >= 300) {
                eegLedDelayTimeout = millis();
                if(eegLedDelay > maxEegLedDelay) {
                    eegLedDelay = maxEegLedDelay;
                    state = State::Idle;
                } else {
                    eegLedDelay = eegLedDelay * 1.1;
                }
            }
            break;
    }
}
