use crate::astronomical::core::JulianDay;
use crate::astronomical::lunar::tithi::TithiCalculator;
use crate::astronomical::solar::sankranti::SankrantiFinder;
pub struct LeapMonthDetector;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct AdhikaMasa {
pub month_index: u8,
pub start_jd: JulianDay,
pub end_jd: JulianDay,
}
impl LeapMonthDetector {
pub fn find_adhika_masa(bs_year: i32) -> Result<Vec<AdhikaMasa>, String> {
let mut results = Vec::new();
let sankrantis = SankrantiFinder::find_all_in_year(bs_year)?;
for i in 0..11 {
let start_s = sankrantis[i].julian_day;
let end_s = sankrantis[i + 1].julian_day;
if let Some(adhika) = Self::check_interval(i as u8 + 1, start_s, end_s)? {
results.push(adhika);
}
}
let next_mesh =
SankrantiFinder::find_sankranti(0, sankrantis[11].julian_day.add_days(25.0))?;
if let Some(adhika) =
Self::check_interval(12, sankrantis[11].julian_day, next_mesh.julian_day)?
{
results.push(adhika);
}
Ok(results)
}
fn check_interval(
month_idx: u8,
start_s: JulianDay,
end_s: JulianDay,
) -> Result<Option<AdhikaMasa>, String> {
let nm1 = TithiCalculator::find_next_new_moon(start_s)?;
if nm1.0 < end_s.0 {
let nm2 = TithiCalculator::find_next_new_moon(nm1)?;
if nm2.0 < end_s.0 {
return Ok(Some(AdhikaMasa {
month_index: month_idx,
start_jd: nm1,
end_jd: nm2,
}));
}
}
Ok(None)
}
}