/*
 * Very simple menu on an OLED display (with 8 lines of text).
 * Displays menu items from the array menu. Max. number of items is 7.
 * 
 * This sketch uses the library "U8g2", "Bounce2" and uses 3 buttons (up/down/select).
 * 
 */

#include <U8g2lib.h>

//U8G2_SSD1306_128X64_NONAME_1_HW_I2C sm_u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SSD1306_128X64_NONAME_F_HW_I2C sm_u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);


#define SCREEN_W  128
#define SCREEN_H  64
#define HEADER_H  8
#define FOOTER_H  8

void u8g2_prepare(void) {
  sm_u8g2.setFont(u8g2_font_6x10_tf);
  sm_u8g2.setFontRefHeightExtendedText();
  sm_u8g2.setDrawColor(1);
  sm_u8g2.setFontPosTop();
  sm_u8g2.setFontDirection(0);
}

void u8g2_page(void) {
  uint8_t x = 0;
  uint8_t y = 0;
  uint8_t w = SCREEN_W-1;
  uint8_t h = HEADER_H-1;
  // Header
  sm_u8g2.drawFrame(x, y, w, h);

  y += HEADER_H; // last hight
  h = (SCREEN_H - (HEADER_H + FOOTER_H) );
  sm_u8g2.drawFrame(x, y, w, h);

  y += h; // last hight
  h = (SCREEN_H - FOOTER_H );
  sm_u8g2.drawFrame(x, y, w, h);
}

void u8g2_string(uint8_t a) {
  sm_u8g2.setFontDirection(0);
  sm_u8g2.drawStr(30+a,31, " 0");
  sm_u8g2.setFontDirection(1);
  sm_u8g2.drawStr(30,31+a, " 90");
  sm_u8g2.setFontDirection(2);
  sm_u8g2.drawStr(30-a,31, " 180");
  sm_u8g2.setFontDirection(3);
  sm_u8g2.drawStr(30,31-a, " 270");
}

void u8g2_line(uint8_t a) {
  sm_u8g2.drawStr( 0, 0, "drawLine");
  sm_u8g2.drawLine(7+a, 10, 40, 55);
  sm_u8g2.drawLine(7+a*2, 10, 60, 55);
  sm_u8g2.drawLine(7+a*3, 10, 80, 55);
  sm_u8g2.drawLine(7+a*4, 10, 100, 55);
}

void u8g2_ascii_1() {
  char s[2] = " ";
  uint8_t x, y;
  sm_u8g2.drawStr( 0, 0, "ASCII page 1");
  for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ ) {
      s[0] = y*16 + x + 32;
      sm_u8g2.drawStr(x*7, y*10+10, s);
    }
  }
}

void u8g2_ascii_2() {
  char s[2] = " ";
  uint8_t x, y;
  sm_u8g2.drawStr( 0, 0, "ASCII page 2");
  for( y = 0; y < 6; y++ ) {
    for( x = 0; x < 16; x++ ) {
      s[0] = y*16 + x + 160;
      sm_u8g2.drawStr(x*7, y*10+10, s);
    }
  }
}

int16_t offset;				// current offset for the scrolling text
u8g2_uint_t width;			// pixel width of the scrolling text (must be lesser than 128 unless U8G2_16BIT is defined

const uint8_t tile_area_x_pos = 2;	// Update area left position (in tiles)
const uint8_t tile_area_y_pos = 3;	// Update area upper position (distance from top in tiles)
const uint8_t tile_area_width = 12;
const uint8_t tile_area_height = 3;	// this will allow cour18 chars to fit into the area

const u8g2_uint_t pixel_area_x_pos = tile_area_x_pos*8;
const u8g2_uint_t pixel_area_y_pos = tile_area_y_pos*8;
const u8g2_uint_t pixel_area_width = tile_area_width*8;
const u8g2_uint_t pixel_area_height = tile_area_height*8;

const uint8_t h_area_x_pos = 0;	// Update area left position (in tiles)
const uint8_t h_area_y_pos = 0;	// Update area upper position (distance from top in tiles)
const uint8_t h_area_width = 16;
const uint8_t h_area_height = 1;	// this will allow cour18 chars to fit into the area

const u8g2_uint_t XX = h_area_x_pos*8;
const u8g2_uint_t YY = h_area_y_pos*8;
const u8g2_uint_t WW = h_area_width*8;
const u8g2_uint_t HH = h_area_height*8;

