use crate::tui::plan::{PlanTask, TaskStatus};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct VisibleWindow {
pub start: usize,
pub len: usize,
}
pub(crate) fn current_task_index(tasks: &[PlanTask]) -> usize {
if let Some(i) = tasks
.iter()
.position(|t| matches!(t.status, TaskStatus::InProgress))
{
return i;
}
if let Some(i) = tasks.iter().position(|t| {
matches!(
t.status,
TaskStatus::Pending | TaskStatus::Blocked(_) | TaskStatus::Failed
)
}) {
return i;
}
tasks.len().saturating_sub(1)
}
pub(crate) fn pick_visible_window(
total: usize,
available_rows: usize,
anchor: usize,
) -> VisibleWindow {
if total == 0 || available_rows == 0 {
return VisibleWindow { start: 0, len: 0 };
}
if total <= available_rows {
return VisibleWindow {
start: 0,
len: total,
};
}
let task_slots = available_rows.saturating_sub(2).max(1);
let half = task_slots / 2;
let mut start = anchor.saturating_sub(half);
let max_start = total.saturating_sub(task_slots);
if start > max_start {
start = max_start;
}
let mut len = task_slots;
if start == 0 {
len = (len + 1).min(total);
}
if start + len == total && start > 0 {
start = start.saturating_sub(1);
len += 1;
if anchor < start {
start = anchor;
}
}
VisibleWindow { start, len }
}