#include <BfButton.h>
#include <LiquidCrystal.h>
#include "SimpleMenu.h"
bool inMenu = true;
int valueA, valueB, valueC, mainValue;
void function(){};
int btnPin=6; //GPIO #3-Push button on encoder
int DT=5; //GPIO #4-DT on encoder (Output B)
int CLK=4; //GPIO #5-CLK on encoder (Output A)
BfButton btn(BfButton::STANDALONE_DIGITAL, btnPin, true, LOW);
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
int counter = 0;
int angle = 0; 
int aState;
int aLastState;  
const int alphabetSize = 26;
char lowerCase[alphabetSize];
char upperCase[alphabetSize];
int cursorPos = 0;
int charPos = 0;

SimpleMenu MenuSub[3] = {
  SimpleMenu("Sensitivity",&mainValue),
  SimpleMenu("Char map",&function),
  SimpleMenu("Credits",MenuSub)
};

SimpleMenu Menu[3] = {
  SimpleMenu("Write mode",&writeMode),
  SimpleMenu("Settings",&valueB),
  SimpleMenu("Save to SD",&valueC)
};
SimpleMenu TopMenu(3,Menu);
enum StateType{
  UPCASE,
  LOWCASE,
  SPECIAL,
};

enum MenuModes{
  WRITE,
  SETTINGS,
  MENU,
};

void display(SimpleMenu *_menu)
{
  inMenu = true;
  lcd.clear();
  lcd.print(">");
  lcd.print(_menu->name);

  SimpleMenu *next = TopMenu.next();
  if(next != NULL)
  {
    lcd.setCursor(1,1);
    lcd.print(next->name);
  }

}

void displayValue(SimpleMenu *_menu)
{
 lcd.clear();
  lcd.print(_menu->name);
  lcd.setCursor(0,1);
  lcd.print(_menu->getValue());
}

StateType state = LOWCASE;
MenuModes Mode = MENU;
//Button press hanlding function
void pressHandler (BfButton *btn, BfButton::press_pattern_t pattern) {
  switch (pattern) {
    case BfButton::SINGLE_PRESS:
      Serial.println("Single push");
      cursorPos ++;
      if(inMenu == true){
        inMenu = false;
        lcd.clear();
        TopMenu.select();
        break;
      }
      break;
      
      
    case BfButton::DOUBLE_PRESS:
     Serial.println("Double push");
     if(state == LOWCASE){
       state = UPCASE;
     }
     else{
       state = LOWCASE;
     }
      break;
      
    case BfButton::LONG_PRESS:
      Serial.println("Long push");
      break;
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  lcd.begin(16, 2);
  pinMode(CLK,INPUT_PULLUP);
  pinMode(DT,INPUT_PULLUP);
  aLastState = digitalRead(CLK);
    
    for (int i = 0; i < alphabetSize; i++) {
        lowerCase[i] = 'a' + i;
    }
        for (int i = 0; i < alphabetSize; i++) {
        upperCase[i] = 'A' + i;
    }
 TopMenu.begin(display,displayValue);
  //Button settings
  btn.onPress(pressHandler)
  .onDoublePress(pressHandler) // default timeout
  .onPressFor(pressHandler, 1000); // custom timeout for 1 second
}

void writeMode(){
while(inMenu == false){  // put your main code here, to run repeatedly:
  //Wait for button press to execute commands
  btn.read();
  aState = digitalRead(CLK);
  //Encoder rotation tracking
if (aState != aLastState) {
  if (digitalRead(DT) != aState) {
    if (digitalRead(CLK) == LOW) { // Check the state of CLK to ensure a full step
      charPos++;
      if (charPos >= alphabetSize) {
        charPos = 0;
      }
    }
  } else {
    if (digitalRead(CLK) == LOW) { // Check the state of CLK to ensure a full step
      charPos--;
      if (charPos < 0) {
        charPos = alphabetSize - 1;
      }
    }
  }
     if (charPos < 0 ) {
       charPos = alphabetSize;
     }
  }   
   
  switch(state){
    case UPCASE:
      lcd.print(upperCase[charPos]);
      break;
    case LOWCASE:
      lcd.print(lowerCase[charPos]);
      break;
  }
  aLastState = aState;  
  lcd.setCursor(cursorPos, 0);
}
}

void menuMode(){
  while (inMenu == true) 
  {
    btn.read();  
    aState = digitalRead(CLK);
    if (aState != aLastState) {
  if (digitalRead(DT) != aState) {
    if (digitalRead(CLK) == LOW) { // Check the state of CLK to ensure a full step
      TopMenu.down();
    }
  } else {
    if (digitalRead(CLK) == LOW) { // Check the state of CLK to ensure a full step
      TopMenu.up();
    }
  }
  }  
     aLastState = aState;  
}
}

void loop() {
  switch(Mode){
    case WRITE:
      writeMode();
      break;
    case MENU:
      menuMode();
      break;
  }
}