/* 
  ====================================================================
  Implementação de display SSD1306 na placa ESP32
  --------------------------------------------------------------------
  Descrição do funcionamento [para fins de teste do display na placa]:

  Botão verde ----> incrementa contagem de ID de aluno
  Botão amarelo --> decrementa contagem de ID de aluno
  Botão Azul -----> mostra mensagem "Audio...gravado"
  Botão Vermelho -> mostra status da mineração de dados
  --------------------------------------------------------------------
  Autores: Eli Ana C. Camargo e Matheus Silva Martins Mota
  ====================================================================
*/

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_SSD1306.h>

#define BTN_CPIN 33
#define BTN_GPIN 14
#define BTN_YPIN 12
#define BTN_BPIN 13

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int btn_green, btn_yellow, btn_blue, btn_mine;
int contador, valor = 0;
int cursor = 85;
int digito = 1;

const char* ssid = "Wokwi-GUEST";
const char* password = "";

// Routes
const String url_mine = "https://alfa2tr-blockchain-cq532hd0u-matheus1714.vercel.app/mine_block";

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

/* ==============================================================
-------- Função para mostrar mensagem de boas-vindas ao usuário
============================================================== */
void msg_inicial(){
  display.clearDisplay();

  display.setTextSize(1,2);
  display.setTextColor(WHITE);
  
  display.setCursor(40, 0);
  display.println("ALFA2-TR");

  display.setCursor(20, 20);
  display.println("Seja bem-vindo!");
  display.display();

  delay(1500);
}

/* ==============================================================
-------- Função para mostrar cabeçalho do display
============================================================== */
void msg_id(){
  display.clearDisplay();
    
  display.setCursor(40, 0);
  display.println("ALFA2-TR");

  display.setCursor(20, 20);
  display.println("ID Aluno:");
  display.display();
}

/* ==============================================================
-------- Função para botões de ajuste do ID dos alunos
============================================================== */
void botoes_digitos(){
  if (btn_green == LOW){
    if(valor >= 9)
      valor = 0;
      else
        valor ++;
    msg_id();
    display.setCursor(cursor, 20);
    display.println(valor);
    display.display();
  }
  
  else if (btn_yellow == LOW){
    if(valor <= 0)
      valor = 9;
      else
        valor --;
    msg_id();
    display.setCursor(cursor, 20);
    display.println(valor);
    display.display();
  }
}

/* ==============================================================
-------- Função para botão que simula gravação do áudio
============================================================== */
void botao_gravacao(){
  if(btn_blue == LOW){
    display.setCursor(20, 40);
    display.println("Audio...");
    display.display();
    delay(2000);
    display.setCursor(70, 40);
    display.println("gravado!");
    display.display(); 
  }
}

/* ==============================================================
-------- Função para minerar block
============================================================== */
void botao_minere(){
  if(btn_mine == LOW){
    char* id_aluno = "3412312";

    display.clearDisplay();
    display.setCursor(20, 40);
    display.println("Minerando...");
    display.display();
    delay(2000);

    HTTPClient http;
    http.useHTTP10(true);
    http.begin(url_mine);
    http.GET();
    String result = http.getString();

    DynamicJsonDocument doc(2048);
    DeserializationError error = deserializeJson(doc, result);

    // Test if parsing succeeds.
    if (error) {
      Serial.print("deserializeJson() failed: ");
      Serial.println(error.c_str());
    }

    http.end();

    display.clearDisplay();
    display.setCursor(20, 40);
    display.println("Minerado ");
    display.display();

    delay(2000);
  }
}

/* ===========================
-------- Função setup -------- 
============================*/
void setup() {
  Serial.begin(115200);

  pinMode(BTN_GPIN,INPUT_PULLUP);
  pinMode(BTN_YPIN,INPUT_PULLUP);
  pinMode(BTN_BPIN,INPUT_PULLUP);
  pinMode(BTN_CPIN,INPUT_PULLUP);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(500); // Espera antes de aparecer a mensagem inicial

  msg_inicial();
  msg_id();

  WiFi.begin(ssid, password, 6);

  Serial.println(WiFi.localIP());
}

/* ===========================
-------- Função loop --------- 
============================*/
void loop() {
  btn_green = digitalRead(BTN_GPIN);
  btn_yellow = digitalRead(BTN_YPIN);
  btn_blue = digitalRead(BTN_BPIN);
  btn_mine = digitalRead(BTN_CPIN);

  botoes_digitos();
  botao_gravacao();
  botao_minere();
}