#include <Wire.h>
#include <U8g2lib.h>
#include <ESP32Encoder.h>

// Define the pins for the rotary encoder switch and button
#define encCLK 18
#define encDT 19
#define encSW 15

//instead of changing here, rather change numbers above
//ESP32Encoder encoder = ESP32Encoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
ESP32Encoder encoder;

// Define the menu options as an array of strings
const char* menuOptions[] = {"Option 1", "Option 2", "Option 3"};

// Set the initial menu selection to the first option
int menuSelection = 0;

// Initialize the ESP32Encoder library for the rotary encoder

long encPos = 0;

// Initialize the OLED display library
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// 'wrktime', 128x64px
const unsigned char epd_bitmap_wrktime [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x01, 0xf8, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xe0, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x03, 0xc0, 0x30, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x07, 0x80, 0x78, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x07, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0f, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x60, 0x00, 0x30, 0xc7, 0x3c, 0x0c, 0x1e, 0x03, 0xff, 0xe1, 0x80, 0x08, 0xf0, 0x78, 0x01, 0xf0, 
  0xf0, 0x70, 0x79, 0xef, 0xbc, 0x1e, 0x1e, 0x03, 0xff, 0xe3, 0x80, 0x1f, 0xf9, 0xfc, 0x07, 0xf8, 
  0xf0, 0x70, 0x79, 0xff, 0xbc, 0x3e, 0x1e, 0x03, 0xff, 0xe3, 0xc0, 0x3f, 0xfd, 0xfe, 0x0f, 0xfc, 
  0x78, 0x70, 0xf1, 0xff, 0x3c, 0x7c, 0x1c, 0x03, 0xff, 0xe3, 0xc0, 0x3f, 0xff, 0xff, 0x0f, 0x1e, 
  0x78, 0xf8, 0xf1, 0xf8, 0x3c, 0xf8, 0x1c, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x1f, 0x0f, 0x1e, 0x0e, 
  0x78, 0xf8, 0xf1, 0xf0, 0x3f, 0xf0, 0x1c, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x1f, 0x0f, 0x1e, 0x0f, 
  0x3c, 0xf9, 0xe1, 0xe0, 0x3f, 0xe0, 0x00, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x0e, 0x0f, 0x1f, 0xff, 
  0x3c, 0xf9, 0xe1, 0xe0, 0x3f, 0xf0, 0x00, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x0e, 0x0f, 0x1f, 0xfe, 
  0x1f, 0xff, 0xc1, 0xe0, 0x3f, 0xf0, 0x00, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x0e, 0x0f, 0x1f, 0xfe, 
  0x1f, 0xdf, 0xc1, 0xe0, 0x3f, 0x78, 0x00, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x0e, 0x0f, 0x1e, 0x00, 
  0x1f, 0xdf, 0xc1, 0xe0, 0x3e, 0x3c, 0x00, 0x00, 0x78, 0x03, 0xc0, 0x3e, 0x0e, 0x0f, 0x1e, 0x00, 
  0x0f, 0x8f, 0x81, 0xe0, 0x3c, 0x3e, 0x00, 0x00, 0x78, 0x03, 0xc6, 0x3e, 0x0e, 0x0f, 0x1f, 0x06, 
  0x0f, 0x8f, 0x81, 0xe0, 0x3c, 0x1f, 0x00, 0x00, 0x78, 0x03, 0xcf, 0x3e, 0x0e, 0x0f, 0x0f, 0xfe, 
  0x0f, 0x0f, 0x81, 0xe0, 0x3c, 0x0f, 0x00, 0x00, 0x78, 0x03, 0xcf, 0x3e, 0x0e, 0x0f, 0x0f, 0xfe, 
  0x07, 0x07, 0x01, 0xe0, 0x1c, 0x0e, 0x00, 0x00, 0x70, 0x03, 0x87, 0x1c, 0x0e, 0x07, 0x03, 0xfc, 
  0x07, 0x07, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x30, 0x01, 0x06, 0x08, 0x04, 0x02, 0x01, 0xf8, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 1040)
const int epd_bitmap_allArray_LEN = 1;
const unsigned char* epd_bitmap_allArray[1] = {
  epd_bitmap_wrktime
};

void showLogo() {
    u8g2.firstPage();
    do{
      u8g2.drawBitmap(0, 0, 128/8, 64, epd_bitmap_wrktime);
    } while ( u8g2.nextPage() );
    delay(1000);
}

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

  // Initialize the rotary encoder pins as inputs with pullups
  pinMode(encCLK, INPUT_PULLUP);
  pinMode(encDT, INPUT_PULLUP);
  pinMode(encSW, INPUT_PULLUP);

  // Initialize the ESP32Encoder library with the rotary encoder pins
  encoder.attachHalfQuad(encDT, encCLK);
  encoder.setCount(0);

  // Initialize the OLED display
  u8g2.begin();
  showLogo();
  u8g2.setFont(u8g2_font_6x10_tf);
}

void loop() {
  // Read the current position of the rotary encoder
  long newPos = encoder.getCount();
  if (newPos != encPos) {
    Serial.println(newPos);
    // Determine the direction of rotation based on the change in the encoder position
    int direction = (newPos - encPos > 0) ? 1 : -1;
    // Update the menu selection based on the direction of rotation
    menuSelection = (menuSelection + direction + sizeof(menuOptions) / sizeof(menuOptions[0])) % sizeof(menuOptions) / sizeof(menuOptions[0]);

    // Save the current encoder position for the next iteration
    encPos = newPos;
  }

  // Draw the menu on the OLED display
  u8g2.clearBuffer();
  for (int i = 0; i < sizeof(menuOptions) / sizeof(menuOptions[0]); i++) {
    if (i == menuSelection) {
      u8g2.drawBox(0, i * 10, 128, 10);
      u8g2.setDrawColor(0);
    } else {
      u8g2.setDrawColor(1);
    }
    u8g2.setCursor(0, i * 10 + 10);
    u8g2.print(menuOptions[i]);
  }
  u8g2.sendBuffer();

  // Check if the button on the rotary encoder has been pressed
  if (digitalRead(encSW) == LOW) {
    // Display the clock timer for 5 seconds
    u8g2.clearBuffer();
    u8g2.setCursor(0, 10);
    u8g2.print("00:00:00");
    u8g2.sendBuffer();
    delay(2000);
    // Reset the menu selection to the first option
    //menuSelection = 0;
  }
}