use std::collections::HashMap;
use yog_sync::{LazyLock, RwLock};
use super::{BOOK_SHEET, LANG};
pub(crate) type Translator = fn(&str) -> Option<String>;
static TRANSLATOR: RwLock<Option<Translator>> = RwLock::new(None);
const WORD_PREFIX: &str = "yog.book.";
const ARGUMENT: &str = "%s";
const ENTITY_KEY: &str = "entity";
const ORDINALS: usize = 4;
const TEENS: std::ops::RangeInclusive<u32> = 11..=13;
const HUNDRED: u32 = 100;
const TEN: u32 = 10;
pub(crate) fn set_translator(tr: Translator) {
*TRANSLATOR.write() = Some(tr);
}
fn translator() -> Option<Translator> {
*TRANSLATOR.read()
}
fn translated(key: &str) -> Option<String> {
translator().and_then(|tr| tr(key)).filter(|t| t != key)
}
pub(crate) fn word(key: &str, arg: &str) -> String {
let k = format!("{WORD_PREFIX}{key}");
let text = translated(&k).or_else(|| {
static EN: LazyLock<HashMap<String, String>> =
LazyLock::new(|| serde_json::from_str(LANG[0].1).unwrap_or_default());
EN.get(&k).cloned()
});
text.unwrap_or(k).replace(ARGUMENT, arg)
}
fn name_from_path(path: &str) -> String {
path.rsplit(yog_ids::sep::PATH)
.flat_map(|seg| seg.split('_'))
.filter(|w| !w.is_empty())
.map(|w| {
let mut c = w.chars();
c.next()
.map(|f| f.to_uppercase().collect::<String>() + c.as_str())
.unwrap_or_default()
})
.collect::<Vec<_>>()
.join(" ")
}
pub(crate) fn ordinal(n: u32) -> String {
let suffixes = word("ordinals", "");
let s: Vec<&str> = suffixes.split_whitespace().collect();
if s.len() < ORDINALS {
return n.to_string();
}
let i = match (n % HUNDRED, n % TEN) {
(teen, _) if TEENS.contains(&teen) => 0,
(_, last) if (1..ORDINALS as u32).contains(&last) => last as usize,
_ => 0,
};
format!("{n}{}", s[i])
}
fn parts(id: &str) -> (&str, &str) {
id.split_once(yog_ids::sep::NAMESPACE)
.unwrap_or((yog_ids::ns::MINECRAFT, id))
}
pub(crate) fn entity_name(id: &str) -> String {
let (ns, path) = parts(id);
translated(&format!(
"{ENTITY_KEY}.{ns}.{}",
path.replace(yog_ids::sep::PATH, ".")
))
.unwrap_or_else(|| name_from_path(path))
}
pub(crate) fn pretty_item_name(id: &str) -> String {
let (ns, path) = parts(id);
let key = path.replace(yog_ids::sep::PATH, ".");
[yog_ids::kind::ITEM, yog_ids::kind::BLOCK]
.iter()
.find_map(|kind| translated(&format!("{kind}.{ns}.{key}")))
.unwrap_or_else(|| name_from_path(path))
}
pub(crate) fn book_sheet(texture: &str) -> String {
let t = texture.trim();
if t.is_empty() || t == yog_ids::yog::BOOK_TEXTURE {
return BOOK_SHEET.to_string();
}
yog_gfx::image::short_source(t)
}