use crate::io::print::{TH, TW};
use crate::layout::coord::{current, CoordMode};
use parking_lot::RwLock;
use std::sync::LazyLock;
static GRID_CONFIG: RwLock<(u32, u32)> = RwLock::new((1, 1));
pub static CW: LazyLock<u32> = LazyLock::new(|| {
let (cell_w, _) = cell_size();
cell_w as u32
});
pub static CH: LazyLock<u32> = LazyLock::new(|| {
let (_, cell_h) = cell_size();
cell_h as u32
});
pub fn grid(rows: u32, cols: u32) {
*GRID_CONFIG.write() = (rows.max(1), cols.max(1));
}
pub fn grid_size() -> (u32, u32) {
*GRID_CONFIG.read()
}
pub fn cell_size() -> (f64, f64) {
let tw = *TW as f64;
let th = *TH as f64;
let (rows, cols) = grid_size();
(tw / cols as f64, th / rows as f64)
}
pub fn size_pct(width_pct: u32, height_pct: u32) -> (u32, u32) {
let w = (*CW as f64 * width_pct as f64 / 100.0) as u32;
let h = (*CH as f64 * height_pct as f64 / 100.0) as u32;
(w, h)
}
pub trait Sizable {
fn set_size(&mut self, size: (u32, u32));
fn size(mut self, width_pct: u32, height_pct: u32) -> Self
where
Self: Sized,
{
let (w, h) = size_pct(width_pct, height_pct);
self.set_size((w, h));
self
}
}
pub fn cell(r: u32, c: u32, pos: &str) -> (f64, f64) {
let tw = *TW as f64;
let th = *TH as f64;
let (rows, cols) = grid_size();
let cell_w = tw / cols as f64;
let cell_h = th / rows as f64;
let (h_factor, v_factor) = match pos {
"top left" | "tl" => (0.0, 0.0),
"top center" | "top" | "tc" => (0.5, 0.0),
"top right" | "tr" => (1.0, 0.0),
"middle left" | "left" | "ml" => (0.0, 0.5),
"middle center" | "center" | "mc" => (0.5, 0.5),
"middle right" | "right" | "mr" => (1.0, 0.5),
"bottom left" | "bl" => (0.0, 0.85),
"bottom center" | "bottom" | "bc" => (0.5, 0.85),
"bottom right" | "br" => (1.0, 0.85),
_ => (0.5, 0.5),
};
match current() {
CoordMode::Cartesian => (
-tw / 2.0 + cell_w * (c as f64 + h_factor),
th / 2.0 - cell_h * (r as f64 + v_factor),
),
CoordMode::Css => (
cell_w * (c as f64 + h_factor),
cell_h * (r as f64 + v_factor),
),
}
}