use crate::{characters::*, TengwarMode, ToTengwar, Transcriber};
#[allow(unused_variables)]
pub trait Policy: Copy {
fn ligates_with_ara(base: char) -> bool { false }
fn telco_ligates_with(base: char) -> bool { false }
fn ligature_valid<P: Policy>(
prev: &Glyph<Self>,
next: &Glyph<P>,
level: u8,
) -> bool { false }
fn nuquerna(base: char) -> char { base }
fn nuquerna_valid(base: char) -> bool { false }
fn rince(base: char, is_final: bool) -> Rince {
if is_final {
if Self::rince_valid_final(base) {
Rince::Final
} else {
Rince::Basic
}
} else {
Rince::Basic
}
}
fn rince_valid(base: char) -> bool { false }
fn rince_valid_final(base: char) -> bool { false }
fn transcriber<M>(input: impl ToTengwar) -> Transcriber<M, Self>
where M: TengwarMode + Default,
{
input.transcriber().set_policy()
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct NoPolicy;
impl Policy for NoPolicy {}
#[derive(Clone, Copy, Debug, Default)]
pub struct Standard;
impl Policy for Standard {
fn ligates_with_ara(base: char) -> bool {
match base {
TENGWA_TINCO..=TENGWA_ALDA => true,
TENGWA_SILME => true,
TENGWA_HYARMEN..=TENGWA_URE => true,
TENGWA_OSSE_REV..=TENGWA_OSSE => true,
TENGWA_ANNA_OPEN..=TENGWA_WAIA => true,
_ => false,
}
}
fn telco_ligates_with(base: char) -> bool {
match Tengwa::either_from(base) {
Tengwa::Regular(tengwa) => tengwa.tema.left || !tengwa.tyelle.stem_up,
Tengwa::Irregular(char) => match char {
TENGWA_ROMEN..=TENGWA_ESSE_NUQ => true,
TENGWA_ARA | TENGWA_TELCO => true,
TENGWA_ANNA_OPEN => true,
TENGWA_MALTA_HOOKED => true,
TENGWA_VALA_HOOKED => true,
_ => false,
}
}
}
fn ligature_valid<P: Policy>(
prev: &Glyph<Self>,
next: &Glyph<P>,
level: u8,
) -> bool {
const L_SILME: u8 = 2;
const L_SILME_MORE: u8 = 3;
const L_REGULARS: u8 = 3;
if level == 0 { return false; }
let lhs = *prev.parts().rhs();
let rhs = *next.parts().lhs();
let tengwar = (&lhs.tengwa, &rhs.tengwa);
let tehtar = (lhs.tehta, rhs.tehta);
match tengwar {
(Some(Tengwa::Irregular(TENGWA_SILME)), Some(rhs)) => {
let too_crowded: bool = match tehtar {
(Some(DC_OVER_DOT_1), Some(DC_OVER_DOT_1)) => false,
(Some(_), Some(_)) => true,
_ => false,
};
if too_crowded {
false
} else {
match rhs {
_ if level < L_SILME => false,
Tengwa::Regular(_) => true,
_ if level < L_SILME_MORE => false,
Tengwa::Irregular(TENGWA_SILME) => true,
Tengwa::Irregular(TENGWA_ESSE) => true,
Tengwa::Irregular(TENGWA_ROMEN) => true,
Tengwa::Irregular(TENGWA_ARDA) => true,
Tengwa::Irregular(TENGWA_LAMBE) => true,
Tengwa::Irregular(TENGWA_ALDA) => true,
Tengwa::Irregular(TENGWA_HALLA) => true,
Tengwa::Irregular(TENGWA_MALTA_HOOKED) => true,
Tengwa::Irregular(TENGWA_VALA_HOOKED) => true,
Tengwa::Irregular(TENGWA_LOWDHAM_HW) => true,
Tengwa::Irregular(_) => false,
}
}
}
(Some(Tengwa::Regular(lhs)), Some(Tengwa::Regular(rhs))) => {
L_REGULARS <= level
&& (lhs.tema.left && lhs.tyelle.is_ascending())
&& (!rhs.tema.left && rhs.tyelle.is_descending())
}
_ => false,
}
}
fn nuquerna(base: char) -> char {
match base {
TENGWA_SILME => TENGWA_SILME_NUQ,
TENGWA_ESSE => TENGWA_ESSE_NUQ,
other => other,
}
}
fn nuquerna_valid(base: char) -> bool {
base == TENGWA_SILME || base == TENGWA_ESSE
}
fn rince_valid(base: char) -> bool {
match base {
TENGWA_ROMEN | TENGWA_ARDA
| TENGWA_SILME | TENGWA_SILME_NUQ
| TENGWA_ESSE | TENGWA_ESSE_NUQ => false,
_ => true,
}
}
fn rince_valid_final(base: char) -> bool {
match base {
TENGWA_LAMBE | TENGWA_ALDA | TENGWA_HYARMEN => true,
tengwa if TEMA_TINCO.contains(tengwa) => true,
tengwa if TEMA_PARMA.contains(tengwa) => true,
_ => false,
}
}
}