/**
 * Gravity calculations based on WGS-84 ellipsoid model.
 * Author: Rene de Ren (Waterschap Brabantse Delta)
 * License: EUPL-1.2
 */

class Gravity {
  constructor() {
    // Standard (conventional) gravity at 45° latitude, sea level
    this.g0 = 9.80665; // m/s²
  }

  /**
   * Returns standard gravity (constant)
   * @returns {number} gravity in m/s²
   */
  getStandardGravity() {
    return this.g0;
  }

  /**
   * Computes local gravity based on latitude and elevation.
   * Formula: WGS-84 normal gravity (Somigliana)
   * @param {number} latitudeDeg  Latitude in degrees (−90 → +90)
   * @param {number} elevationM   Elevation above sea level [m]
   * @returns {number} gravity in m/s²
   */
  getLocalGravity(latitudeDeg, elevationM = 0) {
    const phi = (latitudeDeg * Math.PI) / 180;
    const sinPhi = Math.sin(phi);
    const sin2 = sinPhi * sinPhi;
    const sin2_2phi = Math.sin(2 * phi) ** 2;

    // WGS-84 normal gravity on the ellipsoid
    const gSurface =
      9.780327 * (1 + 0.0053024 * sin2 - 0.0000058 * sin2_2phi);

    // Free-air correction for elevation (~ −3.086×10⁻⁶ m/s² per m)
    const gLocal = gSurface - 3.086e-6 * elevationM;
    return gLocal;
  }

  /**
   * Calculates hydrostatic pressure difference (ΔP = ρ g h)
   * @param {number} density     Fluid density [kg/m³]
   * @param {number} heightM     Height difference [m]
   * @param {number} latitudeDeg Latitude (for local g)
   * @param {number} elevationM  Elevation (for local g)
   * @returns {number} Pressure difference [Pa]
   */
  pressureHead(density, heightM, latitudeDeg = 45, elevationM = 0) {
    const g = this.getLocalGravity(latitudeDeg, elevationM);
    return density * g * heightM;
  }

  /**
   * Calculates weight force (F = m g)
   * @param {number} massKg      Mass [kg]
   * @param {number} latitudeDeg Latitude (for local g)
   * @param {number} elevationM  Elevation (for local g)
   * @returns {number} Force [N]
   */
  weightForce(massKg, latitudeDeg = 45, elevationM = 0) {
    const g = this.getLocalGravity(latitudeDeg, elevationM);
    return massKg * g;
  }
}

module.exports = new Gravity();


/*
const gravity = gravity;

// Standard gravity
console.log('g₀ =', gravity.getStandardGravity(), 'm/s²');

// Local gravity (Breda ≈ 51.6° N, 3 m elevation)
console.log('g @ Breda =', gravity.getLocalGravity(51.6, 3).toFixed(6), 'm/s²');

// Head pressure for 5 m water column at Breda
console.log(
  'ΔP =',
  gravity.pressureHead(1000, 5, 51.6, 3).toFixed(1),
  'Pa'
);

// Weight of 1 kg mass at Breda
console.log('Weight =', gravity.weightForce(1, 51.6, 3).toFixed(6), 'N');
*/