///|
/// Escapes text for safe insertion into SVG/XML attributes.
pub fn escape_svg(value : String) -> String {
  let builder = StringBuilder()
  for character in value.to_array() {
    match character {
      '&' => builder.write_string("&")
      '<' => builder.write_string("<")
      '>' => builder.write_string(">")
      '"' => builder.write_string(""")
      '\'' => builder.write_string("'")
      _ => builder.write_char(character)
    }
  }
  builder.to_string()
}

///|
/// Adds a line path to a document using a data-driven style.
pub fn SvgDocument::add_line(
  self : SvgDocument,
  start : Vec2,
  end : Vec2,
  style : SvgStyle,
) -> Unit {
  self.add(
    SvgElement::SvgPath(
      Path::new().move_to(start.x, start.y).line_to(end.x, end.y),
      style,
    ),
  )
}

///|
/// Adds a filled polygon to a document.
pub fn SvgDocument::add_polygon(
  self : SvgDocument,
  points : Array[Vec2],
  style : SvgStyle,
) -> Unit {
  self.add(SvgElement::SvgPath(polyline(points, closed=true), style))
}

///|
/// Renders a path with a compact style suitable for machine-generated assets.
pub fn SvgStyle::compact(self : SvgStyle) -> String {
  "fill:\{self.fill};stroke:\{self.stroke};stroke-width:\{self.stroke_width};opacity:\{self.opacity}"
}

///|
pub fn SvgDocument::element_count(self : SvgDocument) -> Int {
  self.elements.length()
}

///|
pub fn SvgDocument::bounds(self : SvgDocument) -> Rect {
  Rect::new(0.0, 0.0, self.width, self.height)
}

///|
/// Serializes a design with a title and metadata block.
pub fn SvgDocument::to_svg_string_with_metadata(
  self : SvgDocument,
  title : String,
  description : String,
) -> String {
  let content = self.to_svg_string()
  let marker = " SvgDocument {
  let document = SvgDocument::new(width, height)
  if step_x > 0.0 && step_y > 0.0 {
    let mut y = 0.0
    while y <= height {
      let mut x = 0.0
      while x <= width {
        document.add(
          SvgElement::SvgPath(path.transform(Matrix2D::translate(x, y)), style),
        )
        x += step_x
      }
      y += step_y
    }
  }
  document
}