/*
ESPboy_MenuGUI class
for www.ESPboy.com project by RomanS
https://hackaday.io/project/164830-espboy-games-iot-stem-for-education-fun
v1.0
*/


#include "ESPboyMenuGUI.h"
#define SOUNDPIN D3


ESPboyMenuGUI::ESPboyMenuGUI(TFT_eSPI *tftMenuGUI, Adafruit_MCP23017 *mcpMenuGUI) {
   tft = tftMenuGUI;
   mcp = mcpMenuGUI;
#ifdef U8g2
   u8f = new U8g2_for_TFT_eSPI;
   u8f->begin(*tft); 
   u8f->setFontMode(1);                 // use u8g2 none transparent mode
   u8f->setBackgroundColor(TFT_BLACK);
   u8f->setFontDirection(0);            // left to right
   u8f->setFont(u8g2_font_4x6_t_cyrillic); 
#endif
}


uint8_t ESPboyMenuGUI::getKeys() { return (~mcp->readGPIOAB() & 255); }


void ESPboyMenuGUI::menuDraw(){
  static uint16_t scalingFactor;
  static uint16_t previousRect = 0;

  if(menuList.menuItemsQuantity>1){
    if(menuList.menuItemsQuantity>=MENU_MAX_LINES_ONSCREEN)
      scalingFactor = ((MENU_MAX_LINES_ONSCREEN*MENU_SPACE_BETWEEN_LINES-6)*1000)/(menuList.menuItemsQuantity-1);
    else
      scalingFactor = ((menuList.menuItemsQuantity*MENU_SPACE_BETWEEN_LINES-6)*1000)/(menuList.menuItemsQuantity-1);
  }
  else scalingFactor=1;
  
  tft->drawRect(0, previousRect*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, TFT_BLACK);
  tft->fillRect(125,0, 3, 128, TFT_BLACK);

  if (menuList.menuCurrent+1 > MENU_MAX_LINES_ONSCREEN + menuList.menuOffset) {
      tft->fillScreen(TFT_BLACK); 
      menuList.menuOffset++;}
  if (menuList.menuCurrent < menuList.menuOffset) {
      tft->fillScreen(TFT_BLACK); 
      menuList.menuOffset--;}

  if(menuList.menuItemsQuantity>=MENU_MAX_LINES_ONSCREEN)
    tft->drawLine(126,0, 126, MENU_MAX_LINES_ONSCREEN*MENU_SPACE_BETWEEN_LINES-2, TFT_BLUE);
  else
    tft->drawLine(126,0, 126, menuList.menuItemsQuantity*MENU_SPACE_BETWEEN_LINES-2, TFT_BLUE);
  
  for (uint8_t i=0;; i++){
    if(i>=menuList.menuItemsQuantity || i>=MENU_MAX_LINES_ONSCREEN) break;

    #ifndef U8g2
      if(menuList.menuLine[i+menuList.menuOffset][0] == '-'){ 
        tft->setTextColor(menuList.menuUnselectedLineColor);
        tft->drawString(&menuList.menuLine[i+menuList.menuOffset][1], 3, i*MENU_SPACE_BETWEEN_LINES+2);
      }
      else{
        tft->setTextColor(menuList.menuLineColor);
        tft->drawString(menuList.menuLine[i+menuList.menuOffset], 3, i*MENU_SPACE_BETWEEN_LINES+2); 
      }
    #else
      if(menuList.menuLine[i+menuList.menuOffset][0] == '-'){ 
        u8f->setForegroundColor(menuList.menuUnselectedLineColor);
        u8f->drawStr(3, i*MENU_SPACE_BETWEEN_LINES+1+GUI_FONT_HEIGHT, &menuList.menuLine[i+menuList.menuOffset][1]);
      }
      else { 
        u8f->setForegroundColor(menuList.menuLineColor);
        u8f->drawStr(3, i*MENU_SPACE_BETWEEN_LINES+1+GUI_FONT_HEIGHT, menuList.menuLine[i+menuList.menuOffset]);
      }
    #endif
    
    if((i+menuList.menuOffset) == menuList.menuCurrent){
      tft->drawRect(0, i*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, menuList.menuSelectionColor);
      previousRect=i;}
  }

 tft->fillRect(125, (scalingFactor*menuList.menuCurrent+2)/1000, 3, 5, TFT_YELLOW);
}



uint16_t ESPboyMenuGUI::menuInit(const char** menuLinesF, uint16_t menuLineColorF, uint16_t menuUnselectedLineColorF, uint16_t menuSelectionColorF){             
 uint16_t count=0;
 static uint8_t keyPressed;
  tft->fillScreen(TFT_BLACK);
  menuList.menuLine = menuLinesF;
  menuList.menuLineColor = menuLineColorF;
  menuList.menuUnselectedLineColor = menuUnselectedLineColorF;
  menuList.menuCurrent = 0;
  menuList.menuSelectionColor = menuSelectionColorF;
  menuList.menuOffset=0;
  while(menuLinesF[count++]);
  menuList.menuItemsQuantity = count-1;

  menuDraw();

 while(1){  
  while (!getKeys())delay(50);
  
  keyPressed = getKeys();
  
  if (keyPressed&MenuGUI_PAD_UP && menuList.menuCurrent > 0) {
    menuList.menuCurrent--;
    #ifdef buttonclicks
    tone(SOUNDPIN,10,10);
    #endif
    menuDraw();
  }
  if (keyPressed&MenuGUI_PAD_DOWN && menuList.menuCurrent+1 < menuList.menuItemsQuantity) {
    menuList.menuCurrent++;
    #ifdef buttonclicks
    tone(SOUNDPIN,10,10);
    #endif
    menuDraw();
  }
  if (keyPressed&MenuGUI_PAD_ACT && menuList.menuLine[menuList.menuCurrent][0] != '-') {
    #ifdef buttonclicks  
      tone(SOUNDPIN,100,100);
    #endif
    
    tft->drawRect(0, (menuList.menuCurrent+menuList.menuOffset)*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, TFT_BLACK);
    delay(50);
    tft->drawRect(0, (menuList.menuCurrent+menuList.menuOffset)*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, menuList.menuSelectionColor);
    delay(50);
    tft->drawRect(0, (menuList.menuCurrent+menuList.menuOffset)*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, TFT_BLACK);
    delay(50);
    tft->drawRect(0, (menuList.menuCurrent+menuList.menuOffset)*MENU_SPACE_BETWEEN_LINES, 122, MENU_SPACE_BETWEEN_LINES, menuList.menuSelectionColor);
    delay(200);
    
    tft->fillScreen(TFT_BLACK);
    return(menuList.menuCurrent+1);
  }
  if (keyPressed&MenuGUI_PAD_ESC){
    #ifdef buttonclicks  
      tone(SOUNDPIN,100,100);
    #endif    
    tft->fillScreen(TFT_BLACK);
    return(0);
  }
  
  delay(120);
 }
};
