use crate::core::pattern::relation::{clamp_branches, san_fang_si_zheng};
use crate::core::{Brightness, Chart, EarthlyBranch, StarKind, StarName, StarPlacement};
pub fn stars_in_palace(chart: &Chart, branch: EarthlyBranch) -> Vec<&StarPlacement> {
chart
.palaces()
.iter()
.filter(|palace| palace.branch() == branch)
.flat_map(|palace| palace.stars().iter())
.collect()
}
pub fn palace_has_star(chart: &Chart, branch: EarthlyBranch, star: StarName) -> bool {
stars_in_palace(chart, branch)
.iter()
.any(|placement| placement.name() == star)
}
pub fn find_star_branch(chart: &Chart, star: StarName) -> Option<EarthlyBranch> {
chart.star(star).map(|fact| fact.palace().branch())
}
pub fn stars_in_san_fang_si_zheng(
chart: &Chart,
anchor: EarthlyBranch,
stars: &[StarName],
) -> Vec<(StarName, EarthlyBranch)> {
let mut found = Vec::new();
for branch in san_fang_si_zheng(anchor) {
for placement in stars_in_palace(chart, branch) {
if stars.contains(&placement.name()) {
found.push((placement.name(), branch));
}
}
}
found
}
pub fn clamp_pair_matches(
chart: &Chart,
anchor: EarthlyBranch,
left_star: StarName,
right_star: StarName,
) -> Option<[(StarName, EarthlyBranch); 2]> {
let [low, high] = clamp_branches(anchor);
if palace_has_star(chart, low, left_star) && palace_has_star(chart, high, right_star) {
Some([(left_star, low), (right_star, high)])
} else if palace_has_star(chart, low, right_star) && palace_has_star(chart, high, left_star) {
Some([(right_star, low), (left_star, high)])
} else {
None
}
}
pub fn is_bright(brightness: Brightness) -> bool {
matches!(
brightness,
Brightness::Temple
| Brightness::Prosperous
| Brightness::Advantage
| Brightness::Favourable
)
}
pub fn is_dim(brightness: Brightness) -> bool {
matches!(brightness, Brightness::Weak | Brightness::Trapped)
}
pub fn any_sha_star_in_palace(chart: &Chart, branch: EarthlyBranch) -> bool {
stars_in_palace(chart, branch)
.iter()
.any(|placement| placement.kind() == StarKind::Tough)
}