//! FIT global message numbers, field numbers and enum values.
//!
//! These are facts from the Garmin FIT SDK profile (`Profile.xlsx`, SDK 21.x),
//! transcribed for the handful of messages an activity file needs. They were
//! cross-checked against the generated profile in the `rustyfit` crate.
//!
//! **Watch the `lap` / `session` divergence.** The two messages do *not* share
//! field numbers: `session` inserts `total_fat_calories` at 13, which shifts
//! every summary field after it by one relative to `lap`. Writing lap field
//! numbers into a session message produces a file that parses but reports
//! nonsense (average power showing up as maximum heart rate, and so on).

// These are transcription tables: each constant's name *is* its documentation,
// and a doc comment per entry would bury the numbers that matter.
#![allow(missing_docs)]

/// Global message numbers.
pub mod mesg {
    pub const FILE_ID: u16 = 0;
    pub const SESSION: u16 = 18;
    pub const LAP: u16 = 19;
    pub const RECORD: u16 = 20;
    pub const EVENT: u16 = 21;
    pub const DEVICE_INFO: u16 = 23;
    pub const ACTIVITY: u16 = 34;
}

/// `file_id` (global 0) field numbers.
pub mod file_id {
    pub const TYPE: u8 = 0;
    pub const MANUFACTURER: u8 = 1;
    pub const PRODUCT: u8 = 2;
    pub const SERIAL_NUMBER: u8 = 3;
    pub const TIME_CREATED: u8 = 4;
    pub const PRODUCT_NAME: u8 = 8;
}

/// `device_info` (global 23) field numbers.
pub mod device_info {
    pub const DEVICE_INDEX: u8 = 0;
    pub const MANUFACTURER: u8 = 2;
    pub const PRODUCT: u8 = 4;
    pub const SOFTWARE_VERSION: u8 = 5;
    pub const SOURCE_TYPE: u8 = 25;
    pub const PRODUCT_NAME: u8 = 27;
    pub const TIMESTAMP: u8 = 253;
}

/// `event` (global 21) field numbers.
pub mod event {
    pub const EVENT: u8 = 0;
    pub const EVENT_TYPE: u8 = 1;
    pub const DATA: u8 = 3;
    pub const EVENT_GROUP: u8 = 4;
    pub const TIMESTAMP: u8 = 253;
}

/// `record` (global 20) field numbers.
pub mod record {
    pub const ALTITUDE: u8 = 2;
    pub const HEART_RATE: u8 = 3;
    pub const CADENCE: u8 = 4;
    pub const DISTANCE: u8 = 5;
    pub const SPEED: u8 = 6;
    pub const POWER: u8 = 7;
    pub const GRADE: u8 = 9;
    pub const RESISTANCE: u8 = 10;
    pub const CALORIES: u8 = 33;
    pub const TIMESTAMP: u8 = 253;
}

/// `lap` (global 19) field numbers.
pub mod lap {
    pub const EVENT: u8 = 0;
    pub const EVENT_TYPE: u8 = 1;
    pub const START_TIME: u8 = 2;
    pub const TOTAL_ELAPSED_TIME: u8 = 7;
    pub const TOTAL_TIMER_TIME: u8 = 8;
    pub const TOTAL_DISTANCE: u8 = 9;
    pub const TOTAL_CALORIES: u8 = 11;
    pub const AVG_SPEED: u8 = 13;
    pub const MAX_SPEED: u8 = 14;
    pub const AVG_HEART_RATE: u8 = 15;
    pub const MAX_HEART_RATE: u8 = 16;
    pub const AVG_CADENCE: u8 = 17;
    pub const MAX_CADENCE: u8 = 18;
    pub const AVG_POWER: u8 = 19;
    pub const MAX_POWER: u8 = 20;
    pub const TOTAL_ASCENT: u8 = 21;
    pub const TOTAL_DESCENT: u8 = 22;
    pub const INTENSITY: u8 = 23;
    pub const LAP_TRIGGER: u8 = 24;
    pub const SPORT: u8 = 25;
    pub const SUB_SPORT: u8 = 39;
    pub const TOTAL_WORK: u8 = 41;
    pub const AVG_GRADE: u8 = 45;
    pub const TIMESTAMP: u8 = 253;
    pub const MESSAGE_INDEX: u8 = 254;
}

