#include <AceButton.h>
#include <AceMenu.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Pines del encoder KY-040
const int encoderButtonPin = 2;
const int encoderRightPin = 3;
const int encoderLeftPin = 4;

// Objeto para la pantalla LCD I2C
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Variables para la configuración del tiempo y la temperatura
int timeSetting = 0;
int tempSetting = 0;

// Objetos para las opciones del menú
MenuItem timeMenuItem("Tiempo", setTime);
MenuItem tempMenuItem("Temperatura", setTemp);
MenuItem backMenuItem("Volver");

// Objeto para el menú principal
Menu menu("Menu principal", {&timeMenuItem, &tempMenuItem, &backMenuItem});

void setup() {
  // Inicializar la pantalla LCD
  lcd.init();
  lcd.backlight();

  // Inicializar el encoder KY-040
  pinMode(encoderButtonPin, INPUT_PULLUP);
  pinMode(encoderRightPin, INPUT_PULLUP);
  pinMode(encoderLeftPin, INPUT_PULLUP);

  // Inicializar la librería AceMenu
  menu.setLcd(lcd);
  menu.init();
}



void loop() {
  // Leer el estado del encoder
  int buttonState = digitalRead(encoderButtonPin);
  int rightState = digitalRead(encoderRightPin);
  int leftState = digitalRead(encoderLeftPin);

  // Si se presiona el botón del encoder, seleccionar la opción actual del menú
  if (buttonState == LOW) {
    menu.select();
  }

  // Si se gira el encoder a la derecha, avanzar a la siguiente opción del menú
  if (rightState == LOW) {
    menu.next();
  }

  // Si se gira el encoder a la izquierda, volver a la opción anterior del menú
  if (leftState == LOW) {
    menu.prev();
  }

  // Actualizar el menú en la pantalla LCD
  menu.update();
}


void setTemp() {
  // Mostrar un mensaje en la pantalla LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Ajustar temperatura");

  // Bucle para configurar la temperatura
  while (true) {
    // Leer el estado del encoder
    int buttonState = digitalRead(encoderButtonPin);
    int rightState = digitalRead(encoderRightPin);
    int leftState = digitalRead(encoderLeftPin);

    // Si se presiona el botón del encoder, salir del bucle
    if (buttonState == LOW) {
      break;
    }

    // Si se gira el encoder a la derecha, aumentar la temperatura
    if (rightState == LOW) {
      tempSetting++;
    }

    // Si se gira el encoder a la izquierda, disminuir la temperatura
    if (leftState == LOW) {
      tempSetting--;
    }

    // Mostrar la temperatura en la pantalla LCD
    lcd.setCursor(0, 1);
    lcd.print(tempSetting);
  }
}
void setTime() {
  // Mostrar un mensaje en la pantalla LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Ajustar tiempo");

  // Bucle para configurar el tiempo
  while (true) {
    // Leer el estado del encoder
    int buttonState = digitalRead(encoderButtonPin);
    int rightState = digitalRead(encoderRightPin);
    int leftState = digitalRead(encoderLeftPin);

    // Si se presiona el botón del encoder, salir del bucle
    if (buttonState == LOW) {
      break;
    }

    // Si se gira el encoder a la derecha, aumentar el tiempo
    if (rightState == LOW) {
      timeSetting++;
    }

    // Si se gira el encoder a la izquierda, disminuir el tiempo
    if (leftState == LOW) {
      timeSetting--;
    }

    // Mostrar el tiempo en la pantalla LCD
    lcd.setCursor(0, 1);
    lcd.print(timeSetting);
  }
}