#include "Buttons.h"
#include "Config.h"

void Button::begin() {
  pinMode(pin_, BUTTON_ACTIVE_LEVEL == LOW ? INPUT_PULLUP : INPUT_PULLDOWN);
  raw_ = stable_ = (digitalRead(pin_) == BUTTON_ACTIVE_LEVEL);
  changedAt_ = millis();
}

void Button::suppressUntilRelease() {
  suppressed_ = true;
  raw_ = stable_ = (digitalRead(pin_) == BUTTON_ACTIVE_LEVEL);
  changedAt_ = millis();
  longSent_ = true;
}

ButtonEvent Button::update(uint32_t now) {
  const bool sample = (digitalRead(pin_) == BUTTON_ACTIVE_LEVEL);
  if (suppressed_) {
    raw_ = stable_ = sample;
    changedAt_ = now;
    if (!sample) { suppressed_ = false; longSent_ = false; }
    return ButtonEvent::NONE;
  }
  if (sample != raw_) { raw_ = sample; changedAt_ = now; }
  if (raw_ != stable_ && now - changedAt_ >= BUTTON_DEBOUNCE_MS) {
    stable_ = raw_;
    if (stable_) {
      pressedAt_ = now; nextRepeat_ = now + BUTTON_LONG_PRESS_MS + BUTTON_REPEAT_DELAY_MS;
      longSent_ = false;
    } else if (!longSent_) return ButtonEvent::SHORT;
  }
  if (stable_ && !longSent_ && now - pressedAt_ >= BUTTON_LONG_PRESS_MS) {
    longSent_ = true; return ButtonEvent::LONG;
  }
  if (stable_ && longSent_ && now >= nextRepeat_) {
    nextRepeat_ += BUTTON_REPEAT_MS; return ButtonEvent::REPEAT;
  }
  return ButtonEvent::NONE;
}

