#include "Ramp_Lights.h"
#include <Arduino.h>

static const char* tag = "ramp";

// TODO add tickSkip to instanciation
#define TickDelayCount 5

RAMP_LIGHT::RAMP_LIGHT(OneButton* button, PWM_Output* pwmOutput, int min, int max, float step)
    : button(button), pwmOutput(pwmOutput), min(min), max(max), step(step) {

    button->attachClick([](void* context) { static_cast<RAMP_LIGHT*>(context)->singleClick(); }, this);
    button->attachLongPressStart([](void* context) { static_cast<RAMP_LIGHT*>(context)->longPressStart(); }, this);
    button->attachLongPressStop([](void* context) { static_cast<RAMP_LIGHT*>(context)->longPressStop(); }, this);
    button->attachDuringLongPress([](void* context) { static_cast<RAMP_LIGHT*>(context)->duringLongPress(); }, this);

    if(min < 0.0) min = 0.0;
    if(max > 100.0) max = 100.0;
    currentValue = min;
    IsOn = false;
    rampState = RampingUp;
}

void RAMP_LIGHT::tick(){
    button->tick();
}

void RAMP_LIGHT::singleClick(){
    IsOn = ! IsOn;
    if(IsOn){
        pwmOutput->setOutput(currentValue);
        ESP_LOGD(tag, "Light On");
    }else{
        pwmOutput->setOutput(0.0);
        ESP_LOGD(tag, "Light Off");
    }
}

void RAMP_LIGHT::longPressStart(){
    tickCount = TickDelayCount;
    ESP_LOGD(tag, "ramp long press start");
}

void RAMP_LIGHT::longPressStop(){
    if(IsOn){
        rampState = (rampState == RampingUp) ? RampingDown : RampingUp;
    }
    ESP_LOGD(tag, "ramp long press stop");
}

// Ramping Logic
void RAMP_LIGHT::duringLongPress(){
    if(IsOn){
        if (tickCount > 0 && --tickCount == 0) {
            currentValue += (rampState == RampingUp) ? step : -step;
            currentValue = constrain(currentValue, min, max);
            pwmOutput->setOutput(currentValue);
            ESP_LOGD(tag, "duty: %f, sent val: %d, actual val: %d", currentValue, pwmOutput->currOutVal, pwmOutput->getOutVal());
            tickCount = TickDelayCount;
        }  
    }
}