use crate::astro::context::{self, AstroContext};
use crate::astro::palace::get_five_elements_class;
use crate::data::stars::StarKey;
use crate::data::types::*;
use crate::error::IztroError;
use crate::models::star::Star;
use crate::star::decorative;
use crate::star::location::{
self, ChangQu, DailyStar, KongJie, KuiYue, LuYangTuoMa, LuanXi, MonthlyStar, StartIndex,
TimelyStars, YearlyStars,
};
pub struct StarParam<'a> {
pub solar_date: &'a str,
pub time_index: u8,
pub gender: Gender,
pub fix_leap: bool,
pub from: Option<(HeavenlyStem, EarthlyBranch)>,
pub language: Language,
pub config: &'a Config,
}
impl StarParam<'_> {
fn derive(&self) -> Result<AstroContext, IztroError> {
context::derive(self.solar_date, self.time_index, self.fix_leap, self.config)
}
fn five_elements_class(&self, ctx: &AstroContext) -> FiveElementsClass {
match self.from {
Some((stem, branch)) => get_five_elements_class(stem, branch),
None => ctx.five_elements_class,
}
}
}
pub fn get_start_index(param: &StarParam) -> Result<StartIndex, IztroError> {
let ctx = param.derive()?;
Ok(location::get_start_index(
ctx.lunar_day,
ctx.effective_time_index,
ctx.month_day_count,
param.five_elements_class(&ctx).value() as u32,
))
}
pub fn get_lu_yang_tuo_ma_index(param: &StarParam) -> Result<LuYangTuoMa, IztroError> {
let ctx = param.derive()?;
Ok(location::get_lu_yang_tuo_ma_index(
ctx.yearly_stem,
ctx.yearly_branch,
))
}
pub fn get_kui_yue_index(param: &StarParam) -> Result<KuiYue, IztroError> {
let ctx = param.derive()?;
Ok(location::get_kui_yue_index(ctx.yearly_stem))
}
pub fn get_chang_qu_index(param: &StarParam) -> Result<ChangQu, IztroError> {
let ctx = param.derive()?;
Ok(location::get_chang_qu_index(ctx.effective_time_index))
}
pub fn get_kong_jie_index(param: &StarParam) -> Result<KongJie, IztroError> {
let ctx = param.derive()?;
Ok(location::get_kong_jie_index(ctx.effective_time_index))
}
pub fn get_timely_star_index(param: &StarParam) -> Result<TimelyStars, IztroError> {
let ctx = param.derive()?;
Ok(location::get_timely_star_index(ctx.effective_time_index))
}
pub fn get_luan_xi_index(param: &StarParam) -> Result<LuanXi, IztroError> {
let ctx = param.derive()?;
Ok(location::get_luan_xi_index(ctx.yearly_branch))
}
pub fn get_daily_star_index(param: &StarParam) -> Result<DailyStar, IztroError> {
let ctx = param.derive()?;
let zuo_you = location::get_zuo_you_index(ctx.month_index as u32 + 1);
let chang_qu = location::get_chang_qu_index(ctx.effective_time_index);
Ok(location::get_daily_star_index(
ctx.lunar_day,
ctx.effective_time_index,
zuo_you.zuo,
zuo_you.you,
chang_qu.chang,
chang_qu.qu,
))
}
pub fn get_monthly_star_index(param: &StarParam) -> Result<MonthlyStar, IztroError> {
let ctx = param.derive()?;
Ok(location::get_monthly_star_index(ctx.month_index))
}
pub fn get_yearly_star_index(param: &StarParam) -> Result<YearlyStars, IztroError> {
let ctx = param.derive()?;
Ok(location::get_yearly_star_index(
ctx.soul_body.soul_index,
ctx.soul_body.body_index,
ctx.flow_yearly_stem,
ctx.flow_yearly_branch,
param.gender,
param.config.algorithm,
))
}
pub fn get_major_stars(param: &StarParam) -> Result<[Vec<Star>; 12], IztroError> {
let ctx = param.derive()?;
let start = get_start_index(param)?;
Ok(crate::star::major::get_major_stars(
start.ziwei,
start.tianfu,
ctx.yearly_stem,
param.language,
param.config,
))
}
pub fn get_minor_stars(param: &StarParam) -> Result<[Vec<Star>; 12], IztroError> {
let ctx = param.derive()?;
let zuo_you = location::get_zuo_you_index(ctx.month_index as u32 + 1);
let chang_qu = location::get_chang_qu_index(ctx.effective_time_index);
let kui_yue = location::get_kui_yue_index(ctx.yearly_stem);
let lu_yang_tuo_ma = location::get_lu_yang_tuo_ma_index(ctx.yearly_stem, ctx.yearly_branch);
let kong_jie = location::get_kong_jie_index(ctx.effective_time_index);
let huo_ling = location::get_huo_ling_index(ctx.yearly_branch, ctx.effective_time_index);
Ok(crate::star::minor::get_minor_stars(
zuo_you.zuo,
zuo_you.you,
chang_qu.chang,
chang_qu.qu,
kui_yue.kui,
kui_yue.yue,
lu_yang_tuo_ma.lu,
lu_yang_tuo_ma.yang,
lu_yang_tuo_ma.tuo,
lu_yang_tuo_ma.ma,
kong_jie.kong,
kong_jie.jie,
huo_ling.huo,
huo_ling.ling,
ctx.yearly_stem,
param.language,
param.config,
))
}
pub fn get_adjective_stars(param: &StarParam) -> Result<[Vec<Star>; 12], IztroError> {
let ctx = param.derive()?;
let yearly_stars = get_yearly_star_index(param)?;
let monthly_stars = location::get_monthly_star_index(ctx.month_index);
let daily_stars = get_daily_star_index(param)?;
let timely_stars = location::get_timely_star_index(ctx.effective_time_index);
let luan_xi = location::get_luan_xi_index(ctx.yearly_branch);
let (suiqian12, _) = decorative::get_yearly12(ctx.flow_yearly_branch, param.config.algorithm);
Ok(crate::star::adjective::get_adjective_stars(
&yearly_stars,
&monthly_stars,
&daily_stars,
timely_stars.taifu,
timely_stars.fenggao,
luan_xi.hongluan,
luan_xi.tianxi,
yearly_stars.xianchi,
&suiqian12,
param.config.algorithm,
param.language,
))
}
pub fn get_changsheng12(param: &StarParam) -> Result<[StarKey; 12], IztroError> {
let ctx = param.derive()?;
Ok(decorative::get_changsheng12(
param.five_elements_class(&ctx),
param.gender,
ctx.yearly_branch,
))
}
pub fn get_boshi12(param: &StarParam) -> Result<[StarKey; 12], IztroError> {
let ctx = param.derive()?;
let lu_yang_tuo_ma = location::get_lu_yang_tuo_ma_index(ctx.yearly_stem, ctx.yearly_branch);
Ok(decorative::get_boshi12(
lu_yang_tuo_ma.lu,
param.gender,
ctx.yearly_branch,
))
}
pub fn get_yearly12(param: &StarParam) -> Result<([StarKey; 12], [StarKey; 12]), IztroError> {
let ctx = param.derive()?;
Ok(decorative::get_yearly12(
ctx.flow_yearly_branch,
param.config.algorithm,
))
}