#define led_B 13
#define led_R 12
#define btn_B 14
#define btn_R 27
#define led_Y 26
#define led_G 25
#define btn_Y 33
#define btn_G 32
#define led_W 2
#define T_RODADAS 5

bool deBouncing(bool estado, uint8_t pin);
void ChecarBotoes();
void AcenderLeds();
void Ganhou();
void Perdeu();

int vetor_leds[T_RODADAS];
int vetor_pressionado[T_RODADAS];
int contador_cliques;
int rodada;
bool flag_btn_B = false;
bool flag_btn_R = false;
bool flag_btn_Y = false;
bool flag_btn_G = false;
bool flag_inicio;

void setup() {
  Serial.begin(115200);
  pinMode(btn_B, INPUT_PULLUP);
  pinMode(btn_R, INPUT_PULLUP);
  pinMode(led_B, OUTPUT);
  pinMode(led_R, OUTPUT);
  pinMode(btn_Y, INPUT_PULLUP);
  pinMode(btn_G, INPUT_PULLUP);
  pinMode(led_Y, OUTPUT);
  pinMode(led_G, OUTPUT);
  pinMode(led_W, OUTPUT);

  for(int i = 0; i < T_RODADAS; i++) {
    vetor_leds[i] = random(0, 4);
    Serial.println(vetor_leds[i]);
  }

  rodada = 1;
  flag_inicio = true;
}

void loop() {
  if(flag_inicio) {
    delay(300);
    AcenderLeds();
  }
  ChecarBotoes();

  if (contador_cliques == rodada) {
    rodada++;
    if (rodada == T_RODADAS+1) {
      Ganhou();
    }
    contador_cliques = 0;
    flag_inicio = true;
  }
}

void AcenderLeds() {
    for (int i = 0; i < rodada; i++) {
      if (vetor_leds[i] == 0) {
        digitalWrite(led_R, HIGH);
      } else if (vetor_leds[i] == 1) {
        digitalWrite(led_B, HIGH);
      } else if (vetor_leds[i] == 2) {
        digitalWrite(led_Y, HIGH);
      } else {
        digitalWrite(led_G, HIGH);
      }
      delay(700 - i * 120);
      digitalWrite(led_R, LOW);
      digitalWrite(led_B, LOW);
      digitalWrite(led_Y, LOW);
      digitalWrite(led_G, LOW);
      if (i < rodada-1) {
        Serial.println("Fiz um delay");
        delay(475 - i * 75);
      }
      flag_inicio = false;
    }
}

void ChecarBotoes() {
  //Botão Vermelho
  if (deBouncing(flag_btn_R, btn_R) == false) {
    flag_btn_R = true;
  }
  if (deBouncing(flag_btn_R, btn_R) == true && flag_btn_R == true) {
    Serial.println("Soltei o vermelho.");
    vetor_pressionado[contador_cliques] = 0;
    if (vetor_pressionado[contador_cliques] != vetor_leds[contador_cliques]) {
      Perdeu();
    } else {
      digitalWrite(led_W, HIGH);
      digitalWrite(led_R, HIGH);
      delay(50);
      digitalWrite(led_W, LOW);
      digitalWrite(led_R, LOW);
    }
    contador_cliques++;
    flag_btn_R = false;
  }
  //Botão Azul
  if (deBouncing(flag_btn_B, btn_B) == false) {
    flag_btn_B = true;
  }
  if (deBouncing(flag_btn_B, btn_B) == true && flag_btn_B == true) {
    Serial.println("Soltei o azul.");
    vetor_pressionado[contador_cliques] = 1;
    if (vetor_pressionado[contador_cliques] != vetor_leds[contador_cliques]) {
      Perdeu();
    } else {
      digitalWrite(led_W, HIGH);
      digitalWrite(led_B, HIGH);
      delay(50);
      digitalWrite(led_W, LOW);
      digitalWrite(led_B, LOW);
    }
    contador_cliques++;
    flag_btn_B = false;
  }
  //Botão Amarelo
  if (deBouncing(flag_btn_Y, btn_Y) == false) {
    flag_btn_Y = true;
  }
  if (deBouncing(flag_btn_Y, btn_Y) == true && flag_btn_Y == true) {
    Serial.println("Soltei o amarelo.");
    vetor_pressionado[contador_cliques] = 2;
    if (vetor_pressionado[contador_cliques] != vetor_leds[contador_cliques]) {
      Perdeu();
    } else {
      digitalWrite(led_W, HIGH);
      digitalWrite(led_Y, HIGH);
      delay(50);
      digitalWrite(led_W, LOW);
      digitalWrite(led_Y, LOW);
    }
    contador_cliques++;
    flag_btn_Y = false;
  }
  //Botão Verde
  if (deBouncing(flag_btn_G, btn_G) == false) {
    flag_btn_G = true;
  }
  if (deBouncing(flag_btn_G, btn_G) == true && flag_btn_G == true) {
    Serial.println("Soltei o verde.");
    vetor_pressionado[contador_cliques] = 3;
    if (vetor_pressionado[contador_cliques] != vetor_leds[contador_cliques]) {
      Perdeu();
    } else {
      digitalWrite(led_W, HIGH);
      digitalWrite(led_G, HIGH);
      delay(50);
      digitalWrite(led_W, LOW);
      digitalWrite(led_G, LOW);
    }
    contador_cliques++;
    flag_btn_G = false;
  }
}

void Ganhou() {
  Serial.println("Ganhou!");
  for (;;) {
    digitalWrite(led_B, !digitalRead(led_B));
    delay(150);
    digitalWrite(led_R, !digitalRead(led_R));
    delay(150);
    digitalWrite(led_Y, !digitalRead(led_Y));
    delay(150);
    digitalWrite(led_G, !digitalRead(led_G));
    delay(150);
  }
}

void Perdeu() {
  Serial.println("Perdeu!");
  for (;;) {
    digitalWrite(led_B, !digitalRead(led_B));
    digitalWrite(led_R, !digitalRead(led_R));
    digitalWrite(led_Y, !digitalRead(led_Y));
    digitalWrite(led_G, !digitalRead(led_G));
    digitalWrite(led_W, !digitalRead(led_W));
    delay(50);
  }
}

bool deBouncing(bool estado, uint8_t pin) {
  bool estadoAtual = digitalRead(pin);
  if (estadoAtual != estado) {
    delay(7);
    estadoAtual = digitalRead(pin);
  }
  return estadoAtual;
}