#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "hal.h"
#include "timer.h"
#include "wait.h"
#include "printf.h"
#include "backlight.h"
#include "matrix.h"


/* Clueboard 1%
 *
 * Single switch connected to A1 and GND.
 *
 *     col: { GND }
 *     row: { PA1 }
 */
/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static bool debouncing = false;
static uint16_t debouncing_time = 0;


void matrix_init(void) {
    printf("matrix init\n");

    memset(matrix, 0, MATRIX_ROWS);
    memset(matrix_debouncing, 0, MATRIX_ROWS);

    /* LED Init
     */
    palSetPad(GPIOB, 5);
    palSetPad(GPIOB, 3);
    palSetPad(GPIOA, 2);

    /* Speaker Init
     */
    palClearPad(GPIOA, 7);
}

uint8_t matrix_scan(void) {
    matrix_row_t data = 0;

    // read switch data: { PA1 }
    data = ~(palReadPad(GPIOA, 1));

    if (matrix_debouncing[0] != data) {
        matrix_debouncing[0] = data;
        debouncing = true;
        debouncing_time = timer_read();
    }

    if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
        matrix[0] = matrix_debouncing[0];
        debouncing = false;
    }

    return 1;
}

bool matrix_is_on(uint8_t row, uint8_t col) {
    return (matrix[row] & (1<<col));
}

matrix_row_t matrix_get_row(uint8_t row) {
    return matrix[row];
}

void matrix_print(void) {
    printf("\nr/c 01234567\n");
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
        printf("%X0: ", row);
        matrix_row_t data = matrix_get_row(row);
        for (int col = 0; col < MATRIX_COLS; col++) {
            if (data & (1<<col))
                printf("1");
            else
                printf("0");
        }
        printf("\n");
    }
}
