#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

#define BUZZER 0
#define PEDESTRE 1
#define PARE 2
#define ATENCAO 3
#define SIGA 4
#define BOTOEIRA 5
#define MIL 1000

// controle de ejmissão dos led por tempo
void pisca_temporizado(int segundos, int pino) {
  gpio_put(pino, 1);
  sleep_ms(segundos * MIL);
  gpio_put(pino, 0);
}

// emissão ddo sinal sonoro com intermitência
void buzzer_temporizado(void) {
  for (int ciclos = 0; ciclos < 10; ciclos++) {
    gpio_put(BUZZER, 1);
    sleep_ms(1 * MIL);
    gpio_put(BUZZER, 0);
    sleep_ms(500);
  }
}

// define o estado de todos os atuadores
void estado_atuadores(int estado) {
  gpio_put(BUZZER, estado);
  gpio_put(PEDESTRE, estado);
  gpio_put(SIGA, estado);
  gpio_put(ATENCAO, estado);
  gpio_put(PARE, estado);
}

void sequencia_pedestres(uint _gpio, uint32_t _event_mask) {
  // deabilita o botão
  gpio_set_irq_enabled(BOTOEIRA, GPIO_IRQ_EDGE_RISE, false);
  // zera todos os atuadores
  estado_atuadores(0);
  pisca_temporizado(5, ATENCAO);
  gpio_put(PARE, 1);
  gpio_put(PEDESTRE, 1);
  buzzer_temporizado();
  // habilita o botão
  gpio_set_irq_enabled(BOTOEIRA, GPIO_IRQ_EDGE_RISE, true);
  // zera todos os atuadores
  estado_atuadores(0);
  // termina com verde para que a sequencia normal do sinal seja mantida
  // como o ultimo estado foi PARE, por conseguinte vem o SIGA
  pisca_temporizado(8, SIGA);
}

// funcionamento normal do sinal
void sequencia_normal(void) {
  // zera todos os atuadores
  estado_atuadores(0);
  pisca_temporizado(2, ATENCAO);
  pisca_temporizado(10, PARE);
  pisca_temporizado(8, SIGA);
}

int main() {
  stdio_init_all();

  gpio_init(BOTOEIRA);
  gpio_set_dir(BOTOEIRA, GPIO_IN);
  gpio_init(BUZZER);
  gpio_set_dir(BUZZER, GPIO_OUT);
  gpio_init(PARE);
  gpio_set_dir(PARE, GPIO_OUT);
  gpio_init(ATENCAO);
  gpio_set_dir(ATENCAO, GPIO_OUT);
  gpio_init(SIGA);
  gpio_set_dir(SIGA, GPIO_OUT);
  gpio_init(PEDESTRE);
  gpio_set_dir(PEDESTRE, GPIO_OUT);

  gpio_set_irq_enabled_with_callback(BOTOEIRA, GPIO_IRQ_EDGE_RISE, true, &sequencia_pedestres);

  while (1) {
    sequencia_normal();
  }
}