#[cfg(feature = "gps")]
use crate::field_definitions::ConditionalFieldDefinition;
use crate::field_definitions::{FieldCondition, FieldEncoding, FieldPredictor, FieldSign};
use crate::field_definitions::{MainFieldDefinition, SimpleFieldDefinition};

pub static BLACKBOX_SLOW_FIELDS: [SimpleFieldDefinition; SimpleFieldDefinition::SLOW_FIELD_COUNT] = [
    SimpleFieldDefinition {
        name: "flight_mode_flags",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB,
    },
    SimpleFieldDefinition {
        name: "state_flags",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB,
    },
    SimpleFieldDefinition {
        name: "failsafe_phase",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB, //TAG2_3S32,
    },
    SimpleFieldDefinition {
        name: "rx_signal_received",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB, //TAG2_3S32,
    },
    SimpleFieldDefinition {
        name: "rx_flight_channel_is_valid",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB, //TAG2_3S32,
    },
];

impl SimpleFieldDefinition {
    pub const SLOW_FIELD_COUNT: usize = 5;
    pub const GPS_H_FIELD_COUNT: usize = 3;

    #[allow(unused)]
    pub fn find_by_name(name: &str) -> Option<&'static Self> {
        BLACKBOX_SLOW_FIELDS.iter().find(|field| field.name == name)
    }
}

// GPS home frame
pub static BLACKBOX_GPS_H_FIELDS: [SimpleFieldDefinition; SimpleFieldDefinition::GPS_H_FIELD_COUNT] = [
    SimpleFieldDefinition {
        name: "GPS_home",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
    },
    SimpleFieldDefinition {
        name: "GPS_home",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
    },
    SimpleFieldDefinition {
        name: "GPS_home",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
    },
];

