// https://lastminuteengineers.com/rotary-encoder-arduino-tutorial/

#include <Adafruit_NeoPixel.h>

#define NUMPIXELS 12
#define LEDPIN 2

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);

// Rotary Encoder Inputs
#define CLK 8
#define DT 9
#define SW 10

#define CLK2 5
#define DT2 4
#define SW2 3

int currentStateCLK;
int currentStateCLK2;
int lastStateCLK;
int lastStateCLK2;
String currentDir = "";
int btnState;
unsigned long lastButtonPress = 0;



#define HUE_STEP 1200
#define VAL_STEP 10

long hue = 0;        // 0-65535 https://adafruit.github.io/Adafruit_NeoPixel/html/class_adafruit___neo_pixel.html#a1f16aee5b96e16e62598f826e292b23b
int saturation = 0;  // 0-255
int value = 60;      // 0-255



void setup() {
  Serial.begin(115200);

  pinMode(CLK,INPUT);
  pinMode(DT,INPUT);
  pinMode(SW, INPUT_PULLUP);
  
  // Read the initial state of CLK
  lastStateCLK = digitalRead(CLK);
  
  pixels.begin(); // initialize NeoPixel library.
  pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS);
  pixels.show();

  Serial.println("PIXELS");
}

void loop() {
  currentStateCLK = digitalRead(CLK);
  currentStateCLK2 = digitalRead(CLK2);

  // If last and current state of CLK are different, then pulse occurred
  if (currentStateCLK != lastStateCLK  && currentStateCLK == 1) {
    btnState = digitalRead(SW);
    
    if (digitalRead(DT) != currentStateCLK) {
      currentDir ="CW";
      if (btnState == LOW) {
        hue += HUE_STEP;
        if (hue > 65535) {
          hue = 65535;
          saturation = 0;
        }
        else {
          saturation = 255;
        }
      }
      else {
        value += VAL_STEP;
        if (value > 255) {
          value = 255;
        }
      }
    } else {
      currentDir ="CCW";
      if (btnState == LOW) {
        hue -= HUE_STEP;
        if (hue < 0) {
          hue = 0;
          saturation = 0;
        }
        else {
          saturation = 255;
        }
      }
      else {
        value -= VAL_STEP;
        if (value < 30) {
          value = 0;
        }
      }
    }

    Serial.print("Direction: ");
    Serial.print(currentDir);
    Serial.print(" | Hue: ");
    Serial.print(hue);
    Serial.print(" | Sat: ");
    Serial.print(saturation);
    Serial.print(" | Val: ");
    Serial.println(value);
    
    pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS);
    pixels.show();
  }
  else if (currentStateCLK2 != lastStateCLK2  && currentStateCLK2 == 1) {
    btnState = digitalRead(SW2);
    
    if (digitalRead(DT2) != currentStateCLK2) {
      currentDir ="CW";
      if (btnState == LOW) {
        hue += HUE_STEP;
        if (hue > 65535) {
          hue = 65535;
          saturation = 0;
        }
        else {
          saturation = 255;
        }
      }
      else {
        value += VAL_STEP;
        if (value > 255) {
          value = 255;
        }
      }
    } else {
      currentDir ="CCW";
      if (btnState == LOW) {
        hue -= HUE_STEP;
        if (hue < 0) {
          hue = 0;
          saturation = 0;
        }
        else {
          saturation = 255;
        }
      }
      else {
        value -= VAL_STEP;
        if (value < 30) {
          value = 0;
        }
      }
    }
    
    Serial.print("Direction 2: ");
    Serial.print(currentDir);
    Serial.print(" | Button State: ");
    Serial.print(btnState);
    Serial.print(" | Hue: ");
    Serial.print(hue);
    Serial.print(" | Sat: ");
    Serial.print(saturation);
    Serial.print(" | Val: ");
    Serial.println(value);
    
    pixels.fill(pixels.gamma32(pixels.ColorHSV(hue, saturation, value)), 0, NUMPIXELS);
    pixels.show();
  }

  lastStateCLK = currentStateCLK;
  lastStateCLK2 = currentStateCLK2;

  // Put in a slight delay to help debounce the reading
  delay(1);
}
