#include <LiquidCrystal.h>

// Configuração inicial do display LCD
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

// Caracteres customizados para a exibição de níveis de bateria
byte batteryStates[8][8] = {
  {B01111, B11000, B10101, B10100, B10100, B10100, B11000, B01111},  // Vazio
  {B11111, B00000, B11001, B00000, B00000, B00000, B00000, B11111},  // Contorno
  {B11100, B00100, B10111, B00101, B00111, B00111, B00100, B11100},  // Parcial
  {B1111, B11111, B10110, B10111, B10111, B10111, B11111, B1111},    // Quase cheio
  {B11100, B11100, B01111, B11101, B11111, B11111, B11100, B11100},  // Cheio
  {B11111, B11111, B00110, B11111, B11111, B11111, B11111, B11111},  // 3/4
  {B11111, B11000, B00001, B11000, B11000, B11000, B11000, B11111},  // 1/3
  {B11111, B11110, B00111, B11110, B11110, B11110, B11110, B11111}   // 2/3
};

// Caracteres customizados para a régua de nível
byte levelStates[5][8] = {
  {B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111},  // Vazio
  {B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111},  // 1/4
  {B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111},  // 1/2
  {B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111},  // 3/4
  {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}   // Cheio
};

// Sequências para exibição dos estados da bateria
char batteryDisplay[9][4] = {
  {0, 1, 1, 2}, {3, 1, 1, 2}, {3, 6, 1, 2},
  {3, 7, 1, 2}, {3, 5, 1, 2}, {3, 5, 6, 2},
  {3, 5, 7, 2}, {3, 5, 5, 2}, {3, 5, 5, 4}
};

void setup() {
  lcd.begin(16, 2); // Inicia o display LCD com 16 colunas e 2 linhas
  // Cria os caracteres customizados
  for (int i = 0; i < 8; i++) {
    lcd.createChar(i, batteryStates[i]);
  }

  lcd.setCursor(0, 1);
  lcd.print("Preparando...");
  delay(1000);
  lcd.clear();

  initializeDisplays(); // Inicializa a demonstração dos estados
}

void loop() {
  updateDisplays();
  delay(500); // Atualiza a exibição a cada 500 ms
}

void initializeDisplays() {
  for (int i = 0; i < 9; i++) {
    lcdBatteryStatus(i, 0);
    lcdBatteryLevel(i * 12.5); // Exibe o percentual aproximado
    delay(500);
  }
}

void updateDisplays() {
  int batteryLevel = analogRead(A0);
  int batteryState = map(batteryLevel, 0, 1023, 0, 8);

  lcdBatteryStatus(batteryState, 0);
  lcdBatteryLevel(batteryState * 12.5);

  int rulerLevel = analogRead(A1);
  int rulerState = map(rulerLevel, 0, 1023, 0, 100);

  lcdRulerLevel(rulerState);
}

void lcdBatteryStatus(int state, int row) {
  lcd.setCursor(0, row);
  for (int i = 0; i < 4; i++) {
    lcd.write(batteryDisplay[state][i]);
  }
}

void lcdBatteryLevel(int percent) {
  lcd.setCursor(0, 1);
  lcd.print("Bat:");
  lcd.print(percent);
  lcd.print("%  ");
}

void lcdRulerLevel(int percent) {
  lcd.setCursor(10, 1);
  lcd.print("L:");
  lcd.print(percent);
  lcd.print("% ");
}