#ifndef LED_H
#define LED_H

#include <stdint.h>
#include <stdbool.h>

/*
 * led.h — WS2812B NeoPixel status indicator driver (Issue #193)
 *
 * Hardware: TIM3_CH1 PWM on PB4 at 800 kHz (1.25 µs per bit).
 * Controls an 8-LED ring with state-based animations:
 *   - Boot: Blue chase (startup sequence)
 *   - Armed: Solid green
 *   - Error: Red blinking (visual alert)
 *   - Low Battery: Yellow pulsing (warning)
 *   - Charging: Green breathing (soft indication)
 *   - E-Stop: Red strobe (immediate action required)
 *
 * State transitions are non-blocking via a 1 ms timer callback (led_tick).
 * Each state defines its own animation envelope: color, timing, and brightness.
 *
 * WS2812 protocol (NRZ):
 *   - Bit "0": High 350 ns, Low 800 ns (1.25 µs total)
 *   - Bit "1": High 700 ns, Low 600 ns (1.25 µs total)
 *   - Reset: Low > 50 µs
 *
 * PWM-based implementation via DMA:
 *   - 10 levels: [350 ns, 400, 450, 500, 550, 600, 650, 700, 750, 800]
 *   - Bit "0" → High 350-400 ns  Bit "1" → High 650-800 ns
 *   - Each bit requires one PWM cycle; 24 bits/LED × 8 LEDs = 192 cycles
 *   - DMA rings through buffer, auto-reloads on update events
 */

/* LED state enumeration */
typedef enum {
    LED_STATE_BOOT       = 0,  /* Blue chase (startup) */
    LED_STATE_ARMED      = 1,  /* Solid green */
    LED_STATE_ERROR      = 2,  /* Red blinking */
    LED_STATE_LOW_BATT   = 3,  /* Yellow pulsing */
    LED_STATE_CHARGING   = 4,  /* Green breathing */
    LED_STATE_ESTOP      = 5,  /* Red strobe */
    LED_STATE_COUNT
} LEDState;

/* RGB color (8-bit per channel) */
typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
} RGBColor;

/*
 * led_init()
 *
 * Configure TIM3_CH1 PWM on PB4 at 800 kHz, set up DMA for bit streaming,
 * and initialize the LED buffer. Call once at startup, after buzzer_init()
 * but before the main loop.
 */
void led_init(void);

/*
 * led_set_state(state)
 *
 * Change the LED display state. The animation runs non-blocking via led_tick().
 * Valid states: LED_STATE_BOOT, LED_STATE_ARMED, LED_STATE_ERROR, etc.
 */
void led_set_state(LEDState state);

/*
 * led_get_state()
 *
 * Return the current LED state.
 */
LEDState led_get_state(void);

/*
 * led_set_color(r, g, b)
 *
 * Manually set the LED ring to a solid color. Overrides the current state
 * animation until led_set_state() is called again.
 */
void led_set_color(uint8_t r, uint8_t g, uint8_t b);

/*
 * led_tick(now_ms)
 *
 * Advance animation state machine. Must be called every 1 ms from the main loop.
 * Handles state-specific animations: chase timing, pulse envelope, strobe phase, etc.
 * Updates the DMA buffer with new LED values without blocking.
 */
void led_tick(uint32_t now_ms);

/*
 * led_is_animating()
 *
 * Returns true if the current state is actively animating (e.g., chase, pulse, strobe).
 * Returns false for static states (armed, error solid).
 */
bool led_is_animating(void);

#endif /* LED_H */