// GPS position/velocity frame
#[cfg(feature = "gps")]
pub static BLACKBOX_GPS_G_FIELDS: [ConditionalFieldDefinition; ConditionalFieldDefinition::GPS_G_FIELD_COUNT] = [
    ConditionalFieldDefinition {
        name: "time",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::LAST_MAIN_FRAME_TIME,
        encode: FieldEncoding::UNSIGNED_VB,
        condition: FieldCondition::NOT_LOGGING_EVERY_FRAME,
    },
    ConditionalFieldDefinition {
        name: "GPS_numSat",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_coord",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::HOME_COORD,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_coord",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::HOME_COORD,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_altitude",
        field_name_index: -1,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_speed",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_ground_course",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::UNSIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_velned",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_velned",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    ConditionalFieldDefinition {
        name: "GPS_velned",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        predict: FieldPredictor::ZERO,
        encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
];

#[cfg(feature = "gps")]
impl ConditionalFieldDefinition {
    pub const GPS_G_FIELD_COUNT: usize = 10;

    #[allow(unused)]
    #[cfg(feature = "gps")]
    pub fn find_by_name(name: &str) -> Option<&'static Self> {
        BLACKBOX_GPS_G_FIELDS.iter().find(|field| field.name == name)
    }
}

pub static BLACKBOX_MAIN_FIELDS: &[MainFieldDefinition] = &[
    // loopIteration doesn't appear in p_frames since it always increments
    MainFieldDefinition {
        name: "loopIteration",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::INC,
        p_encode: FieldEncoding::NULL,
        condition: FieldCondition::ALWAYS,
    },
    // Time advances pretty steadily so the p_frame prediction is a straight line
    MainFieldDefinition {
        name: "time",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::STRAIGHT_LINE,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ALWAYS,
    },
    MainFieldDefinition {
        name: "axisP",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID,
    },
    MainFieldDefinition {
        name: "axisP",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID,
    },
    MainFieldDefinition {
        name: "axisP",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID,
    },
    // iterms get special packed encoding in p_frames:
    MainFieldDefinition {
        name: "axisI",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG2_3S32,
        condition: FieldCondition::PID,
    },
    MainFieldDefinition {
        name: "axisI",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG2_3S32,
        condition: FieldCondition::PID,
    },
    MainFieldDefinition {
        name: "axisI",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG2_3S32,
        condition: FieldCondition::PID,
    },
    MainFieldDefinition {
        name: "axisD",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_D_ROLL,
    },
    MainFieldDefinition {
        name: "axisD",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_D_PITCH,
    },
    MainFieldDefinition {
        name: "axisD",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_D_YAW,
    },
    // PID K terms use F (feedforward) suffix, for Betaflight compatibility.
    MainFieldDefinition {
        name: "axisF",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_K,
    },
    MainFieldDefinition {
        name: "axisF",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_K,
    },
    MainFieldDefinition {
        name: "axisF",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_K,
    },
    MainFieldDefinition {
        name: "axisS",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_S_ROLL,
    },
    MainFieldDefinition {
        name: "axisS",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_S_PITCH,
    },
    MainFieldDefinition {
        name: "axisS",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::PID_S_YAW,
    },
    // rc_commands are encoded together as a group in p_frames:
    MainFieldDefinition {
        name: "rcCommand",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::RC_COMMANDS,
    },
    MainFieldDefinition {
        name: "rcCommand",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::RC_COMMANDS,
    },
    MainFieldDefinition {
        name: "rcCommand",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::RC_COMMANDS,
    },
    MainFieldDefinition {
        name: "rcCommand",
        field_name_index: 3,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MIN_THROTTLE,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::RC_COMMANDS,
    },
    // setpoint
    MainFieldDefinition {
        name: "setpoint",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::SETPOINT,
    },
    MainFieldDefinition {
        name: "setpoint",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::SETPOINT,
    },
    MainFieldDefinition {
        name: "setpoint",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::SETPOINT,
    },
    MainFieldDefinition {
        name: "setpoint",
        field_name_index: 3,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_4S16,
        condition: FieldCondition::SETPOINT,
    },
    MainFieldDefinition {
        name: "vbatLatest",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::VBATREF,
        i_encode: FieldEncoding::NEG_14BIT,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::BATTERY_VOLTAGE,
    },
    MainFieldDefinition {
        name: "amperageLatest",
        field_name_index: -1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::BATTERY_CURRENT,
    },
    MainFieldDefinition {
        name: "BaroAlt",
        field_name_index: -1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::BAROMETER,
    },
    MainFieldDefinition {
        name: "surfaceRaw",
        field_name_index: -1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::RANGEFINDER,
    },
    MainFieldDefinition {
        name: "rssi",
        field_name_index: -1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::RSSI,
    },
    MainFieldDefinition {
        name: "magADC",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::MAGNETOMETER,
    },
    MainFieldDefinition {
        name: "magADC",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::MAGNETOMETER,
    },
    MainFieldDefinition {
        name: "magADC",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::TAG8_8SVB,
        condition: FieldCondition::MAGNETOMETER,
    },
    MainFieldDefinition {
        name: "gyroADC",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO,
    },
    MainFieldDefinition {
        name: "gyroADC",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO,
    },
    MainFieldDefinition {
        name: "gyroADC",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO,
    },
    MainFieldDefinition {
        name: "gyroUnfilt",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO_UNFILTERED,
    },
    MainFieldDefinition {
        name: "gyroUnfilt",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO_UNFILTERED,
    },
    MainFieldDefinition {
        name: "gyroUnfilt",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::GYRO_UNFILTERED,
    },
    MainFieldDefinition {
        name: "accSmooth",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ACC,
    },
    MainFieldDefinition {
        name: "accSmooth",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ACC,
    },
    MainFieldDefinition {
        name: "accSmooth",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ACC,
    },
    MainFieldDefinition {
        name: "imuQuaternion",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ATTITUDE,
    },
    MainFieldDefinition {
        name: "imuQuaternion",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ATTITUDE,
    },
    MainFieldDefinition {
        name: "imuQuaternion",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::ATTITUDE,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 1,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 2,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 3,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 4,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 5,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 6,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "debug",
        field_name_index: 7,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::DEBUG,
    },
    MainFieldDefinition {
        name: "motor",
        field_name_index: 0,
        is_signed: FieldSign::SIGNED,
        i_predict: FieldPredictor::MIN_MOTOR,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_1,
    },
    MainFieldDefinition {
        name: "motor",
        field_name_index: 1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_2,
    },
    MainFieldDefinition {
        name: "motor",
        field_name_index: 2,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_3,
    },
    MainFieldDefinition {
        name: "motor",
        field_name_index: 3,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_4,
    },
    #[cfg(feature = "eight_motors")]
    MainFieldDefinition {
        name: "motor",
        field_name_index: 4,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_5,
    },
    #[cfg(feature = "eight_motors")]
    MainFieldDefinition {
        name: "motor",
        field_name_index: 5,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_6,
    },
    #[cfg(feature = "eight_motors")]
    MainFieldDefinition {
        name: "motor",
        field_name_index: 6,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_7,
    },
    #[cfg(feature = "eight_motors")]
    MainFieldDefinition {
        name: "motor",
        field_name_index: 7,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::MOTOR_0,
        i_encode: FieldEncoding::SIGNED_VB,
        p_predict: FieldPredictor::AVERAGE_2,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::AT_LEAST_MOTORS_8,
    },
    #[cfg(feature = "dshot_telemetry")]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 0,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_1_HAS_RPM,
    },
    #[cfg(feature = "dshot_telemetry")]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 1,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_2_HAS_RPM,
    },
    #[cfg(feature = "dshot_telemetry")]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 2,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_3_HAS_RPM,
    },
    #[cfg(feature = "dshot_telemetry")]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 3,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_4_HAS_RPM,
    },
    #[cfg(all(feature = "dshot_telemetry", feature = "eight_motors"))]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 4,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_5_HAS_RPM,
    },
    #[cfg(all(feature = "dshot_telemetry", feature = "eight_motors"))]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 5,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_6_HAS_RPM,
    },
    #[cfg(all(feature = "dshot_telemetry", feature = "eight_motors"))]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 6,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_7_HAS_RPM,
    },
    #[cfg(all(feature = "dshot_telemetry", feature = "eight_motors"))]
    MainFieldDefinition {
        name: "eRPM",
        field_name_index: 7,
        is_signed: FieldSign::UNSIGNED,
        i_predict: FieldPredictor::ZERO,
        i_encode: FieldEncoding::UNSIGNED_VB,
        p_predict: FieldPredictor::PREVIOUS,
        p_encode: FieldEncoding::SIGNED_VB,
        condition: FieldCondition::MOTOR_8_HAS_RPM,
    },
];

impl MainFieldDefinition {
    #[allow(unused)]
    pub fn find_by_name(name: &str) -> Option<&'static Self> {
        BLACKBOX_MAIN_FIELDS.iter().find(|field| field.name == name)
    }
}
