use ratatui::Frame;
use crate::app::{App, Status};
pub fn draw(f: &mut Frame, app: &App, area: ratatui::layout::Rect) {
let inner = super::draw_panel(f, "Clean Map", area);
let cyan = ratatui::style::Color::Cyan;
let yellow = ratatui::style::Color::Yellow;
let green = ratatui::style::Color::Green;
let gray = ratatui::style::Color::DarkGray;
let white = ratatui::style::Color::White;
let opts = &app.clean_options;
let sel = app.clean_selection;
let toggles: Vec<(usize, &str, bool)> = vec![
(0, "Make valid geometries", opts.make_valid),
(1, "Drop invalid features", opts.drop_invalid),
(2, "Remove self-loops", opts.remove_selfloops),
(3, "Dedupe edges", opts.dedupe_edges),
(4, "Remove isolates", opts.remove_isolates),
(5, "Merge node positions", opts.merge_node_positions),
(6, "Include polygons", opts.include_polygons),
(7, "Include points", opts.include_points),
(8, "Merge parallel edges", opts.merge_parallel_edges),
(
9,
"Merge parallel edge properties",
opts.merge_parallel_edge_properties,
),
];
let mut lines: Vec<ratatui::text::Line> = vec![
ratatui::text::Line::from(ratatui::text::Span::styled(
"Clean GeoJSON",
ratatui::style::Style::default()
.fg(cyan)
.add_modifier(ratatui::style::Modifier::BOLD),
)),
ratatui::text::Line::from(""),
ratatui::text::Line::from("Repair geometry, remove duplicates, keep largest component."),
ratatui::text::Line::from(""),
];
let input_display = match &app.clean_input_file {
Some(p) => {
ratatui::text::Span::styled(p.clone(), ratatui::style::Style::default().fg(green))
}
None => ratatui::text::Span::styled(
"(not set - press 'i')".to_string(),
ratatui::style::Style::default().fg(yellow),
),
};
let output_display = match &app.clean_output_file {
Some(p) => {
ratatui::text::Span::styled(p.clone(), ratatui::style::Style::default().fg(green))
}
None => ratatui::text::Span::styled(
"(auto-derived from input)".to_string(),
ratatui::style::Style::default().fg(gray),
),
};
lines.push(ratui_line(vec![span_raw("Input: "), input_display]));
lines.push(ratui_line(vec![span_raw("Output: "), output_display]));
lines.push(ratatui::text::Line::from(""));
lines.push(ratui_line(vec![
span_raw(" Min length (m): "),
span_val(format!("{:.1}", opts.min_length_m), sel == 10),
span_raw(" Node snap (m): "),
span_val(format!("{:.1}", opts.node_snap_m), sel == 11),
]));
lines.push(ratui_line(vec![
span_raw(" Max components: "),
span_val(format!("{}", opts.max_components), sel == 12),
span_raw(" Simplify tol (m): "),
span_val(format!("{:.1}", opts.simplify_tolerance_m), sel == 13),
]));
lines.push(ratui_line(vec![
span_raw(" Precision decimals: "),
span_val(format!("{}", opts.node_precision_decimals), sel == 14),
]));
lines.push(ratatui::text::Line::from(""));
lines.push(ratatui::text::Line::from(" Options:"));
for (idx, label, val) in &toggles {
let check = if *val { "[x]" } else { "[ ]" };
let style = if *idx == sel {
ratatui::style::Style::default()
.fg(yellow)
.add_modifier(ratatui::style::Modifier::BOLD)
} else {
ratatui::style::Style::default().fg(white)
};
lines.push(ratatui::text::Line::from(ratatui::text::Span::styled(
format!(" {} {} ", check, label),
style,
)));
}
lines.push(ratatui::text::Line::from(""));
let status_text = format!("Status: {}", app.clean_status);
let status_color = app.clean_status.color();
lines.push(ratui_line(vec![ratatui::text::Span::styled(
status_text,
ratatui::style::Style::default().fg(status_color),
)]));
if let Status::Done(ref msg) = app.clean_status {
if !msg.is_empty() {
lines.push(ratatui::text::Line::from(""));
for line in msg.lines() {
lines.push(ratatui::text::Line::from(format!(" {}", line)));
}
}
}
lines.push(ratatui::text::Line::from(""));
lines.push(ratui_line(vec![ratatui::text::Span::styled(
"Controls: ",
ratatui::style::Style::default().fg(cyan),
)]));
lines.push(ratatui::text::Line::from(
" [Space] Toggle option [Enter] Run clean",
));
lines.push(ratatui::text::Line::from(
" [I] Set input file [O] Set output file",
));
lines.push(ratatui::text::Line::from(
" [Esc] Return to home [R] Reset to defaults",
));
let paragraph = ratatui::widgets::Paragraph::new(lines);
f.render_widget(paragraph, inner);
super::draw_input_prompt(f, app, area);
}
fn span_raw(s: &str) -> ratatui::text::Span<'static> {
ratatui::text::Span::raw(s.to_string())
}
fn span_val(s: String, highlighted: bool) -> ratatui::text::Span<'static> {
if highlighted {
ratatui::text::Span::styled(
s,
ratatui::style::Style::default()
.fg(ratatui::style::Color::Yellow)
.add_modifier(ratatui::style::Modifier::BOLD),
)
} else {
ratatui::text::Span::styled(
s,
ratatui::style::Style::default().fg(ratatui::style::Color::Green),
)
}
}
fn ratui_line(spans: Vec<ratatui::text::Span<'static>>) -> ratatui::text::Line<'static> {
ratatui::text::Line::from(spans)
}