#![allow(unused)]
use glam::DVec3;
use once_cell::sync::Lazy;

use crate::config::Body;

pub type Position = DVec3;
pub type Velocity = DVec3;
pub type Acceleration = DVec3;
pub type Mass = f64;
pub type Time = f64;


// Constants
const EARTH_RADIUS: f64 = 6.378e6; //meters
const EARTH_MASS: f64 = 5.972e24; //kg
const EARTH_ORBITAL_VELOCITY: f64 = 2.9780e4; //m/s
const AU: f64 = 1.49597870700e11; //meters

const MOON_MASS: Mass = 7.34767309e22; // kg
const MOON_ORBITAL_VELOCITY: f64 = 1.022e3; //m/s relative to earth

const SUN_MASS: f64 = 1.989e30; //kg
const SUN_RADIUS: f64 = 6.957e8; //meters

const G: f64 = 6.67430e-11;
const R_0: f64 = EARTH_RADIUS;
const M_0: f64 = EARTH_MASS;

static T_0: Lazy<f64> = Lazy::new(|| {
    (R_0.powf(3.0) / (G * M_0)).sqrt()
});


#[inline]
pub fn norm_pos(pos: Position) -> Position {
    pos / R_0
}

#[inline]
pub fn real_pos(pos: Position) -> Position {
    pos * R_0
}

#[inline]
pub fn norm_mass(mass: Mass) -> Mass {
    mass / M_0
}

#[inline]
pub fn real_mass(mass: Mass) -> Mass {
    mass * M_0
}

#[inline]
pub fn norm_time(time: Time) -> Time {
    time / *T_0
}

#[inline]
pub fn real_time(time: Time) -> Time {
    time * *T_0
}

#[inline]
pub fn norm_vel(vel: Velocity) -> Velocity {
    vel / (R_0 / *T_0)
}

#[inline]
pub fn real_vel(vel: Velocity) -> Velocity {
    vel * (R_0 / *T_0)
}

#[inline]
pub fn norm_acc(acc: Acceleration) -> Acceleration {
    acc / (R_0 / (*T_0 * *T_0))
}

#[inline]
pub fn real_acc(acc: Acceleration) -> Acceleration {
    acc * (R_0 / (*T_0 * *T_0))
}

#[inline]
pub fn norm_body(body: Body) -> Body {
    Body {
        name: body.name,
        mass: norm_mass(body.mass),
        position: norm_pos(body.position),
        velocity: norm_vel(body.velocity),
        acceleration: DVec3::ZERO,
    }
}

#[inline]
pub fn real_body(body: &Body) -> Body {
    Body {
        name: body.name.clone(),
        mass: real_mass(body.mass),
        position: real_pos(body.position),
        velocity: real_vel(body.velocity),
        acceleration: DVec3::ZERO,
    }
}