use crate::commands::do_split;
use crate::ffi::util::{slice_from, slice_mut_from, state_mut, state_ref};
use std::ffi::c_void;
#[no_mangle]
pub extern "C" fn ratatui_root_area(_handle: *const c_void) -> u32 { 0 }
#[no_mangle]
pub extern "C" fn ratatui_split(
handle: *mut c_void,
area_id: u32,
direction: u8,
constraint_types: *const u8,
constraint_values: *const u16,
count: u32,
out_ids: *mut u32,
) -> u32 {
if count == 0
|| constraint_types.is_null()
|| constraint_values.is_null()
|| out_ids.is_null()
{
return 0;
}
let Some(state) = state_mut(handle) else { return 0; };
let n = count as usize;
let types = slice_from(constraint_types, n);
let values = slice_from(constraint_values, n);
let Some(out) = slice_mut_from(out_ids, n) else { return 0; };
do_split(state, area_id, direction, types, values, out)
}
#[no_mangle]
pub extern "C" fn ratatui_inner(
handle: *mut c_void,
area_id: u32,
horizontal: u16,
vertical: u16,
) -> u32 {
let Some(state) = state_mut(handle) else { return u32::MAX; };
let area = match state.area_map.get(&area_id).copied() {
Some(r) => r,
None => return u32::MAX,
};
use ratatui::layout::Margin;
let inner = area.inner(Margin { horizontal, vertical });
state.register_area(inner)
}
#[no_mangle]
pub extern "C" fn ratatui_hit_test(
handle: *mut c_void,
col: u16,
row: u16,
) -> u32 {
let Some(state) = state_mut(handle) else { return 0; };
let mut best_id = 0u32;
let mut best_area = u32::MAX;
for (&id, &rect) in &state.area_map {
if col >= rect.x && col < rect.x + rect.width
&& row >= rect.y && row < rect.y + rect.height
{
let area = (rect.width as u32) * (rect.height as u32);
if area < best_area {
best_area = area;
best_id = id;
}
}
}
best_id
}
#[no_mangle]
pub extern "C" fn ratatui_get_area_rect(
handle: *const c_void,
area_id: u32,
) -> u64 {
let Some(state) = state_ref(handle) else { return 0; };
match state.area_map.get(&area_id) {
Some(rect) => {
(rect.x as u64)
| ((rect.y as u64) << 16)
| ((rect.width as u64) << 32)
| ((rect.height as u64) << 48)
}
None => 0,
}
}