#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h> // library required for IIC communication
#include "AiEsp32RotaryEncoder.h"
#define ENC_PIN_BTN 16//
#define ENC_PIN_A   17//
#define ENC_PIN_B   18//
#define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
#define ROTARY_ENCODER_STEPS 4

#define   U8X8_HAVE_HW_I2C
uint8_t contrast = 255;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,U8X8_PIN_NONE);
const unsigned char test [] = "This is a test";

AiEsp32RotaryEncoder enc = AiEsp32RotaryEncoder(ENC_PIN_A, ENC_PIN_B, ENC_PIN_BTN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
  enum dispMode { DISP_LOGO,DISP_MAIN,DISP_MENU,DISP_INPUT, DISP_ADJ_VAL};
//  uint8_t d_mode = DISP_LOGO;
  uint8_t d_mode = DISP_ADJ_VAL;
  void IRAM_ATTR readEncoderISR(){enc.readEncoder_ISR();}

void setup(){
  // Encoder
    pinMode(ENC_PIN_A,INPUT_PULLUP);
    pinMode(ENC_PIN_B,INPUT_PULLUP);
    pinMode(ENC_PIN_BTN,INPUT_PULLUP);
    
    enc.begin();
    enc.setup(readEncoderISR);
    setEnc(0,10,true,1,0);
    setup_oled();
}
void loop(){
main_oled();
}


  void getEncoder(){
    if (enc.encoderChanged()) {contrast = map(enc.readEncoder(),0,10,1,255); u8g2.setContrast(contrast) ; Serial.print("Contrast "); Serial.println(contrast); }
    if (enc.isEncoderButtonClicked())  { Serial.println("Enc BTN pressed");  } // DO STUFF
  }
  void setEnc(long minVal, long maxVal, bool wrap, long accl, long newVal){  enc.setBoundaries(minVal, maxVal, wrap); enc.setAcceleration(accl); enc.setEncoderValue(newVal);}
  

void  setup_oled(){
  

  u8g2.begin();
  u8g2.setBusClock(400000L);
  u8g2.enableUTF8Print();
  u8g2.setContrast(contrast) ;
  u8g2.clearBuffer();
  u8g2.setColorIndex(1);

  u8g2.setDrawColor(1);
  //u8g2.sendBuffer();
  valueAdjust(0,1000,500,1,test);
}

 void main_oled(){


  u8g2.clearBuffer();
    switch(d_mode){
    //  case DISP_LOGO : show_logo(); break;
     // case DISP_MAIN : show_main(); break;
      case DISP_MENU : show_val_adj(); break;
      case DISP_INPUT: break;
      default: break;
    }
  u8g2.sendBuffer();
 }


 
/* General adjust value sreen
 prams:
  - Value description & unit ( as const char *)
  - value min/max
  - value current
 Features 
  - select decimal place
  - change decimal place
  - value wrap around
  - ok btn & cancel btn
*/


uint32_t adjBuffMin = 0;
uint32_t adjBuffMax = 0;
uint32_t adjBuffVal = 0;
uint32_t adjBuffStep = 0;
const unsigned char *   adjPtrTxt = NULL;
String   adjStr = "";
uint8_t adjStrLen = 0;
int8_t adjStrPos = 0;
bool selectPos = true;


void valueAdjust(uint32_t valMin,uint32_t valMax, uint32_t val, uint32_t valStep, const unsigned char * valPtrTxt){
  
  adjStr = String(val);
  adjStrLen = adjStr.length();
  adjStrPos = -1; // "back arrow" = -1  "value" =  0 to n  "ok checkmark" = n+1
  adjPtrTxt = valPtrTxt;
  setEnc(-1, adjStrLen+1, true, 1, adjStrPos);
  d_mode = DISP_ADJ_VAL;
  u8g2.setFont(u8g2_font_twelvedings_t_all); // 14x14
  u8g2.setFontPosCenter();
}


void show_val_adj(){

  u8g2.drawGlyph(17, 32, 85);// cancel
  u8g2.drawGlyph(100, 32, 47);// OK
  u8g2.drawStr(35,32,adjStr.c_str());
  // for( uint8_t n = 0; n < adjStr.length(); n++){
  // int xPos =  85 - ((adjStr.length() * 14) + ((adjStr.length()-1) * 2)) + (n*14) + ( (n>1) ? (n-1) * 2 : 0);
  // u8g2.drawGlyph(xPos, 32, adjStr.charAt(n));
  // }
  
 }
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
encoder1:CLK
encoder1:DT
encoder1:SW
encoder1:VCC
encoder1:GND
ssd1306:DATA
ssd1306:CLK
ssd1306:DC
ssd1306:RST
ssd1306:CS
ssd1306:3V3
ssd1306:VIN
ssd1306:GND