/**
 * Analytical approximation of the CIE D65 Spectral Power Distribution (SPD)
 * using Planck's Law for a blackbody at the CCT of D65 (6504 K).
 *
 * This provides a close approximation to the shape of the D65 curve and is
 * normalized to 100.0 at 560 nm to match the CIE standard.
 *
 * Note: The official D65 standard ({@link D65_spd_tabulated}) is based on measurements
 * and is not a perfect blackbody. This function is the standard
 * *physical approximation*.
 */
import { planckian_radiance } from "./planckian_radiance.js";

const D65_ANALYTIC_T = 6504.0; // CCT for D65 in Kelvin

// Pre-calculate the normalization factor:
// This is the un-normalized value of the function at 560nm (560e-9 m),
// which is the wavelength where D65 is defined to be 100.
const NORM_WAVELENGTH_M = 560e-9;
const UNNORMALIZED_VALUE_AT_560 = planckian_radiance(NORM_WAVELENGTH_M, D65_ANALYTIC_T);
const NORMALIZATION_FACTOR = 1 / (UNNORMALIZED_VALUE_AT_560 / 100.0);


/**
 * Returns the analytical D65 SPD, normalized to 100.0 at 560 nm.
 * Returns 0 outside [300, 830] nm.
 *
 * Note: not true D65, if you need accuracy - use {@link D65_spd_tabulated} instead
 *
 * @param {number} wavelength_nm
 * @returns {number}
 * @see D65_spd_tabulated
 */
export function D65_spd_analytical(wavelength_nm) {

    if (wavelength_nm < 300 || wavelength_nm > 830) {
        return 0;
    }

    const lambda_m = wavelength_nm * 1.0e-9; // Convert nm to meters

    const radiance = planckian_radiance(lambda_m, D65_ANALYTIC_T);

    // Return the value, normalized
    return radiance * NORMALIZATION_FACTOR;
}