extern crate rkepler;
use rkepler::datetime::time;
use rkepler::frame::iau06;
use rkepler::math::angle::RADDEG;
use rkepler::math::matrix::mat_r;
use rkepler::math::sphe::sph_p;
use rkepler::math::vector::vec_p;
use rkepler::pos_eph::satell::elp85;
use rkepler::pos_eph::vsop2013::vsop2013_lo;
use rkepler::BodyId;

static BODY: [&BodyId; 8] = [
    &BodyId::MERCURY,
    &BodyId::VENUS,
    &BodyId::EARTH,
    &BodyId::MARS,
    &BodyId::JUPITER,
    &BodyId::SATURN,
    &BodyId::URANUS,
    &BodyId::NEPTUNE,
];
static BODY_NAME: [&str; 8] = [
    "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune",
];

static EMRAT: f64 = 81.30057;

struct Prm {
    mjd_tt: f64,
    mjd_tdb: f64,
    icrf_true: mat_r::MatR,
}

fn main() {
    println!("Hello, world!");
    let mjd_start = 60000.0;
    let mjd_end = 60366.0;
    let step = 7.0;

    let mut prm: Vec<Prm> = Vec::new();
    let mut step_tt = mjd_start;
    while step_tt < mjd_end {
        let step_tdb = step_tt + time::tdb_m_tt_lo(step_tt);
        let nut = iau06::iau06_r::nut00b(step_tt);
        let true_ecl = iau06::iau06_r::gcrs_true_ecl(step_tt, nut.0);
        prm.push(Prm {
            mjd_tt: step_tt,
            mjd_tdb: step_tdb,
            icrf_true: true_ecl,
        });
        step_tt += step;
    }
    for pl in 0..BODY.len() {
        println!();
        println!("Body: {}", BODY_NAME[pl]);
        let mut out_icrs;
        for i in prm.iter() {
            match BODY[pl] {
                BodyId::EARTH => {
                    out_icrs = vsop2013_lo::get_icrs_p(i.mjd_tdb, &BodyId::EMB);
                    let moon_p = elp85::get_icrs_p(i.mjd_tdb, &BodyId::MOON);
                    out_icrs = vec_p::add_scaled(&out_icrs, -1.0 / (1.0 + EMRAT), &moon_p);
                }
                _ => {
                    out_icrs = vsop2013_lo::get_icrs_p(i.mjd_tdb, BODY[pl]);
                }
            }
            let out_true = mat_r::mul_p(&i.icrf_true, &out_icrs);
            let out_sph = sph_p::from_cart(&out_true);
            println!(
                "TT: {}, Lon: {:7.3}, Lat: {:+6.3}, Dist: {:8.5}",
                i.mjd_tt,
                out_sph.lon * RADDEG,
                out_sph.lat * RADDEG,
                out_sph.rad
            );
        }
    }
}
