#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RotaryEncoder.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1  // No reset pin

// Initialize OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Define rotary encoder pins
#define ROTARY_CLK 2
#define ROTARY_DT 3
#define ROTARY_SW 4

RotaryEncoder encoder(ROTARY_CLK, ROTARY_DT);

int menuIndex = 0;  // To track the current menu index
int lastMenuIndex = -1;  // To track changes
String menuItems[] = {"Option 1", "Option 2", "Option 3", "Exit"};  // Define menu items
int menuLength = sizeof(menuItems) / sizeof(menuItems[0]);

void setup() {
  // Initialize OLED display
  if (!display.begin(SSD1306_I2C_ADDRESS, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);  // Don't proceed if OLED fails
  }
  display.clearDisplay();
  display.display();

  // Initialize rotary encoder button
  pinMode(ROTARY_SW, INPUT_PULLUP);

  // Attach interrupts for the rotary encoder
  attachInterrupt(digitalPinToInterrupt(ROTARY_CLK), updateEncoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ROTARY_DT), updateEncoder, CHANGE);

  // Display initial menu
  displayMenu();
}

void loop() {
  // Check if the encoder's button is pressed
  if (digitalRead(ROTARY_SW) == LOW) {
    selectMenuItem();
    delay(500);  // Debounce delay
  }

  // Only update the display if the menu index has changed
  if (menuIndex != lastMenuIndex) {
    displayMenu();
    lastMenuIndex = menuIndex;
  }
}

// Function to update the rotary encoder
void updateEncoder() {
  encoder.tick();  // Update encoder position
  int newPos = encoder.getPosition();

  if (newPos > menuIndex) {
    menuIndex++;
    if (menuIndex >= menuLength) menuIndex = 0;  // Wrap around
  } else if (newPos < menuIndex) {
    menuIndex--;
    if (menuIndex < 0) menuIndex = menuLength - 1;  // Wrap around
  }

  encoder.setPosition(menuIndex);  // Reset position
}

// Function to display the menu
void displayMenu() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  for (int i = 0; i < menuLength; i++) {
    if (i == menuIndex) {
      display.setTextColor(BLACK, WHITE);  // Highlight the current item
    } else {
      display.setTextColor(WHITE);
    }
    display.setCursor(10, 10 + i * 10);
    display.println(menuItems[i]);
  }
  display.display();
}

// Function to handle menu selection
void selectMenuItem() {
  if (menuItems[menuIndex] == "Exit") {
    display.clearDisplay();
    display.setCursor(10, 30);
    display.setTextSize(2);
    display.println("Exiting...");
    display.display();
    delay(1000);
    // Implement the exit action
  } else {
    display.clearDisplay();
    display.setCursor(10, 30);
    display.setTextSize(2);
    display.println(menuItems[menuIndex]);
    display.display();
    delay(1000);
  }
}