#define encoderSwitch 10
#define encoderDT 9
#define encoderCLK 8
#define outputPin2 2
#define outputPin3 3

int counter = 0;
int currentStateCLK;
int lastStateCLK;
int currentStateSW;
int lastStateSW;
int lastCounter = -1; // Initialize to a value that will not match the initial counter value
bool lastOutput2State = LOW;
bool lastOutput3State = LOW;
unsigned long previousMillis = 0; // Stores the last time output 3 was updated
const int pulseDuration = 500; // Duration for which output 3 stays on in milliseconds
bool pulseState = LOW;

void setup() {
  // Set encoder pins as inputs
  pinMode(encoderSwitch, INPUT_PULLUP);
  pinMode(encoderDT, INPUT);
  pinMode(encoderCLK, INPUT);
  
  // Set output pins as outputs
  pinMode(outputPin2, OUTPUT);
  pinMode(outputPin3, OUTPUT);
  
  // Setup Serial Monitor
  Serial.begin(9600);
  
  // Read the initial state of CLK
  lastStateCLK = digitalRead(encoderCLK);
}

void loop() {
  // Read the current state of CLK
  currentStateCLK = digitalRead(encoderCLK);
  
  // If the last and current state of CLK are different, then a pulse occurred
  if (currentStateCLK != lastStateCLK && currentStateCLK == LOW) {
    // If the DT state is different than the CLK state then
    // the encoder is rotating clockwise
    if (digitalRead(encoderDT) == currentStateCLK) {
      if (counter > 0) {
        counter--;
      }
    } else {
      // Encoder is rotating counterclockwise
      if (counter < 9) {
        counter++;
      }
    }
  }
  
  // Remember the last CLK state
  lastStateCLK = currentStateCLK;

  // Read the current state of the switch
  currentStateSW = digitalRead(encoderSwitch);
  
  // If the switch state is LOW (pressed), print a message
  if (currentStateSW == LOW && lastStateSW == HIGH) {
    Serial.println("Switch pressed!");
  }
  
  // Remember the last switch state
  lastStateSW = currentStateSW;
  
  // Control outputs based on counter value and print their state if there's a change
  bool output2State = (counter == 8);
  bool output3State = (counter == 7);

  if (output2State != lastOutput2State || output3State != lastOutput3State || counter != lastCounter) {
    digitalWrite(outputPin2, output2State);
    digitalWrite(outputPin3, output3State);
    
    Serial.print("Counter: ");
    Serial.print(counter);
    Serial.print(" - Output 2: ");
    Serial.print(output2State ? "ON" : "OFF");
    Serial.print(", Output 3: ");
    Serial.println(output3State ? "ON" : "OFF");

    lastOutput2State = output2State;
    lastOutput3State = output3State;
    lastCounter = counter;
  }

  // Handle pulsing output 3 when the counter is between 1 and 6
  if (counter >= 1 && counter <= 6) {
    unsigned long currentMillis = millis();
    unsigned long interval = (7 - counter) * 1500;

    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      // Toggle the pulse state
      pulseState = !pulseState;

      if (pulseState) {
        digitalWrite(outputPin3,  HIGH);
        Serial.print("Counter: ");
        Serial.print(counter);
        Serial.println(" - Output 3: PULSE ON");
        delay (500);
        digitalWrite(outputPin3,  LOW);
//        Serial.print("Counter: ");
//        Serial.print(counter);
//        Serial.println(" - Output 3: PULSE OFF");
      }
    }
  } else {
    // Ensure output 3 is off when the counter is not between 1 and 6
    digitalWrite(outputPin3, LOW);
    pulseState = LOW;
  }
  
  // Add a small delay to debounce the encoder
  delay(5);
}
