use lunar_rust::lunar_month::{self, LunarMonthRefHelper};
use crate::astro::palace::{get_decadals_and_ages, get_five_elements_class, get_palace_names};
use crate::data::earthly_branches::get_earthly_branch_info;
use crate::data::stars::StarKey;
use crate::data::types::*;
use crate::i18n::translate_star;
use crate::models::astrolabe::Astrolabe;
use crate::models::star::Star;
use crate::star::decorative::get_changsheng12;
use crate::star::location::{get_start_index, get_tiancai_index, get_tianshang_tianshi_index};
use crate::star::major::get_major_stars;
use crate::utils::{earthly_branch_to_palace_index, fix_index};
const BODY_OFFSET: [usize; 13] = [0, 2, 4, 6, 8, 10, 0, 2, 4, 6, 8, 10, 0];
impl Astrolabe {
pub fn rearranged(&self, from_stem: HeavenlyStem, from_branch: EarthlyBranch) -> Astrolabe {
let mut chart = self.clone();
let effective_ti = if self.config.day_divide == DayDivide::Current && self.time_index >= 12
{
0
} else {
self.time_index
};
let soul_index = earthly_branch_to_palace_index(from_branch);
let body_index = fix_index((BODY_OFFSET[effective_ti as usize] + soul_index) as i32, 12);
let five_elements_class = get_five_elements_class(from_stem, from_branch);
let palace_names = get_palace_names(soul_index);
let lunar = self.raw_dates.lunar_date;
let signed_month = if lunar.is_leap {
-(lunar.lunar_month as i64)
} else {
lunar.lunar_month as i64
};
let month_day_count =
lunar_month::from_ym(lunar.lunar_year, signed_month).get_day_count() as u32;
let start_idx = get_start_index(
lunar.lunar_day,
effective_ti,
month_day_count,
five_elements_class.value() as u32,
);
let (yearly_stem, yearly_branch) = self.raw_dates.chinese_date.yearly;
let major_stars = get_major_stars(
start_idx.ziwei,
start_idx.tianfu,
yearly_stem,
self.language,
&self.config,
);
let changsheng12 = get_changsheng12(five_elements_class, self.gender, yearly_branch);
let (decadals, ages) = get_decadals_and_ages(
soul_index,
five_elements_class,
self.gender,
yearly_stem,
yearly_branch,
);
let (tianshang_index, tianshi_index) = get_tianshang_tianshi_index(
self.gender,
yearly_branch,
soul_index,
self.config.algorithm,
);
let tiancai_index = get_tiancai_index(yearly_branch, soul_index);
for (i, palace) in chart.palaces.iter_mut().enumerate() {
relocate_adjective_star(
&mut palace.adjective_stars,
StarKey::Tianshang,
i == tianshang_index,
self.language,
);
relocate_adjective_star(
&mut palace.adjective_stars,
StarKey::Tianshi,
i == tianshi_index,
self.language,
);
relocate_adjective_star(
&mut palace.adjective_stars,
StarKey::Tiancai,
i == tiancai_index,
self.language,
);
palace.name = palace_names[i];
palace.major_stars = major_stars[i].clone();
palace.changsheng12 = changsheng12[i];
palace.decadal = decadals[i].clone();
palace.ages = ages[i].clone();
palace.is_body_palace = body_index == i;
}
chart.five_elements_class = five_elements_class;
chart.earthly_branch_of_soul_palace = chart.palaces[soul_index].earthly_branch;
chart.earthly_branch_of_body_palace = chart.palaces[body_index].earthly_branch;
if self.config.algorithm != Algorithm::Zhongzhou {
chart.soul = get_earthly_branch_info(chart.earthly_branch_of_soul_palace).soul;
}
chart
}
}
fn relocate_adjective_star(
stars: &mut Vec<Star>,
key: StarKey,
should_be_here: bool,
lang: Language,
) {
match (stars.iter().position(|s| s.key == key), should_be_here) {
(Some(pos), false) => {
stars.remove(pos);
}
(None, true) => stars.push(Star {
key,
name: translate_star(key, lang).to_string(),
star_type: StarType::Adjective,
scope: Scope::Origin,
brightness: None,
mutagen: None,
}),
_ => {}
}
}