use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GradientStop {
    pub offset: f32,
    pub color: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PathCommand {
    MoveTo { x: f32, y: f32 },
    RelativeMoveTo { dx: f32, dy: f32 },
    LineTo { x: f32, y: f32 },
    RelativeLineTo { dx: f32, dy: f32 },
    HorizontalLineTo { x: f32 },
    RelativeHorizontalLineTo { dx: f32 },
    VerticalLineTo { y: f32 },
    RelativeVerticalLineTo { dy: f32 },
    CurveTo { x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32 },
    RelativeCurveTo { dx1: f32, dy1: f32, dx2: f32, dy2: f32, dx: f32, dy: f32 },
    SmoothCurveTo { x2: f32, y2: f32, x: f32, y: f32 },
    RelativeSmoothCurveTo { dx2: f32, dy2: f32, dx: f32, dy: f32 },
    QuadraticCurveTo { x1: f32, y1: f32, x: f32, y: f32 },
    RelativeQuadraticCurveTo { dx1: f32, dy1: f32, dx: f32, dy: f32 },
    SmoothQuadraticCurveTo { x: f32, y: f32 },
    RelativeSmoothQuadraticCurveTo { dx: f32, dy: f32 },
    Arc { rx: f32, ry: f32, x_rotation: f32, large_arc: bool, sweep: bool, x: f32, y: f32 },
    RelativeArc { rx: f32, ry: f32, x_rotation: f32, large_arc: bool, sweep: bool, dx: f32, dy: f32 },
    ClosePath,
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum FillRule {
    NonZero,
    EvenOdd,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum VectorShape {
    Rect {
        x: f32,
        y: f32,
        width: f32,
        height: f32,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        rx: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Line {
        x1: f32,
        y1: f32,
        x2: f32,
        y2: f32,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Circle {
        cx: f32,
        cy: f32,
        r: f32,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Ellipse {
        cx: f32,
        cy: f32,
        rx: f32,
        ry: f32,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Path {
        commands: Vec<PathCommand>,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        fill_rule: FillRule,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Polyline {
        points: Vec<(f32, f32)>,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    Polygon {
        points: Vec<(f32, f32)>,
        fill: Option<String>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
        line_join: Option<String>,
        line_cap: Option<String>,
        dash_array: Option<String>,
    },
    LinearGradient {
        x: f32,
        y: f32,
        width: f32,
        height: f32,
        x1: f32,
        y1: f32,
        x2: f32,
        y2: f32,
        stops: Vec<GradientStop>,
        stroke: Option<String>,
        stroke_width: Option<f32>,
    },
    PatternFill {
        x: f32,
        y: f32,
        width: f32,
        height: f32,
        pattern_type: String,
        stroke: Option<String>,
        stroke_width: Option<f32>,
    },
}