/*############################################################################
  # Codigo criado por: Mario Parente
  # Em desenvolvimento
  # Data: 09/02/2024
  # Detalhes do projeto: v0.2.3
  # Descrição: Simulador de dados para RPG
  #
  #Updade: v0.2.3 - Inclução de funções para gerar e atualizar histocico de resultado
  #                
  #
  ############################################################################*/
// #include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

char Seta = 0;
int S_Menu = 0;
int resultado = 0;

#define B_Sair 14
#define B_Mudar 13
#define B_Entrar 12

const int M_lista = 16;
String Lista [M_lista];
int num_lista = 0;
char Converte[3];
String D_selecionado = "";
Adafruit_SSD1306 display(128, 64, &Wire, -1);

void setup() {
  pinMode(B_Sair, INPUT_PULLUP);
  pinMode(B_Mudar, INPUT_PULLUP);
  pinMode(B_Entrar, INPUT_PULLUP);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  delay(500); 
  // randomSeed(analogRead(A0));  //Comente caso utilize ESP, devido ao aterramento do A0
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);  //configura o display para ativar 'branco' no pixel
  display.setTextSize(1); //tamanho do texto
  display.print(F("..Simulador de Dado.."));
  display.display();
  historico();
  Imprime_Menu();
}

void loop() { 
  S_Menu = 0; 
  display.display();
  delay(10);
  while (digitalRead(B_Mudar) == HIGH && digitalRead(B_Entrar) == HIGH) {
    //Aguardo algum botão ser pressionado.
  }
  if (digitalRead(B_Mudar) == LOW){
    delay(10);
    Escolha_menu();
  }
  else if (digitalRead(B_Entrar) == LOW){
    delay(10);
    while (digitalRead(B_Entrar) == LOW) {
      //Aguardo o botão ser solto.
    } 
    Entra_menu();
  }
}

int proximaPosicaoLivre() {
  for (int i = 0; i < 16; i++) {
    if (Lista[i] == NULL) {
      return i;
    }
  }
  return -1; // Retorna -1 se não houver posições livres
}

void historico(){
  display.drawRect(56,22,72,39,1); //cria um retalgulo preto
  display.setCursor(67,14);
  display.print(F("Historico"));
  display.drawPixel(93,14,1);
  display.drawPixel(94,13,1);
  display.display();
}

void historico_resultado(){
  display.setTextColor(WHITE);
  for (int i=0; i < 4; i++){
    int Linha = 25+(i*8);
    int L = i*4;
    display.setCursor(58,Linha);
    if (Lista[L] != NULL){
      display.print(Lista[L]);
      display.setCursor(display.getCursorX()-2,display.getCursorY());
      display.print(":");
      display.setCursor(display.getCursorX()-5,display.getCursorY());
      display.print(":");
      display.setCursor(display.getCursorX()-2,display.getCursorY());
    }
    if (Lista[L+1] != NULL) {
      display.print(Lista[L+1]);
    }
    display.setCursor(93,Linha);
    if (Lista[L+2] != NULL) {
      display.print(Lista[L+2]);
      display.setCursor(display.getCursorX()-2,display.getCursorY());
      display.print(":");
      display.setCursor(display.getCursorX()-5,display.getCursorY());
      display.print(":");
      display.setCursor(display.getCursorX()-2,display.getCursorY());
    }
    if (Lista[L+3] != NULL) {
      display.print(Lista[L+3]);
    }
  }
  display.setTextColor(WHITE,BLACK);
  display.display();  
}

void Limpa_Direita(){
  display.fillRect(57,23,70,37,0); //cria um retalgulo preto
  historico();
  display.display();
}

void Limpa_Esquerda(){
  display.fillRect(0,10,55,63,0); //cria um retalgulo preto
  display.display();
}

