import { catmull_rom_compute_T } from "./catmull_rom_compute_T.js";

/**
 * Based on wiki article: https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline#Code_example_in_Python
 * @param {number[]} result
 * @param {number[]} p0 spline point 0
 * @param {number[]} p1 spline point 1
 * @param {number[]} p2 spline point 2
 * @param {number[]} p3 spline point 3
 * @param {number} dimensions number of dimensions in the input and output vectors
 * @param {number} f between 0..1
 * @param {number} alpha between 0..1
 */
export function computeNonuniformCatmullRomSplineSample(result, p0, p1, p2, p3, dimensions, f, alpha) {
    const half_alpha = alpha * 0.5;

    // calculate T
    const t0 = 0;
    let t_01 = catmull_rom_compute_T(p0, p1, dimensions, half_alpha);
    let t_02 = catmull_rom_compute_T(p1, p2, dimensions, half_alpha);
    let t_03 = catmull_rom_compute_T(p2, p3, dimensions, half_alpha);

    // safety check for repeated points, to prevent division by 0
    if (t_01 < 1e-4) {
        t_01 = 1;
    }
    if (t_02 < 1e-4) {
        t_02 = t_01;
    }
    if (t_03 < 1e-4) {
        t_03 = t_02;
    }

    const t1 = t_01 + t0;
    const t2 = t_02 + t1;
    const t3 = t_03 + t2;

    /**
     * Interpolation between points 1 and 2
     * @type {number}
     */
    const t = t1 * (1 - f) + t2 * f;

    /*
            Vector2 A1 = (t1-t)/(t1-t0)*p0 + (t-t0)/(t1-t0)*p1;
		    Vector2 A2 = (t2-t)/(t2-t1)*p1 + (t-t1)/(t2-t1)*p2;
		    Vector2 A3 = (t3-t)/(t3-t2)*p2 + (t-t2)/(t3-t2)*p3;

		    Vector2 B1 = (t2-t)/(t2-t0)*A1 + (t-t0)/(t2-t0)*A2;
		    Vector2 B2 = (t3-t)/(t3-t1)*A2 + (t-t1)/(t3-t1)*A3;

		    Vector2 C = (t2-t)/(t2-t1)*B1 + (t-t1)/(t2-t1)*B2;
     */

    const d_t1_t0 = t1 - t0;

    const m_A1_0 = (t1 - t) / d_t1_t0;
    const m_A1_1 = (t - t0) / d_t1_t0;

    const d_t2_t1 = t2 - t1;

    const m_A2_0 = (t2 - t) / d_t2_t1;

    const d_t_t1 = t - t1;

    const m_A2_1 = d_t_t1 / d_t2_t1;

    const d_t3_t2 = t3 - t2;

    const d_t3_t = t3 - t;

    const m_A3_0 = d_t3_t / d_t3_t2;
    const m_A3_1 = (t - t2) / d_t3_t2;

    const d_t2_t0 = t2 - t0;

    const m_B1_0 = (t2 - t) / d_t2_t0;
    const m_B1_1 = (t - t0) / d_t2_t0;

    const d_t3_t1 = t3 - t1;

    const m_B2_0 = d_t3_t / d_t3_t1;
    const m_B2_1 = d_t_t1 / d_t3_t1;

    const m_C_0 = (t2 - t) / d_t2_t1;
    const m_C_1 = d_t_t1 / d_t2_t1;

    for (let i = 0; i < dimensions; i++) {
        // read vector values for the dimension
        const v0 = p0[i];
        const v1 = p1[i];
        const v2 = p2[i];
        const v3 = p3[i];

        // compute resulting value in this dimension
        const A1 = m_A1_0 * v0 + m_A1_1 * v1;
        const A2 = m_A2_0 * v1 + m_A2_1 * v2;
        const A3 = m_A3_0 * v2 + m_A3_1 * v3;

        const B1 = m_B1_0 * A1 + m_B1_1 * A2;
        const B2 = m_B2_0 * A2 + m_B2_1 * A3;

        const C = m_C_0 * B1 + m_C_1 * B2;

        result[i] = C;
    }
}


