use sciforge::hub::prelude::constants::elements::atomic_mass;
use sciforge::hub::prelude::constants::{G, N_A, R_GAS};
use std::sync::LazyLock;

pub const NEPTUNEMASS: f64 = 1.02413e26;
pub const NEPTUNEEQUATORIALRADIUS: f64 = 24622000.0;
pub const NEPTUNEPOLARRADIUS: f64 = 24341000.0;
pub const NEPTUNEMEANRADIUS: f64 = 24622000.0;

pub fn mh2() -> f64 {
    2.0 * atomic_mass(1) * 1e-3
}
pub fn mhe() -> f64 {
    atomic_mass(2) * 1e-3
}
pub fn mch4() -> f64 {
    (atomic_mass(6) + 4.0 * atomic_mass(1)) * 1e-3
}
pub fn mnh3() -> f64 {
    (atomic_mass(7) + 3.0 * atomic_mass(1)) * 1e-3
}
pub fn mh2o() -> f64 {
    (2.0 * atomic_mass(1) + atomic_mass(8)) * 1e-3
}
pub fn mh2s() -> f64 {
    (2.0 * atomic_mass(1) + atomic_mass(16)) * 1e-3
}
pub fn matmosphere() -> f64 {
    0.80 * mh2() + 0.19 * mhe() + 0.015 * mch4()
}
pub fn mwaterice() -> f64 {
    mh2o()
}
pub fn mammoniaice() -> f64 {
    mnh3()
}
pub fn mmethaneice() -> f64 {
    mch4()
}
pub fn msio2() -> f64 {
    (atomic_mass(14) + 2.0 * atomic_mass(8)) * 1e-3
}
pub fn mfe() -> f64 {
    atomic_mass(26) * 1e-3
}

pub static SURFACEGRAVITY: LazyLock<f64> =
    LazyLock::new(|| G * NEPTUNEMASS / (NEPTUNEEQUATORIALRADIUS * NEPTUNEEQUATORIALRADIUS));
pub static SCALEHEIGHT: LazyLock<f64> =
    LazyLock::new(|| R_GAS * ONEBARTEMPK / (matmosphere() * *SURFACEGRAVITY));
pub static ONEBARDENSITY: LazyLock<f64> = LazyLock::new(|| {
    let rspecific = R_GAS / matmosphere();
    ONEBARPRESSURE / (rspecific * ONEBARTEMPK)
});
pub static WATERICEDENSITY: LazyLock<f64> = LazyLock::new(|| {
    let a = 4.5181e-10f64;
    let c = 7.3560e-10;
    let vcell = a * a * c * (60.0f64.to_radians().sin());
    4.0 * mh2o() / (N_A * vcell)
});
pub static IRONDENSITY: LazyLock<f64> = LazyLock::new(|| {
    let a = 2.8665e-10f64;
    2.0 * mfe() / (N_A * a.powi(3))
});
pub static SILICATEDENSITY: LazyLock<f64> = LazyLock::new(|| {
    let a = 4.9133e-10f64;
    let c = 5.4053e-10;
    let vcell = a * a * c * (60.0f64.to_radians().sin());
    3.0 * msio2() / (N_A * vcell)
});

pub const ONEBARPRESSURE: f64 = 101325.0;
pub const ONEBARTEMPK: f64 = 72.0;
pub const CELSIUSTOKELVIN: f64 = 273.15;
pub const SECONDSPERYEAR: f64 = 3.15576e7;
pub const OMEGANEPTUNE: f64 = 1.0834e-4;
pub const NEPTUNEFLATTENING: f64 = 0.01708;
pub const J2NEPTUNE: f64 = 3.411e-3;
pub const BONDALBEDO: f64 = 0.290;
pub const CLOUDTOPTEMPMINK: f64 = 50.0;
pub const CLOUDTOPTEMPMAXK: f64 = 72.0;
pub const KTTNTTOJOULE: f64 = 4.184e12;
pub const MTTNTTOJOULE: f64 = 4.184e15;
pub const STONYASTEROIDDENSITY: f64 = 3000.0;
pub const INTERIORICEDENSITY: f64 = 1600.0;
pub fn ironasteroiddensity() -> f64 {
    *IRONDENSITY
}
pub fn iceasteroiddensity() -> f64 {
    *WATERICEDENSITY
}
pub const H2LOVE: f64 = 1.0;
pub const K2LOVE: f64 = 0.41;
pub const L2LOVE: f64 = 0.12;
pub const TRITONECCENTRICITY: f64 = 0.000016;
pub const TRITONINCLINATIONDEG: f64 = 156.885;
pub const CLOUDEXTINCTIONCOEFF: f64 = 0.15;
pub const CLOUDLWCSCALE: f64 = 0.2;
pub const METHANEABSORPTION: f64 = 0.01;
pub const TROPOPAUSEM: f64 = 50000.0;
pub const ALBEDOEMAALPHA: f64 = 0.001;
pub const INTERNALHEATINGWM2: f64 = 0.433;
pub const MAXWINDSMS: f64 = 600.0;

pub mod atmosphere;
pub mod biosphere;
pub mod geodata;
pub mod geology;
pub mod hydrology;
pub mod lighting;
pub mod physics;
pub mod rendering;
pub mod satellites;
pub mod temporal;
pub mod terrain;
