#ifndef SERVO_H
#define SERVO_H

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

/*
 * servo.h — Pan-tilt servo driver for camera head (Issue #206)
 *
 * Hardware: TIM4 PWM at 50 Hz (20 ms period)
 *   - CH1 (PB6): Pan servo (0-180°)
 *   - CH2 (PB7): Tilt servo (0-180°)
 *
 * Servo pulse mapping:
 *   - 500 µs  → 0°   (full left/down)
 *   - 1500 µs → 90°  (center)
 *   - 2500 µs → 180° (full right/up)
 *
 * Smooth sweeping via servo_sweep() for camera motion.
 */

/* Servo channels */
typedef enum {
    SERVO_PAN  = 0,   /* CH1 (PB6) */
    SERVO_TILT = 1,   /* CH2 (PB7) */
    SERVO_COUNT
} ServoChannel;

/* Servo state */
typedef struct {
    uint16_t current_angle_deg[SERVO_COUNT];   /* Current angle in degrees (0-180) */
    uint16_t target_angle_deg[SERVO_COUNT];    /* Target angle in degrees */
    uint16_t pulse_us[SERVO_COUNT];            /* Pulse width in microseconds (500-2500) */

    /* Sweep state (per-servo) */
    uint32_t sweep_start_ms[SERVO_COUNT];
    uint32_t sweep_duration_ms[SERVO_COUNT];
    uint16_t sweep_start_deg[SERVO_COUNT];
    uint16_t sweep_end_deg[SERVO_COUNT];
    bool     is_sweeping[SERVO_COUNT];
} ServoState;

/*
 * servo_init()
 *
 * Initialize TIM4 PWM on PB6 (CH1, pan) and PB7 (CH2, tilt) at 50 Hz.
 * Centers both servos at 90° (1500 µs). Call once at startup.
 */
void servo_init(void);

/*
 * servo_set_angle(channel, degrees)
 *
 * Set target angle for a servo (0-180°).
 * Immediately updates PWM without motion ramping.
 * Valid channels: SERVO_PAN, SERVO_TILT
 *
 * Examples:
 *   servo_set_angle(SERVO_PAN, 0);      // Pan left
 *   servo_set_angle(SERVO_PAN, 90);     // Pan center
 *   servo_set_angle(SERVO_TILT, 180);   // Tilt up
 */
void servo_set_angle(ServoChannel channel, uint16_t degrees);

/*
 * servo_get_angle(channel)
 *
 * Return current servo angle in degrees (0-180).
 */
uint16_t servo_get_angle(ServoChannel channel);

/*
 * servo_set_pulse_us(channel, pulse_us)
 *
 * Set servo pulse width directly in microseconds (500-2500).
 * Used for fine-tuning or direct control.
 */
void servo_set_pulse_us(ServoChannel channel, uint16_t pulse_us);

/*
 * servo_sweep(channel, start_deg, end_deg, duration_ms)
 *
 * Smooth linear sweep from start to end angle over duration_ms.
 * Non-blocking: must call servo_tick() every ~10 ms to update PWM.
 *
 * Examples:
 *   servo_sweep(SERVO_PAN, 0, 180, 2000);    // Pan left-to-right in 2 seconds
 *   servo_sweep(SERVO_TILT, 45, 135, 1000);  // Tilt up-down in 1 second
 */
void servo_sweep(ServoChannel channel, uint16_t start_deg, uint16_t end_deg, uint32_t duration_ms);

/*
 * servo_tick(now_ms)
 *
 * Update servo sweep animation (if active). Call every ~10 ms from main loop.
 * No-op if not currently sweeping.
 */
void servo_tick(uint32_t now_ms);

/*
 * servo_is_sweeping()
 *
 * Returns true if any servo is currently sweeping.
 */
bool servo_is_sweeping(void);

/*
 * servo_stop_sweep(channel)
 *
 * Stop sweep immediately, hold current position.
 */
void servo_stop_sweep(ServoChannel channel);

#endif /* SERVO_H */
