/*
 * 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);

typedef struct {
  bool isDelta;
  uint16_t tile_count_x;
  uint16_t tile_count_y;
  uint16_t tile_count_w;
  uint16_t tile_count_h;
} section_t;

typedef struct oled_g
{
  section_t header;
  section_t alertLeftUp;
  section_t alertRightUp;
  section_t alertLeftDown;
  section_t alertRightDown;
  section_t mainSection;
}oled_g_t;

static oled_g_t oled_sections;

void oled_init_section(section_t *ptr, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
  ptr->tile_count_x = x;
  ptr->tile_count_y = y;
  ptr->tile_count_w = w;
  ptr->tile_count_h = h;
}

void oled_init_all_sections(void)
{
  // 1: 3 - 10 - 3
  oled_init_section(&oled_sections.alertLeftUp, 0, 0, 3, 1);
  oled_init_section(&oled_sections.header, 3, 0, 10, 1);
  oled_init_section(&oled_sections.alertRightUp, 13, 0, 3, 1);

  // 6: 16
  oled_init_section(&oled_sections.mainSection, 0, 1, 16, 6);

  // 1: 5 - 11
  oled_init_section(&oled_sections.alertLeftDown, 0, 7, 5, 1);
  oled_init_section(&oled_sections.alertRightDown, 5, 7, 11, 1);
}

void test_box(section_t *ptr, uint8_t inverted)
{
  uint16_t _area_x_pos = (uint16_t)ptr->tile_count_x*8;
  uint16_t _area_y_pos = (uint16_t)ptr->tile_count_y*8;
  uint16_t _area_width = (uint16_t)ptr->tile_count_w*8;
  uint16_t _area_height = (uint16_t)ptr->tile_count_h*8;

  sm_u8g2.clearBuffer();					// clear the internal memory
  sm_u8g2.setDrawColor(inverted);

  sm_u8g2.drawBox(_area_x_pos, _area_y_pos, _area_width, _area_height);

  Serial.printf("P %d %d %d %d \r\n", _area_x_pos, _area_y_pos, _area_width, _area_height);

  Serial.printf("T %d %d %d %d \r\n", ptr->tile_count_x, ptr->tile_count_y, ptr->tile_count_w, ptr->tile_count_h);

  // now only update the selected area, the rest of the display content is not changed
  sm_u8g2.updateDisplayArea(ptr->tile_count_x, ptr->tile_count_y, ptr->tile_count_w, ptr->tile_count_h);
}

void test_box_all(uint32_t delayCount)
{
  // Serial.println(oled_sections.alertLeftUp.tile_count_x);
  // Serial.println(oled_sections.alertLeftUp.tile_count_y);
  // Serial.println(oled_sections.alertLeftUp.tile_count_w);
  // Serial.println(oled_sections.alertLeftUp.tile_count_h);

  test_box(&oled_sections.alertLeftUp, 1);
  // delay(delayCount);

  // test_box(&oled_sections.header, 1);
  // delay(delayCount);
  
  // test_box(&oled_sections.alertRightUp, 1);
  // delay(delayCount);

  // // main
  // test_box(&oled_sections.mainSection, 1);
  // delay(delayCount);

  // // footer
  // test_box(&oled_sections.alertLeftDown, 1);
  // delay(delayCount);

  // test_box(&oled_sections.alertRightDown, 1);
  // delay(delayCount);
}

void page_one(void)
{
  sm_u8g2.clearBuffer();					// clear the internal memory
  sm_u8g2.setFont(u8g2_font_4x6_tr);
  sm_u8g2.setFontRefHeightExtendedText();
  sm_u8g2.setDrawColor(1);
  // sm_u8g2.setFontPosTop();
  sm_u8g2.setFontDirection(0);

  char buf[] = "00-00-0000 00:00 AM"; // 19 Char

  time_t now;
  struct tm timeinfo;
  time(&now);
  localtime_r(&now, &timeinfo);

  int8_t temp = timeinfo.tm_hour - 12;

  sprintf(buf, "%02d-%02d-%04d %02d:%02d %s",
      timeinfo.tm_mday,
      timeinfo.tm_mon+1,
      timeinfo.tm_year + 1900,
      (temp>0)?temp: timeinfo.tm_hour,
      timeinfo.tm_min, (temp >= 0)?"PM":"AM");

  Serial.printf("converted %s (hr=%d)\r\n", buf, timeinfo.tm_hour);
}

void sm_u8g2_loop(void) 
{
  test_box_all(3000);
}

void sm_u8g2_setup(void) 
{
  oled_init_all_sections();
}


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

void loop(void) {
  sm_u8g2_loop();
  delay(5000);
}

  // sm_u8g2.clearBuffer();					// clear the internal memory
  // sm_u8g2.setDrawColor(1);

  // sm_u8g2.drawBox(0, 16, 80, 8);

  // // now only update the selected area, the rest of the display content is not changed
  // sm_u8g2.updateDisplayArea(0, 2, 10, 1);
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
Loading
ssd1306