//! Shared pool-recycling math for virtual scrolling widgets.
//!
//! Both [`handle_virtual_list`] and [`handle_data_grid`] need to compute
//! which contiguous slice of `total_items` is visible inside their pool of
//! reused widget rows, plus the spacer heights needed to keep the scroll
//! area's content height accurate. The math is identical between them; this
//! module centralises it.
//!
//! Free function, plain data in and out, no traits or methods.

#[derive(Clone, Copy, Debug)]
pub struct PoolWindow {
    /// Index of the first item visible in the pool.
    pub visible_start: usize,
    /// Height of the top spacer needed to position pool rows correctly.
    pub top_height: f32,
    /// Height of the bottom spacer.
    pub bottom_height: f32,
}

/// Compute pool window bounds + spacer heights for a virtual scroller.
///
/// `scroll_offset` and `item_height` are in logical pixels.
pub fn compute(
    scroll_offset: f32,
    item_height: f32,
    total_items: usize,
    pool_size: usize,
) -> PoolWindow {
    let visible_start = if item_height > 0.0 {
        (scroll_offset / item_height).floor() as usize
    } else {
        0
    };
    let visible_start = visible_start.min(total_items.saturating_sub(pool_size));
    let visible_end = total_items.min(visible_start + pool_size);
    let top_height = visible_start as f32 * item_height;
    let bottom_height = total_items.saturating_sub(visible_end) as f32 * item_height;
    PoolWindow {
        visible_start,
        top_height,
        bottom_height,
    }
}
