use std::convert::TryFrom;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use crate::errors::{FormError, ErrorKind};
use crate::files::common::Properties;
use crate::language::color::Color;
use crate::language::controls::{BackStyle, DrawMode, DrawStyle, Visibility};
use num_enum::TryFromPrimitive;
use serde::Serialize;
#[derive(
Debug, PartialEq, Eq, Clone, Serialize, Default, TryFromPrimitive, Copy, Hash, PartialOrd, Ord,
)]
#[repr(i32)]
pub enum Shape {
#[default]
Rectangle = 0,
Square = 1,
Oval = 2,
Circle = 3,
RoundedRectangle = 4,
RoundSquare = 5,
}
impl TryFrom<&str> for Shape {
type Error = ErrorKind;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"0" => Ok(Shape::Rectangle),
"1" => Ok(Shape::Square),
"2" => Ok(Shape::Oval),
"3" => Ok(Shape::Circle),
"4" => Ok(Shape::RoundedRectangle),
"5" => Ok(Shape::RoundSquare),
_ => Err(ErrorKind::Form(FormError::InvalidShape {
value: value.to_string(),
})),
}
}
}
impl FromStr for Shape {
type Err = ErrorKind;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Shape::try_from(s)
}
}
impl Display for Shape {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let text = match self {
Shape::Rectangle => "Rectangle",
Shape::Square => "Square",
Shape::Oval => "Oval",
Shape::Circle => "Circle",
Shape::RoundedRectangle => "RoundedRectangle",
Shape::RoundSquare => "RoundSquare",
};
write!(f, "{text}")
}
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub struct ShapeProperties {
pub back_color: Color,
pub back_style: BackStyle,
pub border_color: Color,
pub border_style: DrawStyle,
pub border_width: i32,
pub draw_mode: DrawMode,
pub fill_color: Color,
pub fill_style: DrawStyle,
pub height: i32,
pub left: i32,
pub shape: Shape,
pub top: i32,
pub visible: Visibility,
pub width: i32,
}
impl Default for ShapeProperties {
fn default() -> Self {
ShapeProperties {
back_color: Color::System { index: 5 },
back_style: BackStyle::Transparent,
border_color: Color::System { index: 8 },
border_style: DrawStyle::Solid,
border_width: 1,
draw_mode: DrawMode::CopyPen,
fill_color: Color::RGB {
red: 0,
green: 0,
blue: 0,
},
fill_style: DrawStyle::Transparent,
height: 355,
left: 30,
shape: Shape::Rectangle,
top: 200,
visible: Visibility::Visible,
width: 355,
}
}
}
impl From<Properties> for ShapeProperties {
fn from(prop: Properties) -> Self {
let mut shape_prop = ShapeProperties::default();
shape_prop.back_color = prop.get_color("BackColor", shape_prop.back_color);
shape_prop.back_style = prop.get_property("BackStyle", shape_prop.back_style);
shape_prop.border_color = prop.get_color("BorderColor", shape_prop.border_color);
shape_prop.border_style = prop.get_property("BorderStyle", shape_prop.border_style);
shape_prop.border_width = prop.get_i32("BorderWidth", shape_prop.border_width);
shape_prop.draw_mode = prop.get_property("DrawMode", shape_prop.draw_mode);
shape_prop.fill_color = prop.get_color("FillColor", shape_prop.fill_color);
shape_prop.fill_style = prop.get_property("FillStyle", shape_prop.fill_style);
shape_prop.height = prop.get_i32("Height", shape_prop.height);
shape_prop.left = prop.get_i32("Left", shape_prop.left);
shape_prop.shape = prop.get_property("Shape", shape_prop.shape);
shape_prop.top = prop.get_i32("Top", shape_prop.top);
shape_prop.visible = prop.get_property("Visible", shape_prop.visible);
shape_prop.width = prop.get_i32("Width", shape_prop.width);
shape_prop
}
}