void Imprime_Menu(){
  display.setCursor(8,20);
  display.print(F("D2"));
  display.setCursor(8,30);
  display.print(F("D4"));
  display.setCursor(8,40);
  display.print(F("D6"));
  display.setCursor(8,50);
  display.print(F("D8"));
  display.setCursor(32,20);
  display.print(F("D10"));
  display.setCursor(32,30);
  display.print(F("D12"));
  display.setCursor(32,40);
  display.print(F("D20"));
  display.setCursor(32,50);
  display.print(F("D100"));
  display.setCursor(1, 20);
  display.write(26);
  display.display();
  Seta = 0;
  delay(10);
}

void Escolha_menu(){
  // Limpa ultima posição da seta ->
  display.setCursor(display.getCursorX()-6,display.getCursorY());  
  display.print(F(" "));
  Seta ++;
  if (Seta > 7){
    Seta = 0;
  }
  switch (Seta) {
    case 0:
      display.setCursor(1,20);
    break;
    case 1:
      display.setCursor(1,30);
    break;
    case 2:
      display.setCursor(1,40);
    break;
    case 3:
      display.setCursor(1,50);
    break;
    case 4:
      display.setCursor(25,20);
    break;
    case 5:
      display.setCursor(25,30);
    break;
    case 6:
      display.setCursor(25,40);
    break;
    case 7:
      display.setCursor(25,50);
    break;
  }
  display.write(26);
  display.display();
  delay(10);
}

void Entra_menu(){
  Limpa_Esquerda();
  delay(10);
  switch (Seta) {
    case 0:
      D2();
    break;
    case 1:
      D4();
    break;
    case 2:
      D6();
    break;
    case 3:
      D8();
    break;
    case 4:
      D10();
    break;
    case 5:
      D12();
    break;
    case 6:
      D20();
    break;
    case 7:
      D100();
    break;
  }

  delay(10);
    int i = proximaPosicaoLivre();
    if (i == -1){
      for (i = 0; i < M_lista ; i++) {
        Lista[i] = Lista[i + 2];
      }
    Limpa_Direita();
    i = 14;    
    }
    delay(10);
    Lista[i] = D_selecionado;
    sprintf(Converte, "%d", resultado);
    Lista[i+1] = Converte;
    historico_resultado();
    while (S_Menu == 0){
    //Aguardo algum botão ser pressionado.
    if (digitalRead(B_Entrar) == LOW){
      delay(10);
      while (digitalRead(B_Entrar) == LOW) {
        //Aguardo o botão ser solto.
      }
      delay(10);
      Entra_menu();
    }
    if (digitalRead(B_Sair) == LOW){
     while (digitalRead(B_Sair) == LOW) {
        //Aguardo o botão ser solto.
      }
      delay(10);
      S_Menu = 1;
      Limpa_Esquerda();
      Imprime_Menu();
    }
  }
}

void Em_criacao(){
  Limpa_Esquerda();
  display.drawRect(0,33,127,11,1);
  display.setCursor(12 ,35);  
  display.print(F("Em Desenvolvimento"));
  display.display();
  delay(10);
  while (S_Menu == 0){
    if (digitalRead(B_Sair) == LOW){
     while (digitalRead(B_Sair) == LOW) {
        //Aguardo o botão ser solto.
      }
      delay(10);
      S_Menu = 1;
      display.fillRect(00,33,127,11,0);
      Imprime_Menu();
    }
  }
}

void D2() { // Em Teste
  D_selecionado = " D2";
  resultado = random(1, 3); // Gera um número aleatório entre 1 e 2
  display.setTextSize(2);
  display.setCursor(23, 35); // Ajuste conforme necessário para centralizar o número
  display.print(resultado);
  display.setTextSize(1); // Restaura o tamanho do texto para o padrão
  display.display();
}

void D4(){  // Em Teste
  D_selecionado = " D4";
  resultado = random(1, 5);
  // Desenhar o triângulo
  display.drawTriangle(8,57,48,57,27,20,1);  
  display.setTextSize(2);
  display.setCursor(23,37); 
  display.print(resultado);
  display.setTextSize(1);
  display.display();
}

