void lcd_normal_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = -1;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

  uint8_t selIndex =constrain(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM, 0, entryCount-1);
  uint8_t drawOffset;

  lcd_lib_clear();

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
    drawOffset = (49-12*entryCount)/2+1;
    for(int8_t n=0; n<entryCount; n++)
    {
      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';

      if (n == selIndex) {
        lcd_lib_draw_string(54-6, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(54+6, drawOffset+12*n, ptr+2);
      }
    }
    lcd_lib_draw_hline(0, 127, 53-3);

    break;
  case LANGUAGE_ENGLISH:
    drawOffset = (52-13*entryCount)/2+3;
    for(int8_t n=0; n<entryCount; n++)
    {
      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex) {
        lcd_lib_draw_string(54, drawOffset+13*n, ptr);
      }else{
        lcd_lib_draw_string(60, drawOffset+13*n, ptr+1);
      }
    }
    lcd_lib_draw_hline(0, 127, 53);
    break;
  default:
    break;
  }

  entryDetailsCallback(selIndex);
}
void lcd_scroll_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
    if (lcd_lib_button_pressed)
		return;//Selection possibly changed the menu, so do not update it this cycle.

    if (lcd_lib_encoder_pos == ENCODER_NO_SELECTION)
        lcd_lib_encoder_pos = 0;

	static int16_t viewPos = 0;
	if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos += entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;
	if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos -= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

    uint8_t selIndex = uint16_t(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM);

    lcd_lib_clear();

    int16_t targetViewPos = selIndex * 8 - 15;

    int16_t viewDiff = targetViewPos - viewPos;
    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos ++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos --; led_glow = led_glow_dir = 0; }

    uint8_t drawOffset = 10 - (uint16_t(viewPos) % 8);
    uint8_t itemOffset = uint16_t(viewPos) / 8;
    for(uint8_t n=0; n<6; n++)
    {
        uint8_t itemIdx = n + itemOffset;
        if (itemIdx >= entryCount)
            continue;

        char* ptr = entryNameCallback(itemIdx);
		//ptr[10] = '\0';
		ptr[20] = '\0';
        if (itemIdx == selIndex)
        {
            //lcd_lib_set(3, drawOffset+8*n-1, 62, drawOffset+8*n+7);
            lcd_lib_set(3, drawOffset+8*n-1, 124, drawOffset+8*n+7);
            lcd_lib_clear_string(4, drawOffset+8*n, ptr);
        }else{
            lcd_lib_draw_string(4, drawOffset+8*n, ptr);
        }
    }
    lcd_lib_set(3, 0, 124, 8);
    lcd_lib_clear(3, 47, 124, 63);
    lcd_lib_clear(3, 9, 124, 9);

    lcd_lib_draw_hline(3, 124, 48);

    lcd_lib_clear_string_centerP(1, menuNameP);
    
	entryDetailsCallback(selIndex);
	
    lcd_lib_update_screen();
}
void lcd_tripple_menu(const char* left, const char* right, const char* bottom)
{
    if (lcd_lib_encoder_pos != ENCODER_NO_SELECTION)
    {
        if (lcd_lib_encoder_pos < 0)
            lcd_lib_encoder_pos += 3*ENCODER_TICKS_PER_MAIN_MENU_ITEM;
        if (lcd_lib_encoder_pos >= 3*ENCODER_TICKS_PER_MAIN_MENU_ITEM)
            lcd_lib_encoder_pos -= 3*ENCODER_TICKS_PER_MAIN_MENU_ITEM;
    }

    lcd_lib_clear();
    lcd_lib_draw_vline(64, 5, 45);
    lcd_lib_draw_hline(3, 124, 48);

    if (IS_SELECTED_MAIN(0))
    {
        lcd_lib_draw_box(3+2, 5+2, 64-3-2, 45-2);
        lcd_lib_set(3+3, 5+3, 64-3-3, 45-3);
        lcd_lib_clear_string_center_atP(33, 22, left);
    }else{
        lcd_lib_draw_string_center_atP(33, 22, left);
    }

    if (IS_SELECTED_MAIN(1))
    {
        lcd_lib_draw_box(64+3+2, 5+2, 125-2, 45-2);
        lcd_lib_set(64+3+3, 5+3, 125-3, 45-3);
        lcd_lib_clear_string_center_atP(64 + 33, 22, right);
    }else{
        lcd_lib_draw_string_center_atP(64 + 33, 22, right);
    }

    if (bottom != NULL)
    {
        if (IS_SELECTED_MAIN(2))
        {
            lcd_lib_draw_box(3+2, 49+2, 125-2, 63-2);
            lcd_lib_set(3+3, 49+3, 125-3, 63-3);
            lcd_lib_clear_string_centerP(53, bottom);
        }else{
            lcd_lib_draw_string_centerP(53, bottom);
        }
    }
}
void lcd_basic_screen()
{
    lcd_lib_clear();
    lcd_lib_draw_hline(3, 124, 48);
}
void lcd_advance_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{

  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = -1;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM;

  uint8_t selIndex =constrain(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM, 0, entryCount-1);

  uint8_t drawOffset;

  lcd_lib_clear();

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
    drawOffset = (49-12*entryCount)/2+1;

    for(int8_t n=0; n<entryCount; n++)
    {

      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex)
      {
        lcd_lib_draw_string(4, drawOffset+12*n, CHINESE_POINT);
        lcd_lib_draw_string(16, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(16, drawOffset+12*n, ptr);
      }
    }
    if (menuNameP != NULL) {
      lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 10 + 3);
      lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
    }
    lcd_lib_draw_hline(0, 127, 53 - 3);

    break;
  case LANGUAGE_ENGLISH:
    drawOffset = (40-10*entryCount)/2+13;
    for(int8_t n=0; n<entryCount; n++)
    {

      char* ptr = entryNameCallback(n);
      ptr[20] = '\0';
      if (n == selIndex)
      {
        lcd_lib_draw_string(4, drawOffset+10*n, ENGLISH_POINT);
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }else{
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }
    }
    if (menuNameP != NULL) {
      lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 10);
      lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
    }
    lcd_lib_draw_hline(0, 127, 53);
    break;
  default:

    break;
  }




  entryDetailsCallback(selIndex);
}
void lcd_scroll_menu(const char* menuNameP, int8_t entryCount, entryNameCallback_t entryNameCallback, entryDetailsCallback_t entryDetailsCallback)
{
  if (lcd_lib_button_pressed)
    return;    //Selection possibly changed the menu, so do not update it this cycle.

  if (lcd_lib_encoder_pos < 0) lcd_lib_encoder_pos = 0;
  if (lcd_lib_encoder_pos >= entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM) lcd_lib_encoder_pos = entryCount * ENCODER_TICKS_PER_SCROLL_MENU_ITEM - 1;

  uint8_t selIndex = uint16_t(lcd_lib_encoder_pos/ENCODER_TICKS_PER_SCROLL_MENU_ITEM);

  lcd_lib_clear();

  int16_t targetViewPos;
  int16_t viewDiff;
  int16_t drawOffset;
  uint8_t itemOffset;

  switch (languageType) {
  case LANGUAGE_CHINESE:
  case LANGUAGE_KOREAN:
  {
    static int16_t viewPos = 8 + 12;
    targetViewPos = selIndex * 12;
    viewDiff = targetViewPos - viewPos;

    if (viewDiff<0) {
      viewDiff += 18;
      if (viewDiff > 0) {
        viewDiff=0;
      }
    }
    else if (viewDiff>0) {
      viewDiff -= 18;
      if (viewDiff<0) {
        viewDiff=0;
      }
    }

    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos--; led_glow = led_glow_dir = 0; }

    if (viewPos<0) {
      viewPos=0;
    }

    drawOffset = 7 + 12 -viewPos % 12;
    itemOffset = viewPos / 12;
    for(int8_t n=-2; n<4; n++)
    {
      uint8_t itemIdx = n + itemOffset;
      if (itemIdx >= entryCount)
        continue;

      char* ptr = entryNameCallback(itemIdx);
      ptr[20] = '\0';
      if (itemIdx == selIndex)
      {
        lcd_lib_draw_string(0, drawOffset+12*n, CHINESE_POINT);
        lcd_lib_draw_string(12, drawOffset+12*n, ptr);
      }else{
        lcd_lib_draw_string(12, drawOffset+12*n, ptr);
      }
    }
    lcd_lib_clear(0, 0, 127,0);

    lcd_lib_clear(0, 50, 127, 63);
    lcd_lib_clear(127-strlen_P(menuNameP)*6-6, 0, 127, 13);
    lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-6, 127, 13);

    lcd_lib_clear(0, 49, 127,49);
    lcd_lib_draw_hline(0, 127, 50);
    lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
  }
  break;

  case LANGUAGE_ENGLISH:
  {
    static int16_t viewPos = 8 +20;

    targetViewPos = selIndex * 10;
    viewDiff = targetViewPos - viewPos;

    if (viewDiff<0) {
      viewDiff += 15;
      if (viewDiff > 0) {
        viewDiff=0;
      }
    }
    else if (viewDiff>0) {
      viewDiff -= 15;
      if (viewDiff<0) {
        viewDiff=0;
      }
    }

    viewPos += viewDiff / 4;
    if (viewDiff > 0) { viewPos++; led_glow = led_glow_dir = 0; }
    if (viewDiff < 0) { viewPos--; led_glow = led_glow_dir = 0; }

    if (viewPos<0) {
      viewPos=0;
    }

    drawOffset = 8 +20 -viewPos % 10;
    itemOffset = viewPos / 10;
    for(int8_t n=-2; n<4; n++)
    {
      uint8_t itemIdx = n + itemOffset;
      if (itemIdx >= entryCount)
        continue;

      char* ptr = entryNameCallback(itemIdx);
      ptr[20] = '\0';
      if (itemIdx == selIndex)
      {
        lcd_lib_draw_string(0, drawOffset+10*n, ENGLISH_POINT);
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }else{
        lcd_lib_draw_string(10, drawOffset+10*n, ptr);
      }
    }

    lcd_lib_clear(0, 53, 127, 63);
    lcd_lib_clear(0, 0, 127, 9);
    lcd_lib_draw_hline(127-strlen_P(menuNameP)*6-12, 127, 10);
    lcd_lib_draw_hline(0, 127, 53);
    lcd_lib_draw_stringP(127-strlen_P(menuNameP)*6, 1, menuNameP);
  }
  default:
    break;
  }

  entryDetailsCallback(selIndex);
}
void lcd_basic_screen()
{
  lcd_lib_clear();
  lcd_lib_draw_hline(3, 124, LS(53, 50, 50));
}