//! `Coordinate`, `Geofence`, `MissionItem`, `MissionWaypoint` — per
//! `data_model.md §4 Action / piloting entities`.

use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Coordinate {
    pub latitude: f64,
    pub longitude: f64,
    pub altitude_m: f32,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum GeofenceKind {
    Inclusion,
    Exclusion,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Geofence {
    pub kind: GeofenceKind,
    pub vertices: Vec<Coordinate>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MissionItemKind {
    Waypoint,
    Search,
    RegionSearch,
    Return,
    TargetFollowBreakpoint,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MissionItem {
    pub id: Uuid,
    pub kind: MissionItemKind,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub at: Option<Coordinate>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub region: Vec<Coordinate>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cruise_speed_mps: Option<f32>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub target_classes: Vec<String>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum MavFrame {
    MavFrameGlobalRelativeAlt,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum MavCommand {
    MavCmdNavTakeoff,
    MavCmdNavWaypoint,
    MavCmdNavLand,
    MavCmdDoChangeSpeed,
    MavCmdNavReturnToLaunch,
    MavCmdDoSetMode,
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct MissionWaypoint {
    pub seq: u16,
    pub frame: MavFrame,
    pub command: MavCommand,
    pub current: bool,
    pub auto_continue: bool,
    pub param_1: f32,
    pub param_2: f32,
    pub param_3: f32,
    pub param_4: f32,
    pub lat_deg_e7: i32,
    pub lon_deg_e7: i32,
    pub alt_m: f32,
}
