use alloc::vec::Vec;
use binrw::BinRead;
use super::pvt_geodetic::{
Datum, DiffCorrType, PvtError, PvtMode, PvtModeFlags, RaimIntegrity, WACorrFlags,
};
#[derive(Debug, BinRead)]
pub struct PosCart {
#[br(map = |x: u32| if x == crate::DO_NOT_USE_U4 { None } else { Some(x) })]
pub tow: Option<u32>,
#[br(map = |x: u16| if x == crate::DO_NOT_USE_U2 { None } else { Some(x) })]
pub wnc: Option<u16>,
mode_raw: u8,
#[br(map = |x: u8| PvtError::from(x))]
pub error: PvtError,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub x: Option<f64>,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub y: Option<f64>,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub z: Option<f64>,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub base2rover_x: Option<f64>,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub base2rover_y: Option<f64>,
#[br(map = |x: f64| if x == crate::DO_NOT_USE_F8 { None } else { Some(x) })]
pub base2rover_z: Option<f64>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_xx: Option<f32>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_yy: Option<f32>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_zz: Option<f32>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_xy: Option<f32>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_xz: Option<f32>,
#[br(map = |x: f32| if x == crate::DO_NOT_USE_F4 { None } else { Some(x) })]
pub cov_yz: Option<f32>,
#[br(map = |x: u16| if x == 0 { None } else { Some(x) })]
pub pdop: Option<u16>,
#[br(map = |x: u16| if x == 0 { None } else { Some(x) })]
pub hdop: Option<u16>,
#[br(map = |x: u16| if x == 0 { None } else { Some(x) })]
pub vdop: Option<u16>,
pub misc: u8,
_reserved: u8,
alert_flag_raw: u8,
#[br(map = |x: u8| if x == crate::DO_NOT_USE_U1 { None } else { Some(Datum::from(x)) })]
pub datum: Option<Datum>,
#[br(map = |x: u8| if x == crate::DO_NOT_USE_U1 { None } else { Some(x) })]
pub nr_sv: Option<u8>,
wa_corr_info_raw: u8,
#[br(map = |x: u16| if x == crate::DO_NOT_USE_U2 { None } else { Some(x) })]
pub reference_id: Option<u16>,
#[br(map = |x: u16| if x == crate::DO_NOT_USE_U2 { None } else { Some(x) })]
pub mean_corr_age: Option<u16>,
pub signal_info: u32,
#[br(parse_with = binrw::helpers::until_eof)]
pub padding: Vec<u8>,
}
impl PosCart {
pub fn pvt_mode(&self) -> PvtMode {
PvtMode::from(self.mode_raw)
}
pub fn mode_flags(&self) -> PvtModeFlags {
PvtModeFlags::from_bits_truncate(self.mode_raw)
}
pub fn wa_corr_flags(&self) -> WACorrFlags {
WACorrFlags::from_bits_truncate(self.wa_corr_info_raw)
}
pub fn diff_corr_type(&self) -> DiffCorrType {
DiffCorrType::from(self.wa_corr_info_raw)
}
pub fn raim_integrity(&self) -> RaimIntegrity {
RaimIntegrity::from(self.alert_flag_raw)
}
pub fn galileo_hpca_failed(&self) -> bool {
self.alert_flag_raw & (1 << 2) != 0
}
pub fn galileo_iono_storm(&self) -> bool {
self.alert_flag_raw & (1 << 3) != 0
}
}