use bone_types::{Angle, Length, Point2};

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct PreviewCircle {
    pub center: Point2,
    pub radius: Length,
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub struct PreviewArc {
    pub center: Point2,
    pub radius: Length,
    pub start_angle: Angle,
    pub sweep_angle: Angle,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct SketchPreview {
    pub anchors: Vec<Point2>,
    pub segments: Vec<(Point2, Point2)>,
    pub circles: Vec<PreviewCircle>,
    pub arcs: Vec<PreviewArc>,
    pub snap: Option<Point2>,
}

impl SketchPreview {
    #[must_use]
    pub const fn empty() -> Self {
        Self {
            anchors: Vec::new(),
            segments: Vec::new(),
            circles: Vec::new(),
            arcs: Vec::new(),
            snap: None,
        }
    }

    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.anchors.is_empty()
            && self.segments.is_empty()
            && self.circles.is_empty()
            && self.arcs.is_empty()
            && self.snap.is_none()
    }
}

#[cfg(test)]
mod tests {
    use super::{PreviewArc, PreviewCircle, SketchPreview};
    use bone_types::{Angle, Length, Point2};
    use uom::si::angle::radian;
    use uom::si::length::millimeter;

    #[test]
    fn empty_has_no_overlay() {
        let preview = SketchPreview::empty();
        assert!(preview.is_empty());
    }

    #[test]
    fn anchor_only_is_non_empty() {
        let preview = SketchPreview {
            anchors: vec![Point2::from_mm(1.0, 2.0)],
            ..SketchPreview::empty()
        };
        assert!(!preview.is_empty());
    }

    #[test]
    fn segment_only_is_non_empty() {
        let preview = SketchPreview {
            segments: vec![(Point2::from_mm(0.0, 0.0), Point2::from_mm(1.0, 1.0))],
            ..SketchPreview::empty()
        };
        assert!(!preview.is_empty());
    }

    #[test]
    fn snap_only_is_non_empty() {
        let preview = SketchPreview {
            snap: Some(Point2::from_mm(2.0, 3.0)),
            ..SketchPreview::empty()
        };
        assert!(!preview.is_empty());
    }

    #[test]
    fn circle_only_is_non_empty() {
        let preview = SketchPreview {
            circles: vec![PreviewCircle {
                center: Point2::from_mm(0.0, 0.0),
                radius: Length::new::<millimeter>(3.0),
            }],
            ..SketchPreview::empty()
        };
        assert!(!preview.is_empty());
    }

    #[test]
    fn arc_only_is_non_empty() {
        let preview = SketchPreview {
            arcs: vec![PreviewArc {
                center: Point2::from_mm(0.0, 0.0),
                radius: Length::new::<millimeter>(2.0),
                start_angle: Angle::new::<radian>(0.0),
                sweep_angle: Angle::new::<radian>(1.0),
            }],
            ..SketchPreview::empty()
        };
        assert!(!preview.is_empty());
    }
}
