pub const OMEGANEPTUNE: f64 = crate::OMEGANEPTUNE;

pub fn coriolisparameter(latitudedeg: f64) -> f64 {
    let latrad = latitudedeg.to_radians();
    2.0 * OMEGANEPTUNE * latrad.sin()
}

pub fn geostrophicwindspeed(pressuregradientpaperm: f64, latitudedeg: f64, airdensity: f64) -> f64 {
    let f = coriolisparameter(latitudedeg);
    if f.abs() < 1e-10 {
        return f64::INFINITY;
    }
    pressuregradientpaperm / (airdensity * f.abs())
}

pub fn gradientwindspeed(
    pressuregradient: f64,
    radiusm: f64,
    latitudedeg: f64,
    airdensity: f64,
) -> f64 {
    let f = coriolisparameter(latitudedeg);
    let term = f * f * radiusm * radiusm / 4.0 + radiusm * pressuregradient / airdensity;
    if term < 0.0 {
        return 0.0;
    }
    -f * radiusm / 2.0 + term.sqrt()
}

pub fn thermalwindshear(
    tempgradientkperm: f64,
    meantempk: f64,
    latitudedeg: f64,
    deltap: f64,
    meanp: f64,
) -> f64 {
    let g0 = *crate::SURFACEGRAVITY;
    let f = coriolisparameter(latitudedeg);
    if f.abs() < 1e-10 {
        return 0.0;
    }
    if meantempk.abs() < 1e-10 || meanp.abs() < 1e-10 {
        return 0.0;
    }
    -(g0 / (f * meantempk)) * tempgradientkperm * deltap / meanp
}

pub fn ekmanspiraldepth(eddyviscosity: f64, latitudedeg: f64) -> f64 {
    let f = coriolisparameter(latitudedeg);
    if f.abs() < 1e-10 {
        return f64::INFINITY;
    }
    std::f64::consts::PI * (2.0 * eddyviscosity / f.abs()).sqrt()
}

pub fn zonalwindprofile(latitudedeg: f64) -> f64 {
    let latrad = latitudedeg.to_radians();
    let equatorialjet = -400.0;
    let polarcorrection = 200.0 * (3.0 * latrad).cos();
    equatorialjet + polarcorrection
}

pub fn beauforttoms(beaufort: u8) -> f64 {
    0.836 * (beaufort as f64).powf(1.5)
}
