/*
  Timer_lite.h - Librería para temporizador ligero
  Copyright (c) 2021 Koneko Microcontroladores. Todos los derechos reservados.

  Autor: Arturo Corro arturo@koneko.mx
  Versiones: 0.1.0

  v0.0.1 - May 2, 2021 - Versión inicial

  RTClib
    https://github.com/adafruit/RTClib
    Direcciones de memoria 0x07-0x0D (0-6)
*/

#ifndef Timer_lite_H
#define Timer_lite_H

#include <Arduino.h>
#include <EEPROM.h>
#include <Wire.h>
#include "RTClib.h"

//#define DEBUG_SERIAL_ENABLE

#define dbSerial Serial

#ifdef DEBUG_SERIAL_ENABLE
    #define serialPrint(a)    dbSerial.print(a)
    #define serialPrintln(a)  dbSerial.println(a)
    #define serialBegin(a)    dbSerial.begin(a)
    #define serialBeginWhile(a) while(!dbSerial) delay(1)
#else
    #define serialPrint(a)    do{}while(0)
    #define serialPrintln(a)  do{}while(0)
    #define serialBegin(a)    do{}while(0)
    #define serialBeginWhile(a) do{}while(0)
#endif

#define RELAY_OFF HIGH
#define RELAY_ON  LOW

#define TIMER_DETENIDO         0
#define TIMER_INICIO_ESPERA    1
#define TIMER_ARRANQUE         2
#define TIMER_ARRANQUE_ESPERA  3
#define TIMER_ENCENDIDO        4
#define TIMER_ENCENDIDO_ESPERA 5

class Timer_lite
{
    private:
        // Numero de instancias
        static uint8_t _instancias_num;
        uint8_t _instancia_num;

        // Direcciones de Hardware
        uint8_t _relay_pin;

        // EEPROM ADDRESS
        uint8_t _eeprom_address_tiempo_inicio_espera;
        uint8_t _eeprom_address_tiempo_arranque;
        uint8_t _eeprom_address_tiempo_arranque_espera;
        uint8_t _eeprom_address_tiempo_encendido;
        uint8_t _eeprom_address_tiempo_encendido_espera;
        uint8_t _eeprom_address_timer_detenido;


        // Uso del temporizador
        uint8_t _periodo;
        uint32_t _fin_de_periodo_seg;
        uint32_t _restante_del_periodo_seg;

        uint8_t _status_relay;

        // Contador para ciclo
        //uint32_t _T[3];


        //** MÉTODOS PRIVADOS**
        void _init(uint8_t initial_eeprom_address = 0);

        void     EEPROMWritelong(uint8_t address, uint32_t value);
        uint32_t EEPROMReadlong(uint8_t address);

        //void proximoPeriodo();

    public:
        // Fecha y hora, Reloj de Tiempo Real
        static DateTime _now;
        static RTC_DS3231 _RTC;

        //** CONSTRUCTOR **
        Timer_lite(uint8_t relay_pin);
        Timer_lite(uint8_t relay_pin, uint8_t initial_eeprom_address);

        //** DESTRUCTOR **
        ~Timer_lite();

        // Relay
        void setRelayPin(uint8_t relay_pin);
        void setRelaySatus(uint8_t relay_status);

        // Configuraciones Timer_lite
        void setTiempoInicioEspera(uint32_t segundos);
        void setTiempoInicioEspera(uint8_t minutos, uint8_t segundos);
        void setTiempoArranque(uint32_t segundos);
        void setTiempoArranque(uint8_t horas, uint8_t minutos, uint8_t segundos);
        void setTiempoArranqueEspera(uint32_t segundos);
        void setTiempoArranqueEspera(uint8_t horas, uint8_t minutos, uint8_t segundos);
        void setTiempoEncendido(uint32_t segundos);
        void setTiempoEncendido(uint8_t horas, uint8_t minutos, uint8_t segundos);
        void setTiempoEncendidoEspera(uint32_t segundos);
        void setTiempoEncendidoEspera(uint8_t horas, uint8_t minutos, uint8_t segundos);

        // Set Fecha y Hora
        void setFecha(uint16_t anho, uint8_t mes, uint8_t dia);
        void setHora(uint8_t hrs, uint8_t min, uint8_t seg);
        void setFechaHora(uint16_t anho, uint8_t mes, uint8_t dia, uint8_t hrs, uint8_t min, uint8_t seg);
        void setFechaHoraSistema();

        // Get Fecha y Hora
        String getFecha();
        String getHora();

        // Status Timer_lite
        uint8_t  getInstanciasNum();
        uint8_t  getInstanciaNum();

        uint8_t  getPeriodo();
        uint32_t getFinPeriodoSeg();
        uint32_t getRestantePeriodoSeg();

        uint8_t  getStatusRelay();

        uint32_t getTiempoInicioEspera();
        uint32_t getTiempoArranque();
        uint32_t getTiempoArranqueEspera();
        uint32_t getTiempoEncendido();
        uint32_t getTiempoEncendidoEspera();
        uint8_t  getTimerDetenido();

        // Metodos de control
        void detener();
        void reanudar();

        void reiniciar();

        // PROCESO DEL TEMPORIZADOR
        void initialize();
        void process_loop();
};

#endif
