#include "Wire.h"
#include "Bounce2.h"
#include "EEPROM.h"

/*
 * Estructuras
 */

struct Luns {
  bool Luns0;
  bool Luns1;
  bool Luns2;
  bool Luns3;
  bool Luns4;
  bool Luns5;
  bool Luns6;
  bool Luns7;
  bool Luns8;
  bool Luns9;
  bool Luns10;
  bool Luns11;
  bool Luns12;
  bool Luns13;
  bool Luns14;
  bool Luns15;
  bool Luns16;
  bool Luns17;
  bool Luns18;
  bool Luns19;
  bool Luns20;
  bool Luns21;
  bool Luns22;
  bool Luns23;
};

/* 
 * Definición de entradas dixitais
 */
int E_BUTTON = 2;     // Pin de botón de memorizar
int E_BUTTON1 = 3;    // Pin de botón de incrementar

/* 
 * Debouncing de entradas dixitais
 */
int intervalodb = 100;        // Tempo de botón premido
Bounce DB_BUTTON = Bounce();  // Instancia de debouncing de botón de memorizar
Bounce DB_BUTTON1 = Bounce();  // Instancia de debouncing de botón de alternar

/* 
 * Definición de entradas dixitais tras debouncing
 */
bool V_BUTTON = 0; // Botón de memorizar
bool V_BUTTON1 = 0; // Botón de alternar

/* 
 * Definición de flancos entradas dixitais tras debouncing
 */
bool FP_BUTTON1 = 0; // Flanco positivo de botón de memorizar

/* 
 * Definición de saídas dixitais
 */
int S_LED = 12; // Pin de saída a led

/*
 * Definición de marcas
 */
bool booleano; 
bool booleeprom;

/* ------------------------------------------------
 * VOID SETUP: Código executado no ciclo de inicio
 * ------------------------------------------------*/
void setup() {

  struct Luns LunsVar;

/*
 * Definición de entradas dixitais
 */
  pinMode(E_BUTTON,INPUT); // Pin de botón de memorizar
  // Deboucing (para evitar interferencias e rebotes ao premer os botóns)
  DB_BUTTON.attach(E_BUTTON);
  DB_BUTTON.interval(intervalodb); // intervalo en ms

  pinMode(E_BUTTON1,INPUT); // Pin de botón de alternar
  // Deboucing (para evitar interferencias e rebotes ao premer os botóns)
  DB_BUTTON1.attach(E_BUTTON1);
  DB_BUTTON1.interval(intervalodb); // intervalo en ms


/*
 * Definición de saídas dixitais
 */
  pinMode(S_LED,OUTPUT);       // Pin de saída a LED

/*
 * Iniciar comunicación por porto serie para depurar o código
 */
  Serial.begin(9600);

EEPROM.get( 0, booleeprom );
booleano = booleeprom;

}

/* ----------------------------------------
 * VOID LOOP: Código repetido ciclicamente
 * ----------------------------------------*/
void loop() {

/* 
 * Actualizar as instancias de debouncing das entradas dixitais
 */
  // Actualizar instancias:
  DB_BUTTON.update();
  DB_BUTTON1.update();

  // Ler os valores actualizados:
  bool V_BUTTON = DB_BUTTON.read();
  bool V_BUTTON1 = DB_BUTTON1.read();

  if (V_BUTTON == 1){
  EEPROM.put( 0, LunsVar );
  }

  if (V_BUTTON == 1 || V_BUTTON1 == 1){
    digitalWrite(S_LED, HIGH);
  }
  else{
    digitalWrite(S_LED, LOW);
  }

  if (V_BUTTON1 == 1 && FP_BUTTON1 == 0){
    if (booleano == 0){
      booleano = 1;
      FP_BUTTON1 = 1;
  }
  else if (booleano == 1){
      booleano = 0;
      FP_BUTTON1 = 1;
  }
}
else if (V_BUTTON1 == 0 && FP_BUTTON1 == 1){
  FP_BUTTON1 = 0;
}

EEPROM.get( 0, booleeprom );

  Serial.println("Runtime:");
  Serial.println(booleano);
  Serial.println("EEPROM:");
  Serial.println(booleeprom);
  Serial.println("-----------");
  delay(1000);
}