extern crate rkepler;

use rkepler::frame::constant::AU;
use rkepler::frame::iau06;
use rkepler::math::angle::{RADASEC, RADDEG};
use rkepler::math::matrix::mat_r;
use rkepler::math::sphe::sph_p;
use rkepler::phys_eph::body_prm;
use rkepler::pos_eph::satell::elp85;
use rkepler::BodyId;

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

struct Eph {
    mjd_tt: f64,
    rec: f64,
    dec: f64,
    dist: f64,
    diam: f64,
}

fn main() {
    println!("Hello, world!");

    let mjd_start = 60000.0;
    let mjd_end = 60032.0;
    let step = 1.0;

    let mut prm: Vec<Prm> = Vec::new();
    let mut step_tt = mjd_start;
    let phys_prm = body_prm::moon();

    while step_tt < mjd_end {
        let nut = iau06::iau06_r::nut00b(step_tt);
        let true_ecl = iau06::iau06_r::gcrs_true(step_tt, nut.0, nut.1);
        prm.push(Prm {
            mjd_tt: step_tt,
            icrf_true: true_ecl,
        });
        step_tt += step;
    }

    let mut eph: Vec<Eph> = Vec::new();
    for i in prm.iter() {
        let icrf_p = elp85::get_icrs_p(i.mjd_tt, &BodyId::MOON);
        let true_p = mat_r::mul_p(&i.icrf_true, &icrf_p);
        let true_s = sph_p::from_cart(&true_p);
        let deqv = 2.0 * phys_prm.vis_equ_rad(true_s.rad);

        eph.push(Eph {
            mjd_tt: i.mjd_tt,
            rec: true_s.lon,
            dec: true_s.lat,
            dist: true_s.rad,
            diam: deqv,
        });
    }

    println!();
    println!("Body: {}", "Moon");
    for i in eph.iter() {
        println!(
            "TT: {}, Rec: {:7.4}, Lat: {:+7.3}, Dist: {:7.0}, Diam: {:6.1}",
            i.mjd_tt,
            i.rec * RADDEG / 15.0,
            i.dec * RADDEG,
            i.dist * AU,
            i.diam * RADASEC,
        );
    }
}
