#include "pico/stdlib.h"
#include "hardware/gpio.h"

#define UNLOCK_SEQUENCE 0b1101 // Represents Btn2-Btn3-Btn1-Btn3 sequence
#define ADMIN_SEQUENCE 0b1010  // Represents Btn3-Btn1 sequence

#define E_BTN1 0
#define S_BTN2 1
#define W_BTN3 2
#define N_BTN4 3
#define LED_0 4
#define LED_1 5
#define LED_2 6
#define LED_3 7
#define ALARM_LED 8
#define UNLOCKED_LED 9

bool is_locked = true;
bool alarm_triggered = false;

void update_leds() {
    gpio_put(UNLOCKED_LED, !is_locked);
}

bool is_button_pressed(uint pin) {
    return gpio_get(pin) == 0;
}

void check_sequence(uint8_t sequence) {
    static uint8_t input_sequence = 0;
    
    if (sequence == UNLOCK_SEQUENCE) {
        if (!is_locked) {
            printf("Lock closed.\n");
            is_locked = true;
            update_leds();
        } else {
            printf("UNLOCKED! Lock open.\n");
            is_locked = false;
            update_leds();
        }
        input_sequence = 0;
        return;
    }
    
    input_sequence = (input_sequence << 2) | sequence;

    if (input_sequence == ADMIN_SEQUENCE && alarm_triggered) {
        printf("Alarm deactivated. Resetting...\n");
        alarm_triggered = false;
        gpio_put(ALARM_LED, false); // Turn off alarm LED
        input_sequence = 0; // Reset input sequence
        return;
    }
    
    if (input_sequence != UNLOCK_SEQUENCE && input_sequence != ADMIN_SEQUENCE) {
        // If four buttons pressed and not an unlock or admin sequence, trigger alarm
        if (input_sequence != 0b1111) {
            alarm_triggered = true;
            gpio_put(ALARM_LED, true); // Turn on alarm LED
            printf("ALARM triggered!\n");
            // Your alarm signal logic here
            input_sequence = 0; // Reset input sequence
        }
    }
}

void button_pressed(uint pin) {
    switch (pin) {
        case E_BTN1:
            gpio_put(LED_0, true);
            check_sequence(E_BTN1);
            gpio_put(LED_0, false);
            break;
        case S_BTN2:
            gpio_put(LED_1, true);
            check_sequence(S_BTN2);
            gpio_put(LED_1, false);
            break;
        case W_BTN3:
            gpio_put(LED_2, true);
            check_sequence(W_BTN3);
            gpio_put(LED_2, false);
            break;
        case N_BTN4:
            gpio_put(LED_3, true);
            check_sequence(N_BTN4);
            gpio_put(LED_3, false);
            break;
        default:
            break;
    }
}

int main() {
    stdio_init_all();
    gpio_init_mask((1u << E_BTN1) | (1u << S_BTN2) | (1u << W_BTN3) | (1u << N_BTN4) |
                   (1u << LED_0) | (1u << LED_1) | (1u << LED_2) | (1u << LED_3) |
                   (1u << ALARM_LED) | (1u << UNLOCKED_LED));

    gpio_set_dir(E_BTN1, GPIO_IN);
    gpio_set_dir(S_BTN2, GPIO_IN);
    gpio_set_dir(W_BTN3, GPIO_IN);
    gpio_set_dir(N_BTN4, GPIO_IN);

    gpio_set_dir(LED_0, GPIO_OUT);
    gpio_set_dir(LED_1, GPIO_OUT);
    gpio_set_dir(LED_2, GPIO_OUT);
    gpio_set_dir(LED_3, GPIO_OUT);
    gpio_set_dir(ALARM_LED, GPIO_OUT);
    gpio_set_dir(UNLOCKED_LED, GPIO_OUT);

    // Initially, the lock is closed and the locked LED is ON
    gpio_put(UNLOCKED_LED, false);
    gpio_put(ALARM_LED, false);

    while (1) {
        if (is_locked || alarm_triggered) {
            if (is_button_pressed(E_BTN1)) {
                button_pressed(E_BTN1);
                sleep_ms(200); // Debounce delay (adjust as needed)
            }
            if (is_button_pressed(S_BTN2)) {
                button_pressed(S_BTN2);
                sleep_ms(200); // Debounce delay (adjust as needed)
            }
            if (is_button_pressed(W_BTN3)) {
                button_pressed(W_BTN3);
                sleep_ms(200); // Debounce delay (adjust as needed)
            }
            if (is_button_pressed(N_BTN4)) {
                button_pressed(N_BTN4);
                sleep_ms(200); // Debounce delay (adjust as needed)
            }
        } else {
            printf("Press any key to close the lock.\n");
            // Read button inputs here and set is_locked to true when any button is pressed
            // For example: if (any_button_pressed) is_locked = true;
        }
    }
    
    return 0;
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT