use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};
use alloc::string::{String, ToString};
use crate::astronomy::planets::{sun_longitude, moon_longitude};
use crate::astronomy::ayanamsha::{AyanamshaMode, get_ayanamsha, tropical_to_sidereal};
use crate::astronomy::solver::find_angle_crossing;
pub const YOGA_NAMES: [&str; 27] = [
"Vishkumbha", "Priti", "Ayushman", "Saubhagya", "Shobhana",
"Atiganda", "Sukarman", "Dhriti", "Shula", "Ganda",
"Vriddhi", "Dhruva", "Vyaghata", "Harshana", "Vajra",
"Siddhi", "Vyatipata", "Variyana", "Parigha", "Shiva",
"Siddha", "Sadhya", "Shubha", "Shukla", "Brahma",
"Indra", "Vaidhriti",
];
#[derive(Debug, Clone, Serialize, Deserialize)]
#[wasm_bindgen(getter_with_clone)]
pub struct YogaInfo {
pub index: u8,
pub name: String,
}
#[wasm_bindgen]
pub fn calculate_yoga(jd: f64, ayanamsha_mode: AyanamshaMode) -> YogaInfo {
let sun_tropical = sun_longitude(jd);
let moon_tropical = moon_longitude(jd);
let ayanamsha = get_ayanamsha(ayanamsha_mode, jd);
let sun_sidereal = tropical_to_sidereal(sun_tropical, ayanamsha);
let moon_sidereal = tropical_to_sidereal(moon_tropical, ayanamsha);
let mut sum = sun_sidereal + moon_sidereal;
if sum >= 360.0 {
sum -= 360.0;
}
let yoga_span = 360.0 / 27.0;
let yoga_index = (sum / yoga_span).floor() as u8 + 1;
YogaInfo {
index: yoga_index,
name: YOGA_NAMES[(yoga_index - 1) as usize].to_string(),
}
}
#[wasm_bindgen]
pub fn yoga_end_time(jd: f64, ayanamsha_mode: AyanamshaMode) -> f64 {
let current = calculate_yoga(jd, ayanamsha_mode);
let yoga_span = 360.0 / 27.0;
let target_angle = current.index as f64 * yoga_span;
let start_search = jd;
let end_search = jd + 1.0;
find_angle_crossing(
|t| {
let sl = sun_longitude(t);
let ml = moon_longitude(t);
let ayan = get_ayanamsha(ayanamsha_mode, t);
let sl_sid = tropical_to_sidereal(sl, ayan);
let ml_sid = tropical_to_sidereal(ml, ayan);
let mut sum = sl_sid + ml_sid;
if sum >= 360.0 { sum -= 360.0; }
sum
},
start_search,
end_search,
target_angle
).unwrap_or(jd)
}
#[wasm_bindgen]
pub fn yoga_start_time(jd: f64, ayanamsha_mode: AyanamshaMode) -> f64 {
let current = calculate_yoga(jd, ayanamsha_mode);
let yoga_span = 360.0 / 27.0;
let target_angle = (current.index as f64 - 1.0) * yoga_span;
let start_search = jd - 1.0;
let end_search = jd;
find_angle_crossing(
|t| {
let sl = sun_longitude(t);
let ml = moon_longitude(t);
let ayan = get_ayanamsha(ayanamsha_mode, t);
let sl_sid = tropical_to_sidereal(sl, ayan);
let ml_sid = tropical_to_sidereal(ml, ayan);
let mut sum = sl_sid + ml_sid;
if sum >= 360.0 { sum -= 360.0; }
sum
},
start_search,
end_search,
target_angle
).unwrap_or(jd)
}