#pragma once

namespace fgc {

// Affine map between heading degrees and absolute encoder counts for one axis:
//
//   counts = zero_count + deg * counts_per_deg
//   deg    = (counts - zero_count) / counts_per_deg
//
// The firmware speaks only in encoder counts; this is how the host converts to
// the heading/elevation degrees used by the MQTT contract and CamEvent. The
// parameters are operator-calibrated against real `xenc` readings after homing
// (counts_per_deg may be negative to flip the direction sense).
struct AxisMap {
    double counts_per_deg = 1.0;        // calibrate on the rig
    long   zero_count     = 0;          // xenc value that corresponds to 0 deg
    double min_deg        = -100000.0;  // soft clamp applied by toCounts (degrees)
    double max_deg        = 100000.0;

    // Degrees -> counts. Clamps `deg` to [min_deg, max_deg] and rounds.
    long toCounts(double deg) const;

    // Counts -> degrees. Returns 0 if counts_per_deg is ~0 (misconfigured).
    double toDeg(long counts) const;
};

// Per-axis maps for the two-axis gimbal.
struct Geometry {
    AxisMap yaw;
    AxisMap pitch;
};

}  // namespace fgc
