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

#define LED_VERMELHO 28
#define LED_VERDE 27
#define BUZZER_PIN 15
#define SINAL_VERMELHO 20
#define SINAL_AMARELO 19
#define SINAL_VERDE 18
#define BOTAO 16

void buzinar(uint slice_num, uint16_t frequency, uint16_t duration_ms)
{
  pwm_set_wrap(slice_num, 125000000 / frequency);
  pwm_set_gpio_level(BUZZER_PIN, 40000); // Ciclo de trabalho 50%

  // Tocando o som principal
  sleep_ms(duration_ms - 2000); // Beep por (duration_ms - 200) milissegundos

  // Aviso de desligamento (aumenta a frequência nos últimos 200 ms)
  for (int i = 0; i < 10; i++)
  {
    pwm_set_wrap(slice_num, 125000000 / (frequency + (i * 120))); // Aumenta a frequência
    sleep_ms(100); // Pausa curta
  }
  pwm_set_gpio_level(BUZZER_PIN, 0); // Desliga o buzzer
}

void inicia_botao()
{
  gpio_init(BOTAO);
  gpio_set_dir(BOTAO, GPIO_IN);
  gpio_pull_up(BOTAO); //habilita o resistor pull-up, quando precionado vale 0.
}

void inicia_led_carros()
{
  gpio_init(SINAL_VERMELHO);
  gpio_init(SINAL_AMARELO);
  gpio_init(SINAL_VERDE);
  gpio_set_dir(SINAL_VERMELHO, GPIO_OUT);
  gpio_set_dir(SINAL_AMARELO, GPIO_OUT);
  gpio_set_dir(SINAL_VERDE, GPIO_OUT);
}

void inicia_led_pedestre()
{
  gpio_init(LED_VERMELHO);
  gpio_init(LED_VERDE);
  gpio_set_dir(LED_VERMELHO, GPIO_OUT);
  gpio_set_dir(LED_VERDE, GPIO_OUT);
}

void ligar_sinal_vermelho()
{
  gpio_put(SINAL_VERMELHO, 1);
}
void desligar_sinal_vermelho()
{
  gpio_put(SINAL_VERMELHO, 0);
}
void desligar_sinal_amarelo()
{
  gpio_put(SINAL_AMARELO, 0);
}
void ligar_sinal_amarelo()
{
  gpio_put(SINAL_AMARELO, 1);
}
void ligar_sinal_verde()
{
  gpio_put(SINAL_VERDE, 1);
}
void desligar_sinal_verde()
{
  gpio_put(SINAL_VERDE, 0);
}


void ligar_led_vermelho()
{
  gpio_put(LED_VERMELHO, 1);
}
void desligar_led_verde()
{
  gpio_put(LED_VERDE, 0);
}
//void ligar_led_verde(uint slice_num)
void ligar_led_verde()
{
  gpio_put(LED_VERDE, 1);
}
void desligar_led_vermelho()
{
  gpio_put(LED_VERMELHO, 0);
}
void pressionou_botao()
{
  uint slice_num = pwm_gpio_to_slice_num(BUZZER_PIN);
  desligar_led_verde();
  desligar_led_vermelho();
  desligar_sinal_verde();
  desligar_sinal_amarelo();
  desligar_sinal_vermelho();
  ligar_sinal_amarelo();
  ligar_led_vermelho();
  sleep_ms(5000);
  desligar_led_vermelho();
  desligar_sinal_amarelo();
  ligar_sinal_vermelho();
  ligar_led_verde();
  buzinar(slice_num, 2000, 15000);
  sleep_ms(1200);
}

void semaforo_normal()
{
  int valor = gpio_get(BOTAO);
  uint slice_num = pwm_gpio_to_slice_num(BUZZER_PIN);
  desligar_led_verde();
  desligar_sinal_vermelho();
  ligar_sinal_verde();

  ligar_led_vermelho();
  sleep_ms(8000);

  desligar_led_vermelho();
  desligar_sinal_verde();
  ligar_led_vermelho();
  ligar_sinal_amarelo();
  sleep_ms(2000);

  desligar_sinal_amarelo();
  desligar_led_vermelho();
  ligar_sinal_vermelho();
  ligar_led_verde();

  buzinar(slice_num, 2000, 10000);
  sleep_ms(1000);
}



int main() {

  // Inicializa o padrão de entrada/saída da Raspberry Pi Pico
  stdio_init_all();

  inicia_led_pedestre();
  inicia_led_carros();
  inicia_botao();

  // Configura o pino do buzzer como saída PWM
  gpio_set_function(BUZZER_PIN, GPIO_FUNC_PWM);
  uint slice_num = pwm_gpio_to_slice_num(BUZZER_PIN);

  pwm_config config = pwm_get_default_config();
  pwm_init(slice_num, &config, true);

  while (true) {
    int valor = gpio_get(BOTAO);
    printf("O valor de do Botao é: %d \n", valor );

    if (valor == 0)
    {
      pressionou_botao();
    } else {
      semaforo_normal();
    }


  }
}