use crate::core::error::ChartError;
use crate::core::model::chart::{
Chart, DecadalPeriod, HoroscopeChart, TemporalContext, TemporalLayer, TemporalPalaceLayout,
TemporalPalaceName, build_decadal_frame,
};
use crate::core::model::star::mutagen::Scope;
use crate::core::placement::overlay::decadal::{
DecadalMutagenLayerInput, build_decadal_mutagen_layer,
};
use crate::core::placement::overlay::flow::build_flow_star_layer;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct DecadalHoroscopeInput {
pub period_index: usize,
}
pub fn build_decadal_horoscope_layer(
natal: &Chart,
period: &DecadalPeriod,
) -> Result<TemporalLayer, ChartError> {
let context = TemporalContext::Decadal {
stem_branch: period.stem_branch(),
start_age: period.start_age(),
};
let flow_layer = build_flow_star_layer(context)?;
let mutagen_layer = build_decadal_mutagen_layer(
natal,
DecadalMutagenLayerInput::new(period.stem_branch(), period.start_age()),
)?;
let palace_layout = build_decadal_palace_layout(natal, period)?;
TemporalLayer::try_new_with_palace_layout(
Scope::Decadal,
context,
flow_layer.placements().to_vec(),
mutagen_layer.activations().to_vec(),
Some(palace_layout),
)
}
fn build_decadal_palace_layout(
natal: &Chart,
period: &DecadalPeriod,
) -> Result<TemporalPalaceLayout, ChartError> {
let shift = period.palace_name().index() as isize;
let names = natal
.palaces()
.iter()
.map(|palace| TemporalPalaceName::new(palace.branch(), palace.name().offset(-shift)))
.collect();
TemporalPalaceLayout::try_new(Scope::Decadal, names)
}
pub fn build_decadal_horoscope_chart(
natal: Chart,
input: DecadalHoroscopeInput,
) -> Result<HoroscopeChart, ChartError> {
let frame = build_decadal_frame(&natal)?;
let period =
frame
.periods()
.get(input.period_index)
.ok_or(ChartError::InvalidDecadalPeriodIndex {
index: input.period_index,
len: frame.periods().len(),
})?;
let layer = build_decadal_horoscope_layer(&natal, period)?;
Ok(HoroscopeChart::with_layers(natal, vec![layer]))
}