use crate::error::Result;
use crate::traits::{FromParams, ToParams};
use crate::types::{Coord, CoordRect, ParameterCollection, UnknownFields};
use altium_format_derive::AltiumRecord;
use super::{LineStyle, LineWidth, SchGraphicalBase, SchPrimitive};
#[derive(Debug, Clone, Default, AltiumRecord)]
#[altium(record_id = 6, format = "params")]
pub struct SchPolyline {
#[altium(flatten)]
pub graphical: SchGraphicalBase,
#[altium(param = "LINEWIDTH", default)]
pub line_width: LineWidth,
#[altium(param = "LINESTYLE", default)]
pub line_style: LineStyle,
#[altium(param = "ISSOLID", default)]
pub is_solid: bool,
#[altium(
indexed_coords,
prefix_x = "X",
prefix_y = "Y",
count = "LOCATIONCOUNT"
)]
pub vertices: Vec<(i32, i32)>,
#[altium(unknown)]
pub unknown_params: UnknownFields,
}
impl SchPolyline {
pub fn polygon(&self) -> PolygonView<'_> {
PolygonView { polyline: self }
}
}
pub struct PolygonView<'a> {
polyline: &'a SchPolyline,
}
impl<'a> PolygonView<'a> {
pub fn vertices(&self) -> &[(i32, i32)] {
&self.polyline.vertices
}
pub fn graphical(&self) -> &SchGraphicalBase {
&self.polyline.graphical
}
}
impl SchPrimitive for SchPolyline {
const RECORD_ID: i32 = 6;
fn location(&self) -> Option<crate::types::CoordPoint> {
Some(crate::types::CoordPoint::from_raw(
self.graphical.location_x,
self.graphical.location_y,
))
}
fn record_type_name(&self) -> &'static str {
"Polyline"
}
fn import_from_params(params: &ParameterCollection) -> Result<Self> {
Self::from_params(params)
}
fn export_to_params(&self) -> ParameterCollection {
self.to_params()
}
fn owner_index(&self) -> i32 {
self.graphical.base.owner_index
}
fn calculate_bounds(&self) -> CoordRect {
let Some(&(first_x, first_y)) = self.vertices.first() else {
return CoordRect::empty();
};
let (min_x, max_x, min_y, max_y) = self.vertices.iter().skip(1).fold(
(first_x, first_x, first_y, first_y),
|(min_x, max_x, min_y, max_y), &(x, y)| {
(min_x.min(x), max_x.max(x), min_y.min(y), max_y.max(y))
},
);
CoordRect::from_points(
Coord::from_raw(min_x),
Coord::from_raw(min_y),
Coord::from_raw(max_x),
Coord::from_raw(max_y),
)
}
}