use crossterm::event::MouseEvent;
use rdom_core::{NodeId, Position, Selection};
use crate::TuiDom;
use crate::node::{TuiNodeExt, first_text_descendant, last_text_descendant, text_len};
pub(crate) use crate::style::user_select::{
all_host, contain_host, is_unselectable, resolve_child, used_value,
};
pub(crate) fn span_all_text(dom: &TuiDom, host: NodeId) -> Option<Selection> {
let first = first_text_descendant(dom, host)?;
let last = last_text_descendant(dom, host).unwrap_or(first);
let end = text_len(dom, last);
Some(Selection::new(
Position::new(first, 0),
Position::new(last, end),
))
}
pub(crate) fn clamp_to_contain_host(
dom: &TuiDom,
host: NodeId,
mouse: MouseEvent,
) -> Option<Position> {
use crate::runtime::hit_test::{nearest_inline_target_in_subtree, resolve_in_target};
if let Some(target) = nearest_inline_target_in_subtree(dom, host, mouse.row)
&& let Some(pos) = resolve_in_target(dom, target, mouse.column, mouse.row)
{
return Some(pos);
}
let rect = dom.node(host).layout_rect()?;
let below = (mouse.row as i32) >= rect.y + rect.height as i32;
let above = (mouse.row as i32) < rect.y;
let want_end = if below {
true
} else if above {
false
} else {
(mouse.column as i32) >= rect.x + rect.width as i32
};
if want_end {
let node = last_text_descendant(dom, host)?;
Some(Position::new(node, text_len(dom, node)))
} else {
let node = first_text_descendant(dom, host)?;
Some(Position::new(node, 0))
}
}