#include "display.h"

c_onScreenButton ma20("20m", (uint8_t)mA20, LocBottom);
c_onScreenButton ma200("200m", (uint8_t)mA200, LocBottom);
c_onScreenButton ma1000("1A", (uint8_t)mA1000, LocBottom);
c_onScreenButton mauto("Auto", (uint8_t)mAuto, LocBottom);
c_onScreenButton bsetup("Conf", 5, LocBottom);
c_onScreenButton errorState("ER", 6, LocRight, &getErrorState);
c_onScreenButton okState("OK", 7, LocRight, &getOkState);
c_onScreenButton openState("Open", 8, LocRight, &getOpenState);
c_onScreenButton wifiState("Wifi", 9, LocRight, &getWifiState);

std::vector<c_onScreenButton> MainScreen;

#ifdef HAS_SSD1322

#define FONT8 u8g2_font_helvR08_tf
#define FONT16 u8g2_font_7x14_tf
#define FONT24 u8g2_font_freedoomr25_tn //u8g2_font_logisoso24_tf

U8G2_SSD1322_NHD_256X64_2_4W_HW_SPI display(U8G2_R0, OLED_CS, OLED_DC, OLED_RST);

void initMainScreenButtons(void)
{
  Serial.print("Init GUI: ");
  display.setFont(FONT8);
  uint16_t screenwidth = display.getWidth() - 1;
  uint16_t buttonwidth = ((screenwidth / mLast) - CONTROLLOFFSET * 2) - 1;
  uint16_t currentWidth = 0;
  uint16_t ypos = display.getHeight() - 1 - CONTROLSLINE_H + 2;

  //setup bottom buttons
  ma20.begin(currentWidth, ypos, buttonwidth, CONTROLSLINE_H + 6, CONTROLRADIUS);
  ma200.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
  ma1000.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
  mauto.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);
  bsetup.begin(currentWidth += (buttonwidth - 1), ypos, buttonwidth, CONTROLSLINE_H + CONTROLRADIUS, CONTROLRADIUS);

  //setup right side indicators
  uint16_t currentYpos = 0;
  uint16_t IndicatorXpos = screenwidth - INDICATORWIDTH - (INDICATORWIDTH / 2);

  errorState.begin(IndicatorXpos, currentYpos, INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
  okState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
  openState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);
  wifiState.begin(IndicatorXpos, currentYpos += (INDICATORHEIGHT - 1), INDICATORWIDTH, INDICATORHEIGHT, INDICATORRADIUS);

  //fill vector
  Serial.print("Store");
  MainScreen.push_back(ma20);
  MainScreen.push_back(ma200);
  MainScreen.push_back(ma1000);
  MainScreen.push_back(mauto);
  MainScreen.push_back(bsetup);

  MainScreen.push_back(errorState);
  MainScreen.push_back(okState);
  MainScreen.push_back(openState);
  MainScreen.push_back(wifiState);

  for (auto &&button : MainScreen)
  {
    button.setVisible(true);
  }
  Serial.println("OK");
}

void c_onScreenButton::begin(uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height, uint16_t radius)
{
  Serial.printf("%s", _name.c_str());
  _xpos = xpos;
  _width = width;
  _ypos = ypos;
  _radius = radius;
  _height = height;

  if (_location == LocBottom)
  {
    Serial.print(":Calc_yTpos");
    _yTpos = display.getHeight() - 1 - (CONTROLSLINE_H / 2) + (display.getMaxCharHeight() / 2);
    Serial.print(":Calc_xTpos");
    _xTpos = _xpos + (_width / 2) - (display.getStrWidth(_name.c_str()) / 2);
  }
  if (_location == LocRight)
  {
    Serial.print(":Calc_yTpos");
    _yTpos = _ypos + display.getMaxCharHeight() - 2;
    Serial.print(":Calc_xTpos");
    _xTpos = _xpos + (_width / 2) - (display.getStrWidth(_name.c_str()) / 2);
  }

  Serial.print(":OK | ");
}

void drawDashedHLine(uint16_t x, uint16_t y, uint16_t len)
{
  for(int i = 0; i < len; i+=2)
  {
    display.drawPixel(x+i, y);
  }
}

void drawDashedVLine(uint16_t x, uint16_t y, uint16_t len)
{
  for(int i = 0; i < len; i+=2)
  {
    display.drawPixel(x, y+i);
  }
}

void c_onScreenButton::drawButton()
{
  display.setFont(FONT8);
  //Serial.printf("drawbutton:%s(x=%u, y=%u, w=%u, h=%u)\n", _name.c_str(), _xpos, _ypos, _width, _height);
  if (!_visible)
  {
    //hide button
    return;
  }

  if (getState())
  {
    display.drawRBox(_xpos, _ypos, _width, _height, _radius);
    display.setDrawColor(0);
    display.drawStr(_xTpos, _yTpos, _name.c_str());
  }
  else
  {
    display.setDrawColor(1);
    display.drawRFrame(_xpos, _ypos, _width, _height, _radius);
    display.drawStr(_xTpos, _yTpos, _name.c_str());
  }

  display.setDrawColor(1);
}

String showValue(String designator, double value, String unit)
{
  String text;
  text.clear();
  if (designator != "")
  {
    text = designator;
  }
  text += value;
  text += unit;
  return text;
}

void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress)
{
  uint16_t radius = height / 2;
  uint16_t doubleRadius = radius << 1;

  display.setColorIndex(1);
  display.drawRFrame(x, y, width, height, radius);

  uint16_t maxProgressWidth = (width - doubleRadius + 1) * progress / 100;

  display.drawRBox(x + 1, y + 2, maxProgressWidth, height - 3, radius);
}

void drawMeasurementValues()
{
  // display.setFont(FONT16);
  // display.drawStr(0, 12, showValue("m:", getMin(), "").c_str());
  // display.drawStr(80, 12, showValue("r:", getRms(), "").c_str());
  // display.drawStr(160, 12, showValue("m:", getMax(), "").c_str());

  drawDashedHLine(0,12,220);
  drawDashedVLine(40,12,33);
  display.setFont(FONT8);
  display.drawStr(5,8,"Fs:100Hz    LP");
 

  display.setFont(FONT24);

  display.drawStr(60, 45, showValue("", getValue(), "").c_str());
  uint16_t stringwidth = display.getStrWidth(showValue("", getValue(), "").c_str());
  display.setFont(u8g2_font_8x13_t_symbols);
  display.drawUTF8(60+stringwidth+3 , 43, "mΩ");
  //drawProgressBar(0, 40, 127, 5, getBar());
}

void drawMainSceenButtons()
{
  //draw controlstrip indicators
  for (auto &&thismode : MainScreen)
  {
    thismode.setState((thismode.getIndex() == (uint8_t)getMeasureMode()));
    thismode.drawButton();
  }
}

void drawMainScreen()
{
  drawMainSceenButtons();
  drawMeasurementValues();
}

uint64_t lastDisplayTime = 0;

void initDisplay()
{
  initMainScreenButtons();
  display.begin();
  display.clearBuffer();
  lastDisplayTime = millis();
}

void handleDisplay()
{
  uint64_t currentmillis = millis();
  if (currentmillis - lastDisplayTime > SCREENREFRESH)
  {
    do
    {
      drawMainScreen();
    } while (display.nextPage());
    lastDisplayTime = millis();
  }
}

#endif