#include "he_logic.h"
#include "print.h"
#include <string.h>

he_switch_t he_switches[MATRIX_ROWS][MATRIX_COLS];

uint16_t global_actuation_point = 500;
uint16_t global_rt_sensitivity = 150;

void he_logic_init(void) {
    memset(he_switches, 0, sizeof(he_switches));
    // Set some defaults
    for(int r = 0; r < MATRIX_ROWS; r++) {
        for(int c = 0; c < MATRIX_COLS; c++) {
            he_switches[r][c].lowest_val = 4095;
        }
    }
}

void he_logic_process_switch(uint8_t row, uint8_t col, uint16_t adc_val) {
    he_switch_t *sw = &he_switches[row][col];
    
    // Smooth out noise if needed (skipped for speed)
    sw->current_val = adc_val;

    // Track baseline (lowest value seen when not pressed, roughly)
    if (adc_val < sw->lowest_val) {
        sw->lowest_val = adc_val;
    }
    if (adc_val > sw->highest_val) {
        sw->highest_val = adc_val;
    }

    // A simple Hall Effect logic: value goes up as switch is pressed down.
    // Static actuation point
    uint16_t travel = (adc_val > sw->lowest_val) ? (adc_val - sw->lowest_val) : 0;
    
    if (!sw->is_pressed) {
        // Press if travel exceeds global actuation point
        if (travel > global_actuation_point) {
            sw->is_pressed = true;
            sw->highest_val = adc_val; // Reset highest val tracking for RT
        }
    } else {
        // Rapid Trigger release logic
        if (sw->highest_val > adc_val) {
            uint16_t release_delta = sw->highest_val - adc_val;
            if (release_delta > global_rt_sensitivity) {
                sw->is_pressed = false;
                sw->lowest_val = adc_val; // Reset lowest val tracking for RT
            }
        }
        
        // Also release if travel falls below actuation point
        if (travel < global_actuation_point - global_rt_sensitivity) {
            sw->is_pressed = false;
        }
    }
}
