use crate::{Vec3, Star};
use crate::{rpot_val, rpot_grad, ref_sphere, sphere_eclipse_vector, dbrent};
pub fn fblink(q: f64, star: Star, spin: f64, ffac: f64, acc: f64, earth: &Vec3, p: &Vec3) -> Result<bool, &'static str> {
let (rref, pref) = ref_sphere(q, star, spin, ffac);
let cofm: Vec3 = match star {
Star::Primary => Vec3::cofm1(),
Star::Secondary => Vec3::cofm2(),
};
let mut lam1 = 0.0;
let mut lam2 = 0.0;
if !sphere_eclipse_vector(earth, p, &cofm, rref, &mut lam1, &mut lam2) {
return Ok(false);
}
if lam1 == 0.0 {
return Ok(true);
}
let func = |lam: f64| {
rpot_val(q, star, spin, earth, p, lam)
};
let mut nstep: i32 = 1;
let mut step: f64 = lam2 - lam1;
let mut f1: f64 = 0.0;
let mut f2: f64 = 0.0;
let mut flam: f64 = 1.0;
let mut lam: f64 = lam1;
while step > acc {
lam = lam1 + step/2.0;
for _ in 0..nstep {
flam = func(lam);
if flam <= pref {
return Ok(true);
}
if nstep == 1 {
f1 = func(lam1);
f2 = func(lam2);
}
if flam < f1 && flam < f2 {
break;
}
lam += step;
}
if flam < f1 && flam < f2 {
break;
}
step /= 2.0;
nstep *= 2;
}
if flam < f1 && flam < f2 {
let dfunc = |lam: f64| {
let (_dp, dl) = rpot_grad(q, star, spin, earth, p, lam);
dl
};
let (_xmin, flam) = dbrent(lam1, lam, lam2, |x| func(x), |x| dfunc(x), acc, true, pref)?;
Ok(flam < pref)
} else {
Ok(false)
}
}