void D6(){  // Em Teste
  D_selecionado = " D6";
  resultado = random(1, 7);
  display.drawRoundRect(5, 14, 50, 50, 5, 1);
  // Ajustes para centralizar
  int pontoSize = 4;  // Tamanho dos pontos
  int offsetX = 5;    // Deslocamento horizontal
  int offsetY = 14;   // Deslocamento vertical
  // Desenhar pontos com base no número sorteado
  switch (resultado) {
    case 1:
      display.fillCircle(offsetX + 25, offsetY + 25, pontoSize, 1);
      break;
    case 2:
      display.fillCircle(offsetX + 15, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 35, pontoSize, 1);
      break;
    case 3:
      display.fillCircle(offsetX + 15, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 25, offsetY + 25, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 35, pontoSize, 1);
      break;
    case 4:
      display.fillCircle(offsetX + 15, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 15, offsetY + 35, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 35, pontoSize, 1);
      break;
    case 5:
      display.fillCircle(offsetX + 15, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 25, offsetY + 25, pontoSize, 1);
      display.fillCircle(offsetX + 15, offsetY + 35, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 35, pontoSize, 1);
      break;
    case 6:
      display.fillCircle(offsetX + 15, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 15, pontoSize, 1);
      display.fillCircle(offsetX + 15, offsetY + 25, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 25, pontoSize, 1);
      display.fillCircle(offsetX + 15, offsetY + 35, pontoSize, 1);
      display.fillCircle(offsetX + 35, offsetY + 35, pontoSize, 1);
      break;
  }
  display.display();
}

void D8(){   // Em Teste
  D_selecionado = " D8";
  resultado = random(1, 9);
  display.fillTriangle( 8,50,51,50,30,63,1);
  display.fillTriangle(30,13,48,25,51,50,1);
  display.fillTriangle( 8,50,11,25,30,13,1);
  display.setTextSize(2);
  display.setCursor(25,31); 
  display.print(resultado);
  display.setTextSize(1);
  display.display();
}

void D10(){ // Em Teste
  D_selecionado = "D10";
  resultado = random(1, 11);
  display.drawLine(29,13,53,33,1);
  display.drawLine( 4,33,29,13,1);
  display.drawLine(54,44,29,63,1);
  display.drawLine(29,63, 3,44,1);
  display.drawLine(53,33,54,44,1);
  display.drawLine( 4,33, 3,44,1);
  display.drawLine( 3,44,12,44,1);
  display.drawLine(45,44,54,44,1);
  display.drawLine(12,44,29,53,1);
  display.drawLine(45,44,29,53,1);
  display.drawLine(12,44,29,13,1);
  display.drawLine(29,13,45,44,1);
  display.setTextSize(2);
  if (resultado < 10 ){    
    display.setCursor(24,33);
    display.print(resultado);
  }
  else{
    display.setTextColor(1);
    display.setCursor(19,33);
    display.print(1);
    display.setCursor(28,33);
    display.print(0);
    display.setTextColor(WHITE,BLACK);
  }
  display.setTextSize(1);  
  display.display();
}

void D12() { // Em Teste
  D_selecionado = "D12";
  resultado = random(1, 13); // Gera um número aleatório entre 1 e 12

  display.setTextSize(2);
  display.setCursor(20, 35); // Ajuste conforme necessário para centralizar o número
  display.print(resultado);
  display.setTextSize(1); // Restaura o tamanho do texto para o padrão
  display.display();
}

void D20() { // Em Teste
  D_selecionado = "D20";
  resultado = random(1, 21); // Gera um número aleatório entre 1 e 20

  display.setTextSize(2);
  display.setCursor(20, 35); // Ajuste conforme necessário para centralizar o número
  display.print(resultado);
  display.setTextSize(1); // Restaura o tamanho do texto para o padrão
  display.display();
}

void D100() { // Em Teste
  D_selecionado = "DC";
  resultado = random(1, 101); // Gera um número aleatório entre 1 e 100

  display.setTextSize(2);
  display.setCursor(20, 35); // Ajuste conforme necessário para centralizar o número
  display.print(resultado);
  display.setTextSize(1); // Restaura o tamanho do texto para o padrão
  display.display();
}