#include "input.h"

#define CLK_PIN 2
#define DT_PIN 3
#define SW_PIN 4

Encoder encoder(CLK_PIN, DT_PIN);
void setup_input() {
  pinMode(SW_PIN, INPUT_PULLUP);
}

#define KNOB_DIR -1
uint32_t read_knob() {
  uint32_t rotate = KNOB_DIR * encoder.read() / 4;
  if(rotate != 0) {
    encoder.write(0);
  }
  return rotate;
}

// button physical state
#define PRESSED 0
#define RELEASED 1
uint8_t pstate = RELEASED;
#define DEBOUNCE_CYCLES 3
uint8_t debounce;

uint8_t debounced_read() {
  byte read = digitalRead(SW_PIN);
  if (read != pstate && ++debounce >= DEBOUNCE_CYCLES) {
    pstate = read;
    debounce = 0;
  }
  return pstate;
}

// button logical state
#define DOWN 0
#define UP 1
#define LONGPRESS 2
uint8_t lstate = UP;

#define LONGPRESS_MS 500
uint32_t pressed_at;

uint8_t read_button() {
  uint8_t read = debounced_read();

  switch(lstate) {
    case UP:
      if(read == PRESSED) {
        lstate = DOWN;
        pressed_at = millis();
      }
      break;

    case DOWN:
      if(millis() - pressed_at >= LONGPRESS_MS) {
        lstate = LONGPRESS;
        return EVENT_HOLD;
      }
      if(read == RELEASED) {
        lstate = UP;
        return EVENT_CLICK;
      }
      break;

    case LONGPRESS:
      if(read == RELEASED) lstate = UP;
      break;
  }

  return EVENT_NONE;
}