use abstracttui::base::{Point, Rect, Rgba};
use abstracttui::render::Style;
use abstracttui::text::truncate_ellipsis;
use abstracttui::ui::StyledCanvas;
use crate::view::GraphStyle;
pub(crate) struct CardPaint {
pub title: String,
pub badge: Option<String>,
pub accent: Option<Rgba>,
}
pub(crate) fn draw_card(
canvas: &mut dyn StyledCanvas,
rect: Rect,
style: &GraphStyle,
paint: &CardPaint,
selected: bool,
) {
if rect.w <= 0 || rect.h <= 0 {
return;
}
let border_ink = if selected {
style.card_border_selected
} else {
style.card_border
};
let left_ink = match (selected, paint.accent) {
(false, Some(accent)) => accent,
_ => border_ink,
};
let bg = style.card_bg;
canvas.fill(rect, ' ', style.card_title, bg);
if rect.w < 3 || rect.h < 2 {
let text = truncate_ellipsis(&paint.title, rect.w);
let mut s = Style::new().fg(style.card_title).bg(bg);
if selected {
s = s.bold().reverse();
}
canvas.print_styled(Point::new(rect.x, rect.y), &text, &s);
return;
}
let (top, bottom) = (rect.y, rect.bottom() - 1);
let (left, right) = (rect.x, rect.right() - 1);
for x in (left + 1)..right {
canvas.put(Point::new(x, top), '─', border_ink, bg);
canvas.put(Point::new(x, bottom), '─', border_ink, bg);
}
for y in (top + 1)..bottom {
canvas.put(Point::new(left, y), '│', left_ink, bg);
canvas.put(Point::new(right, y), '│', border_ink, bg);
}
canvas.put(Point::new(left, top), '╭', left_ink, bg);
canvas.put(Point::new(right, top), '╮', border_ink, bg);
canvas.put(Point::new(left, bottom), '╰', left_ink, bg);
canvas.put(Point::new(right, bottom), '╯', border_ink, bg);
let title_budget = rect.w - 4;
if title_budget > 0 && !paint.title.is_empty() {
let text = truncate_ellipsis(&paint.title, title_budget);
let mut s = Style::new().fg(style.card_title).bg(bg);
if selected {
s = s.bold();
}
let advanced = canvas.print_styled(Point::new(left + 2, top), &text, &s);
canvas.put(Point::new(left + 1, top), ' ', border_ink, bg);
canvas.put(Point::new(left + 2 + advanced, top), ' ', border_ink, bg);
}
if rect.h >= 3 {
if let Some(badge) = paint.badge.as_deref() {
let budget = rect.w - 2;
if budget > 0 && !badge.is_empty() {
let text = truncate_ellipsis(badge, budget);
let w = abstracttui::text::width(&text);
let x = right - w;
let s = Style::new().fg(style.badge).bg(bg);
canvas.print_styled(Point::new(x, top + 1), &text, &s);
}
}
}
}