/*
Descripción del programa:
Este programa muestra un reloj digital en una pantalla TTGO con ESP32.
El diseño del reloj es similar a un display de 7 segmentos, y la hora se
actualiza en tiempo real, utilizando la hora de compilación como la hora inicial.
El reloj parpadea el colon (:) cada segundo y actualiza los minutos y horas 
en intervalos de tiempo apropiados.

Componentes clave:
- Inicializa la pantalla y establece el fondo en negro.
- Actualiza y redibuja el tiempo en formato digital cada segundo.
- Usa la hora de compilación para establecer la hora inicial.

Funcionalidad:
- setup(): Configura la pantalla y la inicializa.
- loop(): Actualiza y redibuja el tiempo en la pantalla cada segundo.
- conv2d(const char* p): Convierte dos caracteres en un número de dos dígitos para obtener la hora de compilación.

Colores usados:
code	color
0x0000	Black
0xFFFF	White
0xBDF7	Light Gray
0x7BEF	Dark Gray
0xF800	Red
0xFFE0	Yellow
0xFBE0	Orange
0x79E0	Brown
0x07E0	Green
0x07FF	Cyan
0x001F	Blue
0xF81F	Pink
*/

#include <TFT_eSPI.h> // Biblioteca gráfica y de fuentes para el controlador ST7735
#include <SPI.h> // Biblioteca para comunicación SPI

TFT_eSPI tft = TFT_eSPI();  // Invoca la biblioteca, pines definidos en User_Setup.h

uint32_t targetTime = 0;       // Para el próximo tiempo de espera de 1 segundo

byte omm = 99; // Minutos anteriores
byte xcolon = 0; // Posición del colon en la pantalla

// Función para convertir dos caracteres en un número de dos dígitos
static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9')
    v = *p - '0'; // Convierte el primer carácter
  return 10 * v + *++p - '0'; // Convierte el segundo carácter y lo suma al primero
}

// Obtiene la hora, minutos y segundos de la hora de compilación
uint8_t hh = conv2d(__TIME__);
uint8_t mm = conv2d(__TIME__ + 3);
uint8_t ss = conv2d(__TIME__ + 6);

void setup(void) {
  tft.init(); // Inicializa la pantalla
  tft.setRotation(1); // Establece la orientación de la pantalla
  tft.fillScreen(TFT_BLACK); // Rellena la pantalla con color negro

  tft.setTextColor(TFT_YELLOW, TFT_BLACK); // Establece el color del texto en amarillo y el fondo en negro

  targetTime = millis() + 1000; // Establece el tiempo objetivo para el primer segundo
}

void loop() {
  if (targetTime < millis()) {
    targetTime = millis() + 1000; // Actualiza el tiempo objetivo para el próximo segundo
    ss++; // Incrementa los segundos
    if (ss == 60) {
      ss = 0; // Reinicia los segundos
      omm = mm; // Guarda los minutos actuales
      mm++; // Incrementa los minutos
      if (mm > 59) {
        mm = 0; // Reinicia los minutos
        hh++; // Incrementa las horas
        if (hh > 23) {
          hh = 0; // Reinicia las horas
        }
      }
    }

    // Actualiza la hora digital
    byte xpos = 50; // Posición x inicial para dibujar el tiempo
    byte ypos = 90; // Posición y inicial para dibujar el tiempo
    if (omm != mm) { // Solo redibuja cada minuto para minimizar el parpadeo
      tft.setTextColor(TFT_BLACK, TFT_BLACK); // Establece el color de la fuente en negro para borrar la imagen
      tft.drawString("88:88", xpos, ypos, 7); // Sobrescribe el texto para borrarlo
      tft.setTextColor(0xFBE0); // Naranja
      omm = mm; // Actualiza los minutos anteriores

      // Dibuja las horas con formato de dos dígitos
      if (hh < 10) xpos += tft.drawChar('0', xpos, ypos, 7); // Dibuja '0' si la hora es menor a 10
      xpos += tft.drawNumber(hh, xpos, ypos, 7); // Dibuja las horas
      xcolon = xpos; // Guarda la posición del colon
      xpos += tft.drawChar(':', xpos, ypos, 7); // Dibuja el colon
      // Dibuja los minutos con formato de dos dígitos
      if (mm < 10) xpos += tft.drawChar('0', xpos, ypos, 7); // Dibuja '0' si los minutos son menores a 10
      tft.drawNumber(mm, xpos, ypos, 7); // Dibuja los minutos
    }

    if (ss % 2) { // Hace parpadear el colon
      tft.setTextColor(0x07E0, TFT_BLACK); // Establece el color del colon a verde
      xpos += tft.drawChar(':', xcolon, ypos, 7); // Dibuja el colon
      tft.setTextColor(0xFBE0, TFT_BLACK); // Establece el color del colon a naranja
    } else {
      tft.drawChar(':', xcolon, ypos, 7); // Dibuja el colon sin cambiar de color
    }
  }
}