#include <Adafruit_SSD1306.h>



/********************************************************/
/*____________________DISPLAY_PINS______________________*/

#define BUTTON_UP_PIN 4                               /* Menu button pin */
#define UP_LED_PIN 27                                 /* Signal LEG pin */

/********************************************************/
/*____________________CONTROL_VARS______________________*/

volatile uint8_t button_up_clicked   = 0;             /* only perform action when button is clicked, and wait until another press */
volatile uint8_t check_display_count = 0;
volatile uint8_t display_increment   = 0;

/********************************************************/
/*______________________TASK_DATA_______________________*/

const static uint8_t p_oledDisplayTask = 1;
TaskHandle_t h_oledDisplayTask;

/********************************************************/
/*__________________DISPLAY_SETTINGS____________________*/

#define SCREEN_WIDTH 128                  // OLED display width, in pixels
#define SCREEN_HEIGHT 64                  // OLED display height, in pixels
#define OLED_RESET -1                     // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C               ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

/********************************************************/
/*_________________STATE_MACHNE_DATA____________________*/
const int NUM_ITEMS = 4; // number of items in the list and also the number of screenshots and screenshots with QR codes (other screens)

const char *menu_items [NUM_ITEMS] =
{ // array with item names
  "Welcome",
  "Conectivitate",
  "Termostat",
  "Calitate aer"
};

enum oledState
{
  ECRAN_0,
  ECRAN_1,
  ECRAN_2,
  ECRAN_3
};

oledState currentOledState = ECRAN_0;

const char *stateToString_oledState(oledState oled_state)
{
  switch (oled_state)
  {
    case ECRAN_0:
      return menu_items[0];
    case ECRAN_1:
      return menu_items[1];
    case ECRAN_2:
      return menu_items[2];
    case ECRAN_3:
      return menu_items[3];
    default:
      return "UNKNOWN";
  }
}

/********************************************************/

// class SSD1306_OLED()
// {
//   private:
//     static int manage_button_pressing()
//     static void oled_display_update();
//   public:
//     static int get_button_increment();
//     static void change_display_information();
// }

/********************************************************/

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello, ESP32!");
  pinMode(BUTTON_UP_PIN, INPUT_PULLUP); // up button
  pinMode(UP_LED_PIN, OUTPUT);
  // pinMode(DOWN_LED_PIN, OUTPUT);

  xTaskCreatePinnedToCore(
    T_oledDisplayTask,  /* Task function. */
    "oledDisplayTask",  /* String with name of task. */
    2000,               /* Stack size in bytes. */
    NULL,               /* Parameter passed as input of the task */
    p_oledDisplayTask,  /* Priority of the task. */
    &h_oledDisplayTask, /* Task handle to keep track of created task */
    1                   /* pin task to core 0 */
  );
  Serial.println("  >> Created Task: oledDisplayTask");

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
  {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ; // Don't proceed, loop forever
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("DISPLAY ON!");
  display.display();

}

void loop()
{

}


void T_oledDisplayTask(void *parameter)
{
  for (;;)
  {

    /************************************************************/
    uint8_t oled_screen_number = get_button_increment();
    change_display_information(oled_screen_number);
    /************************************************************/

    Serial.print("Display count: "); Serial.println(display_increment);

    vTaskDelay(pdMS_TO_TICKS(50)); // Delay for 100 milliseconds

  }
}

void oled_display_update(String oled_message, uint8_t cursor_1, uint8_t cursor_2, uint8_t text_size)
{
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(cursor_1, cursor_2);
  display.println(oled_message);
  display.display();
}


void change_display_information(uint8_t display_index)
{

  String oled_message; // Declare here
  String tempString; // Declare here
  String humidityString; // Declare here

  switch (display_index)
  {
    case 0:
      currentOledState = ECRAN_0;
      if (currentOledState == ECRAN_0)
      {
        String title = String(stateToString_oledState(currentOledState)); // Convert to String and remove the state number        int spaces = (20 - title.length()) / 2; // Assuming the display is 20 characters wide
        int spaces = (6 - title.length()) / 2; // Assuming the display is 20 characters wide
        oled_message = String(' ', spaces) + title + "\nWelcome to\nsmart home";
        oled_display_update(oled_message, 0, 0, 1);
        break;
      }
    case 1:
      currentOledState = ECRAN_1;
      tempString = String(23.5, 1);  // One decimal place
      humidityString = String(23.5, 1); // One decimal place
      if (currentOledState == ECRAN_1)
      {
        String title = String(stateToString_oledState(currentOledState)); // Convert to String and remove the state number        int spaces = (20 - title.length()) / 2; // Assuming the display is 20 characters wide
        int spaces = (6 - title.length()) / 2; // Assuming the display is 20 characters wide
        oled_message = String(' ', spaces) + title + "\nTemp: " + tempString + "C\nHumidity: " + humidityString + "%";
        oled_display_update(oled_message, 0, 0, 1);
      }
      break;
    case 2:
      currentOledState = ECRAN_2;
      if (currentOledState == ECRAN_2)
      {
        String title = String(stateToString_oledState(currentOledState)); // Convert to String and remove the state number        int spaces = (20 - title.length()) / 2; // Assuming the display is 20 characters wide
        int spaces = (6 - title.length()) / 2; // Assuming the display is 20 characters wide
        oled_message = String(' ', spaces) + title + "\nCurrent State:\n" + "COOLING";
        oled_display_update(oled_message, 0, 0, 1);
      }
      break;
    case 3:
      currentOledState = ECRAN_3;
      if (currentOledState == ECRAN_3)
      {
        String title = String(stateToString_oledState(currentOledState)).substring(0); // Convert to String and remove the state number        int spaces = (20 - title.length()) / 2; // Assuming the display is 20 characters wide
        int spaces = (6 - title.length()) / 2; // Assuming the display is 20 characters wide
        oled_message = String(' ', spaces) + title + "\nNEFOLOSIT\nNEFOLOSIT";
        oled_display_update(oled_message, 0, 0, 1);
      }
      break;
  }
}


int get_button_increment()
{
  check_display_count = manage_button_pressing();
  if ( check_display_count == 1)
  {

    display_increment += 1;

    if (display_increment == 4)
    {
      display_increment = 0;
    }

  }

  return display_increment;
}


int manage_button_pressing()
{
  // Up button
  if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0))
  {
    button_up_clicked = 1;
    Serial.println("Up button pressed");
    digitalWrite(UP_LED_PIN, HIGH);
  }
  else if (digitalRead(BUTTON_UP_PIN) == HIGH)
  {
    button_up_clicked = 0;
    Serial.println("Up button released");
    digitalWrite(UP_LED_PIN, LOW);
  }

  return button_up_clicked;
}