/// `session` (global 18) field numbers. Note the offset relative to [`lap`].
pub mod session {
    pub const EVENT: u8 = 0;
    pub const EVENT_TYPE: u8 = 1;
    pub const START_TIME: u8 = 2;
    pub const SPORT: u8 = 5;
    pub const SUB_SPORT: u8 = 6;
    pub const TOTAL_ELAPSED_TIME: u8 = 7;
    pub const TOTAL_TIMER_TIME: u8 = 8;
    pub const TOTAL_DISTANCE: u8 = 9;
    pub const TOTAL_CALORIES: u8 = 11;
    pub const AVG_SPEED: u8 = 14;
    pub const MAX_SPEED: u8 = 15;
    pub const AVG_HEART_RATE: u8 = 16;
    pub const MAX_HEART_RATE: u8 = 17;
    pub const AVG_CADENCE: u8 = 18;
    pub const MAX_CADENCE: u8 = 19;
    pub const AVG_POWER: u8 = 20;
    pub const MAX_POWER: u8 = 21;
    pub const TOTAL_ASCENT: u8 = 22;
    pub const TOTAL_DESCENT: u8 = 23;
    pub const FIRST_LAP_INDEX: u8 = 25;
    pub const NUM_LAPS: u8 = 26;
    pub const TRIGGER: u8 = 28;
    pub const TOTAL_WORK: u8 = 48;
    pub const TIMESTAMP: u8 = 253;
    pub const MESSAGE_INDEX: u8 = 254;
}

/// `activity` (global 34) field numbers.
pub mod activity {
    pub const TOTAL_TIMER_TIME: u8 = 0;
    pub const NUM_SESSIONS: u8 = 1;
    pub const TYPE: u8 = 2;
    pub const EVENT: u8 = 3;
    pub const EVENT_TYPE: u8 = 4;
    pub const LOCAL_TIMESTAMP: u8 = 5;
    pub const TIMESTAMP: u8 = 253;
}

/// Enum values used by the messages above.
pub mod enums {
    /// `file` — `file_id.type`.
    pub const FILE_ACTIVITY: u8 = 4;

    /// `manufacturer` — 255 is the SDK's "development" manufacturer, the
    /// correct value for an application that is not a registered Garmin
    /// partner. Both Strava and Garmin Connect accept it.
    pub const MANUFACTURER_DEVELOPMENT: u16 = 255;

    /// `sport`.
    pub const SPORT_CYCLING: u8 = 2;

    /// `sub_sport`. `VIRTUAL_ACTIVITY` is what makes Strava file the upload as
    /// a *Virtual Ride* rather than an outdoor ride with no GPS.
    pub const SUB_SPORT_INDOOR_CYCLING: u8 = 6;
    pub const SUB_SPORT_VIRTUAL_ACTIVITY: u8 = 58;

    /// `event`.
    pub const EVENT_TIMER: u8 = 0;
    pub const EVENT_LAP: u8 = 9;
    pub const EVENT_SESSION: u8 = 8;
    pub const EVENT_ACTIVITY: u8 = 26;

    /// `event_type`.
    pub const EVENT_TYPE_START: u8 = 0;
    pub const EVENT_TYPE_STOP: u8 = 1;
    pub const EVENT_TYPE_STOP_ALL: u8 = 4;

    /// `lap_trigger`.
    pub const LAP_TRIGGER_MANUAL: u8 = 0;
    pub const LAP_TRIGGER_SESSION_END: u8 = 7;

    /// `session_trigger`.
    pub const SESSION_TRIGGER_ACTIVITY_END: u8 = 0;

    /// `activity` — `activity.type`.
    pub const ACTIVITY_MANUAL: u8 = 0;

    /// `intensity`.
    pub const INTENSITY_ACTIVE: u8 = 0;

    /// `source_type`.
    pub const SOURCE_TYPE_LOCAL: u8 = 5;

    /// `device_index` — 0 is reserved for the device that created the file.
    pub const DEVICE_INDEX_CREATOR: u8 = 0;
}
