use crate::common::ToText;
use crate::svg::{DEFAULT_SVG_INDENT, DEFAULT_SVG_OFFSET};
use crate::{HtmlElement, SvgNumber};
use std::fmt;
use std::fmt::Display;
pub const DEFAULT_SVG_NAMESPACE: &str = "http://www.w3.org/2000/svg";
#[derive(Debug, Default, Clone)]
pub struct SvgDocument {
namespace: Option<String>,
view_box: Option<(SvgNumber, SvgNumber, SvgNumber, SvgNumber)>,
width: Option<SvgNumber>,
height: Option<SvgNumber>,
}
impl SvgDocument {
pub fn new() -> Self {
Self::default()
}
pub fn default_namespace(mut self) -> Self {
self.set_default_namespace();
self
}
pub fn set_default_namespace(&mut self) {
self.namespace = DEFAULT_SVG_NAMESPACE.to_string().into();
}
pub fn namespace<T: ToString>(mut self, namespace: T) -> Self {
self.set_namespace(namespace);
self
}
pub fn set_namespace<T: ToString>(&mut self, namespace: T) {
self.namespace = namespace.to_string().into();
}
pub fn view_box<T: Into<SvgNumber>>(mut self, min_x: T, min_y: T, width: T, height: T) -> Self {
self.set_view_box(min_x, min_y, width, height);
self
}
pub fn set_view_box<T: Into<SvgNumber>>(&mut self, min_x: T, min_y: T, width: T, height: T) {
self.view_box = Some((min_x.into(), min_y.into(), width.into(), height.into()));
}
pub fn width<T: Into<SvgNumber>>(mut self, width: T) -> Self {
self.set_width(width);
self
}
pub fn set_width<T: Into<SvgNumber>>(&mut self, width: T) {
self.width = Some(width.into());
}
pub fn height<T: Into<SvgNumber>>(mut self, height: T) -> Self {
self.set_height(height);
self
}
pub fn set_height<T: Into<SvgNumber>>(&mut self, height: T) {
self.height = Some(height.into());
}
}
impl ToText for SvgDocument {
fn to_text(&self, offset: usize, indent: usize) -> String {
let svg: HtmlElement = (*self).clone().into();
svg.to_text(offset, indent)
}
}
impl Display for SvgDocument {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_text(DEFAULT_SVG_OFFSET, DEFAULT_SVG_INDENT))
}
}
impl From<SvgDocument> for HtmlElement {
fn from(value: SvgDocument) -> Self {
let mut svg = HtmlElement::new("svg");
if let Some(width) = value.width {
svg.set_attribute("width", width.to_string());
}
if let Some(height) = value.height {
svg.set_attribute("height", height.to_string());
}
if let Some(namespace) = value.namespace {
svg.set_attribute("xmlns", namespace);
}
if let Some((min_x, min_y, width, height)) = value.view_box {
svg.set_attribute("viewBox", format!("{} {} {} {}", min_x, min_y, width, height));
}
svg
}
}