use crate::support::canvas::Canvas;
use crate::support::color::Color;
use crate::support::point::Point;
use super::ast::DelimiterKind;
#[derive(Clone, Copy)]
pub struct DelimiterGeometry {
pub origin: Point,
pub width: f32,
pub height: f32,
pub thickness: f32,
pub color: Color,
}
pub fn draw_delimiter(
canvas: &mut Canvas,
kind: DelimiterKind,
is_open: bool,
geometry: DelimiterGeometry,
) {
let DelimiterGeometry {
origin,
width,
height,
thickness,
color,
} = geometry;
canvas.stroke_style(color);
canvas.line_width(thickness);
let top = origin.y;
let bottom = origin.y + height;
let mirror = !is_open
&& !matches!(
kind,
DelimiterKind::AngleLeft
| DelimiterKind::AngleRight
| DelimiterKind::Bar
| DelimiterKind::DoubleBar
);
let (left, right) = if mirror {
(origin.x + width, origin.x)
} else {
(origin.x, origin.x + width)
};
let cap = (height * 0.18).min(width * 2.0).max(width * 0.5);
canvas.begin_path();
match kind {
DelimiterKind::Paren => {
canvas.move_to(Point::new(right, top));
canvas.cubic_to(
Point::new(left, top + cap),
Point::new(left, bottom - cap),
Point::new(right, bottom),
);
}
DelimiterKind::Bracket => {
canvas.move_to(Point::new(right, top));
canvas.line_to(Point::new(left, top));
canvas.line_to(Point::new(left, bottom));
canvas.line_to(Point::new(right, bottom));
}
DelimiterKind::Brace => {
let mid = (top + bottom) / 2.0;
canvas.move_to(Point::new(right, top));
canvas.quad_to(Point::new(left, top), Point::new(left, top + cap));
canvas.line_to(Point::new(left, mid - cap * 0.5));
canvas.quad_to(
Point::new(left - cap * 0.5, mid),
Point::new(left, mid + cap * 0.5),
);
canvas.line_to(Point::new(left, bottom - cap));
canvas.quad_to(Point::new(left, bottom), Point::new(right, bottom));
}
DelimiterKind::Floor => {
canvas.move_to(Point::new(left, top));
canvas.line_to(Point::new(left, bottom));
canvas.line_to(Point::new(right, bottom));
}
DelimiterKind::Ceil => {
canvas.move_to(Point::new(left, bottom));
canvas.line_to(Point::new(left, top));
canvas.line_to(Point::new(right, top));
}
DelimiterKind::Bar => {
let x = (left + right) / 2.0;
canvas.move_to(Point::new(x, top));
canvas.line_to(Point::new(x, bottom));
}
DelimiterKind::DoubleBar => {
let gap = width * 0.3;
let x1 = (left + right) / 2.0 - gap / 2.0;
let x2 = (left + right) / 2.0 + gap / 2.0;
canvas.move_to(Point::new(x1, top));
canvas.line_to(Point::new(x1, bottom));
canvas.move_to(Point::new(x2, top));
canvas.line_to(Point::new(x2, bottom));
}
DelimiterKind::AngleLeft => {
let mid = (top + bottom) / 2.0;
canvas.move_to(Point::new(right, top));
canvas.line_to(Point::new(left, mid));
canvas.line_to(Point::new(right, bottom));
}
DelimiterKind::AngleRight => {
let mid = (top + bottom) / 2.0;
canvas.move_to(Point::new(left, top));
canvas.line_to(Point::new(right, mid));
canvas.line_to(Point::new(left, bottom));
}
}
canvas.stroke();
}
pub fn delimiter_width(target_height: f32) -> f32 {
(target_height * 0.18).max(4.0)
}