// main.cpp

#include "mbed.h"
#include "background_dark_inverted.h"
#include <vector>
#include <string>

#define TARGET_TX_PIN USBTX
#define TARGET_RX_PIN USBRX
// #define BAUD_RATE 1843200
// #define BAUD_RATE 921600
// #define BAUD_RATE 460800
#define BAUD_RATE 115200

static BufferedSerial serial_port(TARGET_TX_PIN, TARGET_RX_PIN, BAUD_RATE);

FileHandle *mbed::mbed_override_console(int fd)
{
    return &serial_port;
}

DigitalOut led(LED1);

#define BUFFER_SIZE 64
static char rx_buffer[BUFFER_SIZE];

// ASCII fart background
void draw_mask(const char *unused_filename, int shift, const char *text = nullptr) {
    const int view_width = 50; // visible width
    const int view_height = 24;

    // Terminal clear + home
    printf("\033[2J\033[H");

    for (int i = 0; i < view_height && i < BACKGROUND_DARK_INVERTED_LINES; i++) {
        const char *row = BACKGROUND_DARK_INVERTED[i];
        int width = strlen(row);
        if (width == 0) {
            printf("\r\n");
            continue;
        }

        int start = shift % width;

        // Print visible window (wrap around)
        for (int j = 0; j < view_width; j++) {
            char c = row[(start + j) % width];
            printf("%c", c);
        }
        printf("\r\n");
    }

    if (text && text[0] != '\0')
        printf("\r\n[RX] %s\r\n", text);

    fflush(stdout);
}

int main(void) {
    serial_port.set_format(8, BufferedSerial::None, 1);
    printf("Baud: %d, Format: 8-N-1\r\n", BAUD_RATE);

    int shift = 0;
    char message[BUFFER_SIZE] = {0};
    bool message_active = false;
    Timer msg_timer;
    Timer anim_timer;
    msg_timer.start();
    anim_timer.start();

    const char *bg_file = "background_dark_inverted.txt";

    bool need_redraw = false;

    while (true) {
        if (serial_port.readable()) {
            memset(rx_buffer, 0, sizeof(rx_buffer));
            ssize_t num = serial_port.read(rx_buffer, sizeof(rx_buffer) - 1);
            if (num > 0) {
                led = !led;

                strncpy(message, rx_buffer, sizeof(message) - 1);
                message_active = true;
                msg_timer.reset();

		need_redraw = true;
            }
        }

        if (message_active && msg_timer.elapsed_time() > 1s) {
            message_active = false;
            memset(message, 0, sizeof(message));

	    need_redraw = true;
        }

        // if (message_active && msg_timer.elapsed_time() > 100ms) {
	//	shift = (shift + 1) % 8;

        // }
        if (anim_timer.elapsed_time() >= 900ms) {
	    shift++;
            anim_timer.reset();

	    need_redraw = true;
        }
	if (need_redraw) {
	    draw_mask(bg_file, shift, message_active ? message : nullptr);
	    need_redraw = false;
	    ThisThread::sleep_for(150ms);
	}
        ThisThread::sleep_for(20ms);
    }
}
