///|
/// SVG filter description used by exported documents.
pub(all) enum SvgFilter {
  Blur(Double)
  DropShadow(dx~ : Double, dy~ : Double, blur~ : Double, color~ : Color)
  ColorMatrix(Array[Double])
} derive(Eq, Debug, ToJson)

///|
pub fn SvgFilter::to_svg_string(
  self : SvgFilter,
  identifier : String,
) -> String {
  match self {
    Blur(radius) =>
      ""
    DropShadow(dx~, dy~, blur~, color~) =>
      ""
    ColorMatrix(values) => {
      let builder = StringBuilder()
      builder.write_string(" 0 {
          builder.write_string(" ")
        }
        builder.write_string(value.to_string())
      }
      builder.write_string("\" />")
      builder.to_string()
    }
  }
}

///|
pub fn grayscale_filter() -> SvgFilter {
  ColorMatrix([
    0.333, 0.333, 0.333, 0.0, 0.0, 0.333, 0.333, 0.333, 0.0, 0.0, 0.333, 0.333, 0.333,
    0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
  ])
}

///|
pub fn tint_filter(color : Color, amount : Double) -> SvgFilter {
  let t = amount.max(0.0).min(1.0)
  ColorMatrix([
    1.0 - t,
    0.0,
    0.0,
    0.0,
    color.r * t,
    0.0,
    1.0 - t,
    0.0,
    0.0,
    color.g * t,
    0.0,
    0.0,
    1.0 - t,
    0.0,
    color.b * t,
    0.0,
    0.0,
    0.0,
    1.0,
    0.0,
  ])
}

///|
pub fn filter_defs(filters : Array[(String, SvgFilter)]) -> String {
  let builder = StringBuilder()
  builder.write_string("")
  for item in filters {
    builder.write_string(item.1.to_svg_string(item.0))
  }
  builder.write_string("")
  builder.to_string()
}

///|
pub fn style_with_filter(style : SvgStyle, identifier : String) -> String {
  style.compact() + ";filter:url(#" + escape_svg(identifier) + ")"
}