void u8g2_page2(void) {
  sm_u8g2.clearBuffer();					// clear the internal memory
  sm_u8g2.setFont(u8g2_font_helvR10_tr);	// choose a suitable font
  sm_u8g2.drawStr(0,12,"UpdateDisplayArea");	// write something to the internal memory

  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  sm_u8g2.drawBox(pixel_area_x_pos-1, pixel_area_y_pos-1, pixel_area_width+2, pixel_area_height+2);

  // now only update the selected area, the rest of the display content is not changed
  sm_u8g2.updateDisplayArea(tile_area_x_pos, tile_area_y_pos, tile_area_width, tile_area_height);
}

void u8g2_page3() {
  sm_u8g2.clearBuffer();					// clear the internal memory

  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  sm_u8g2.drawBox(pixel_area_x_pos+offset, pixel_area_y_pos-1, pixel_area_width+2, pixel_area_height+2);
  
  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  //sm_u8g2.drawBox(pixel_area_x_pos-1, pixel_area_y_pos-1, pixel_area_width+2, pixel_area_height+2);

  // now only update the selected area, the rest of the display content is not changed
  sm_u8g2.updateDisplayArea(tile_area_x_pos, tile_area_y_pos, tile_area_width, tile_area_height);

  offset--;								// scroll by one pixel
  if ( offset == 0 )	
    offset = pixel_area_width;			// start over again
}

void u8g2_page_header(void)
{  
  sm_u8g2.clearBuffer();					// clear the internal memory

  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  sm_u8g2.drawBox(XX, YY, WW, HH);
  
  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  //sm_u8g2.drawBox(pixel_area_x_pos-1, pixel_area_y_pos-1, pixel_area_width+2, pixel_area_height+2);

  // now only update the selected area, the rest of the display content is not changed
  sm_u8g2.updateDisplayArea(h_area_x_pos, h_area_y_pos, h_area_width, h_area_height);
}

const char *text = "U8g2";	// scroll this text from right to left

void page_one(void)
{
  sm_u8g2.clearBuffer();					// clear the internal memory
  sm_u8g2.setFont(u8g2_font_4x6_tr);	// choose a suitable font
  sm_u8g2.drawStr(0,12,"00-00-0000");	// write something to the internal memory
  
  // draw a frame, only the content within the frame will be updated
  // the frame is never drawn again, but will stay on the display
  // sm_u8g2.drawBox(pixel_area_x_pos-1, pixel_area_y_pos-1, pixel_area_width+2, pixel_area_height+2);
  
  sm_u8g2.sendBuffer();					// transfer internal memory to the display
  
  sm_u8g2.setFont(u8g2_font_6x10_tf);	// set the target font for the text width calculation
  width = sm_u8g2.getUTF8Width(text);		// calculate the pixel width of the text
  offset = width+pixel_area_width;
}

void page_two(void)
{
  sm_u8g2.clearBuffer();						// clear the complete internal memory

  // draw the scrolling text at current offset
  sm_u8g2.setFont(u8g2_font_6x10_tf);		// set the target font
  sm_u8g2.drawUTF8(
    pixel_area_x_pos-width+offset, 
    pixel_area_y_pos+pixel_area_height+sm_u8g2.getDescent()-1, 
    text);								// draw the scolling text
  
  // now only update the selected area, the rest of the display content is not changed
  sm_u8g2.updateDisplayArea(tile_area_x_pos, tile_area_y_pos, tile_area_width, tile_area_height);
      
  offset--;								// scroll by one pixel
  if ( offset == 0 )	
    offset = width+pixel_area_width;			// start over again
}
uint8_t draw_state = 1;

void draw(void) {
  
  switch(draw_state) {
    case 1:
      u8g2_prepare();
      u8g2_page(); 
      break;

    case 2:
      u8g2_prepare(); 
      u8g2_page2(); 
      break;
    // case 7: u8g2_ascii_1(); break;
    // case 8: u8g2_ascii_2(); break;
  }
}

void setup() {
  Serial.begin(9600);
  
  sm_u8g2.begin();
  sm_u8g2.setPowerSave(0);

  // u8g2_prepare();
  // u8g2_page2();

  // u8g2_page_header();

  page_one();

  delay(5000);

  //u8g2_page3();
}

void loop(void) {
  // picture loop  
  // sm_u8g2.firstPage();  
  // do {
  //   draw();
  // } while( sm_u8g2.nextPage() );

  // draw_state++;

  // delay between each page

  //u8g2_page3();

  page_two();


  delay(250);
}
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
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA