use crate::constants::{PI, TWO_PI};
use crate::{DpperInit, DpperOpsMode, SatRec};
pub struct DpperOption {
pub init: DpperInit,
pub opsmode: DpperOpsMode,
pub ep: f64,
pub inclp: f64,
pub nodep: f64,
pub argpp: f64,
pub mp: f64,
}
pub struct DpperResult {
pub ep: f64,
pub inclp: f64,
pub nodep: f64,
pub argpp: f64,
pub mp: f64,
}
pub fn dpper(satrec: &SatRec, options: &DpperOption) -> DpperResult {
let e3 = satrec.e3;
let ee2 = satrec.ee2;
let peo = satrec.peo;
let pgho = satrec.pgho;
let pho = satrec.pho;
let pinco = satrec.pinco;
let plo = satrec.plo;
let se2 = satrec.se2;
let se3 = satrec.se3;
let sgh2 = satrec.sgh2;
let sgh3 = satrec.sgh3;
let sgh4 = satrec.sgh4;
let sh2 = satrec.sh2;
let sh3 = satrec.sh3;
let si2 = satrec.si2;
let si3 = satrec.si3;
let sl2 = satrec.sl2;
let sl3 = satrec.sl3;
let sl4 = satrec.sl4;
let t = satrec.t;
let xgh2 = satrec.xgh2;
let xgh3 = satrec.xgh3;
let xgh4 = satrec.xgh4;
let xh2 = satrec.xh2;
let xh3 = satrec.xh3;
let xi2 = satrec.xi2;
let xi3 = satrec.xi3;
let xl2 = satrec.xl2;
let xl3 = satrec.xl3;
let xl4 = satrec.xl4;
let zmol = satrec.zmol;
let zmos = satrec.zmos;
let init: DpperInit = options.init.clone();
let opsmode = options.opsmode.clone();
let mut ep = options.ep;
let mut inclp = options.inclp;
let mut nodep = options.nodep;
let mut argpp = options.argpp;
let mut mp = options.mp;
let mut alfdp;
let mut betdp;
let cosip;
let sinip;
let cosop;
let sinop;
let dalf;
let dbet;
let dls;
let mut f2;
let mut f3;
let mut pe;
let mut pgh;
let mut ph;
let mut pinc;
let mut pl;
let mut sinzf;
let mut xls;
let xnoh;
let mut zf;
let mut zm;
const ZNS: f64 = 1.19459e-5;
const ZES: f64 = 0.01675;
const ZNL: f64 = 1.5835218e-4;
const ZEL: f64 = 0.05490;
zm = zmos + (ZNS * t);
if init == DpperInit::Y {
zm = zmos;
}
zf = zm + (2.0 * ZES * zm.sin());
sinzf = zf.sin();
f2 = (0.5 * sinzf * sinzf) - 0.25;
f3 = -0.5 * sinzf * zf.cos();
let ses = (se2 * f2) + (se3 * f3);
let sis = (si2 * f2) + (si3 * f3);
let sls = (sl2 * f2) + (sl3 * f3) + (sl4 * sinzf);
let sghs = (sgh2 * f2) + (sgh3 * f3) + (sgh4 * sinzf);
let shs = (sh2 * f2) + (sh3 * f3);
zm = zmol + (ZNL * t);
if init == DpperInit::Y {
zm = zmol;
}
zf = zm + (2.0 * ZEL * zm.sin());
sinzf = zf.sin();
f2 = (0.5 * sinzf * sinzf) - 0.25;
f3 = -0.5 * sinzf * zf.cos();
let sel = (ee2 * f2) + (e3 * f3);
let sil = (xi2 * f2) + (xi3 * f3);
let sll = (xl2 * f2) + (xl3 * f3) + (xl4 * sinzf);
let sghl = (xgh2 * f2) + (xgh3 * f3) + (xgh4 * sinzf);
let shll = (xh2 * f2) + (xh3 * f3);
pe = ses + sel;
pinc = sis + sil;
pl = sls + sll;
pgh = sghs + sghl;
ph = shs + shll;
if init == DpperInit::N {
pe -= peo;
pinc -= pinco;
pl -= plo;
pgh -= pgho;
ph -= pho;
inclp += pinc;
ep += pe;
sinip = inclp.sin();
cosip = inclp.cos();
if inclp >= 0.2 {
ph /= sinip;
pgh -= cosip * ph;
argpp += pgh;
nodep += ph;
mp += pl;
} else {
sinop = nodep.sin();
cosop = nodep.cos();
alfdp = sinip * sinop;
betdp = sinip * cosop;
dalf = (ph * cosop) + (pinc * cosip * sinop);
dbet = (-ph * sinop) + (pinc * cosip * cosop);
alfdp += dalf;
betdp += dbet;
nodep %= TWO_PI;
if nodep < 0.0 && opsmode == DpperOpsMode::A {
nodep += TWO_PI;
}
xls = mp + argpp + (cosip * nodep);
dls = (pl + pgh) - (pinc * nodep * sinip);
xls += dls;
xnoh = nodep;
nodep = alfdp.atan2(betdp);
if nodep < 0.0 && opsmode == DpperOpsMode::A {
nodep += TWO_PI;
}
if (xnoh - nodep).abs() > PI {
if nodep < xnoh {
nodep += TWO_PI;
} else {
nodep -= TWO_PI;
}
}
mp += pl;
argpp = xls - mp - (cosip * nodep);
}
}
DpperResult {
ep,
inclp,
nodep,
argpp,
mp,
}
}