#include <ezButton.h>
#include <Arduino.h>
#include <U8g2lib.h>
#include <EEPROM.h> 

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif


U8G2_SSD1309_128X64_NONAME0_1_HW_I2C u8g2 (U8G2_R0, /* clock=/ A5, / data=/ A4, / reset=*/ U8X8_PIN_NONE);  //OLED kezelő

// Rotary Encoder Inputs
#define CLK 2
#define DT 3
#define BUTTON 4

byte menu_Mode;
byte battery_connected=0;
char *battTypeTxt[] = {"AGM", "Gel", "EFB", "Wet" };
byte battType;
byte battery_Capacity=72;
byte settings=0;
byte battTypeNum;
byte dataRow=1;
byte screen_Mode;
byte settingRow;
byte modifyData=0;
int lastState;
int currentState;
unsigned long pressedTime  = 0;
unsigned long releasedTime = 0;
const int SHORT_PRESS_TIME = 500; // 500 milliseconds

ezButton ez_Button(BUTTON);

int counter = 1;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";


void setup() {
  u8g2.begin();
  // Set encoder pins as inputs
  pinMode(CLK,INPUT);
  pinMode(DT,INPUT);
  pinMode(BUTTON,INPUT);
  
  // Setup Serial Monitor
  Serial.begin(115200);

  // Read the initial state of CLK
  lastStateCLK = digitalRead(CLK);
  
  // Call updateEncoder() when any high/low changed seen
  // on interrupt 0 (pin 2), or interrupt 1 (pin 3)
  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);

  pinMode(CLK,INPUT_PULLUP);
  pinMode(DT,INPUT_PULLUP);
  pinMode(BUTTON,INPUT_PULLUP);
  ez_Button.setDebounceTime(100); // set debounce time to 100 milliseconds

  EEPROM.get(3,battType);
  if (battType<0 || battType>3){battType=0; EEPROM.put(3,battType);}
  EEPROM.get(13, battery_Capacity);
  if (battery_Capacity<10 || battery_Capacity>100) {battery_Capacity=50;EEPROM.put(13,battery_Capacity);}  
}

void loop() {
  ez_Button.loop();
  OLED();

  if(settings==0 && ez_Button.isReleased()){
    Serial.println("The button is released");
    settings=1;
    while (digitalRead(BUTTON) == LOW) {}
    delay(100);
  }
    
  if(settings==1) {  settingsData();}
}

void settingsData(){

  if (modifyData==0){
    if (counter>=1 && counter<=3) dataRow=counter;
    if (counter>3) counter=3;
    if (counter<1) counter=1;

  currentState = digitalRead(BUTTON);
  if(lastState == HIGH && currentState == LOW)        // button is pressed
    pressedTime = millis();
  else if(lastState == LOW && currentState == HIGH) { // button is released
    releasedTime = millis();
    long pressDuration = releasedTime - pressedTime;

    if( pressDuration < SHORT_PRESS_TIME ){
      Serial.println("A short press is detected modifyData==0");
      modifyData=1;
      settingRow=dataRow;
      if(dataRow==1){ EEPROM.get(3,battType);
        counter=battType;}
      if(dataRow==2){ EEPROM.get(13,battery_Capacity);
        counter=battery_Capacity;}
      if(dataRow==2){ settings=0;}
    }
  }

  // save the the last state
  lastState = currentState;
    
  }

  if (modifyData==1){

   if (settingRow==1) {
    if (counter>=0 && counter<=3) battType=counter;
    if(counter>3) counter=3;
    if(counter<0) counter=0;


    currentState = digitalRead(BUTTON);
    if(lastState == HIGH && currentState == LOW)  {      // button is pressed
      pressedTime = millis();
    }
    else if(lastState == LOW && currentState == HIGH) { // button is released
    releasedTime = millis();

    long pressDuration = releasedTime - pressedTime;

    if( pressDuration < SHORT_PRESS_TIME ){
      Serial.println("A short press is detected");
      modifyData=0;
      if(dataRow==1) EEPROM.put(3,battType);
    }
    }

  }

    if (settingRow==2) {
    if (counter>=10 && counter<=100) battery_Capacity=counter;
    if(counter>100) counter=100;
    if(counter<10) counter=10;


    currentState = digitalRead(BUTTON);
    if(lastState == HIGH && currentState == LOW)  {      // button is pressed
      pressedTime = millis();
    }
    else if(lastState == LOW && currentState == HIGH) { // button is released
    releasedTime = millis();

    long pressDuration = releasedTime - pressedTime;

    if( pressDuration < SHORT_PRESS_TIME ){
      Serial.println("A short press is detected");
      modifyData=0;
      if(dataRow==1) EEPROM.put(3,battType);
    }
    }

  }

    lastState = currentState;
  }

}

void OLED(void) {
  u8g2.firstPage();
  do {
      menu_Mode=counter;

    if(settings==0 && menu_Mode==1){
      u8g2.setFont(u8g2_font_ncenB10_tr);
      if (battery_connected==0) u8g2.drawStr(8, 10, "Battery not connected");
      if (battery_connected==1) u8g2.drawStr(8, 10, "Battery connected");
    }

      if(settings==1){
//        u8g2.setFont(u8g2_font_ncenB10_tr);
//				u8g2.drawStr(8, 6, "Battery");
        u8g2.setFont(u8g2_font_8x13_mf);
        u8g2.drawStr(5, 15, "Type:");
          u8g2.setCursor(85, 15);
          u8g2.print( battTypeTxt[battType]);
        u8g2.drawStr(5, 35, "capacity.:");
          u8g2.setCursor(80, 35);
          u8g2.print( battery_Capacity);
          u8g2.drawStr(105, 35, "Ah");
        u8g2.drawStr(5, 55, "<- Back");
        if (dataRow==1) u8g2.drawFrame(2,0, 124, 20);
        if (dataRow==2) u8g2.drawFrame(2,20, 124, 20);     
        if (dataRow==3) u8g2.drawFrame(2,40, 124, 20);    
    }

        if(screen_Mode==3){
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.setCursor(35, 24);
    u8g2.print( counter);
    }

        if(screen_Mode==4){
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.setCursor(45, 24);
    u8g2.print( counter);
    }

  } while ( u8g2.nextPage() );
  //delay(1000);
}



void updateEncoder(){
  // Read the current state of CLK
  currentStateCLK = digitalRead(CLK);

  // If last and current state of CLK are different, then pulse occurred
  // React to only 1 state change to avoid double count
  if (currentStateCLK != lastStateCLK  && currentStateCLK == 1){

    // If the DT state is different than the CLK state then
    // the encoder is rotating CCW so decrement
    if (digitalRead(DT) != currentStateCLK) {
      counter --;
      currentDir ="CCW";
    } else {
      // Encoder is rotating CW so increment
      counter ++;
      currentDir ="CW";
    }
  }

  // Remember last CLK state
  lastStateCLK = currentStateCLK;
}