import { assert } from "../../../assert.js";
import { plane3_lerp } from "../plane/plane3_lerp.js";

/**
 * Lerp between two planes of a frustum, opposing planes (x0,x1) or (y0,y1) or (z0,z1)
 * @param {number[]} output
 * @param {number} output_offset
 * @param {number[]} input
 * @param {number} plane_min_offset
 * @param {number} plane_max_offset
 * @param {number} section0
 * @param {number} section1
 */
function frustum_plane_pair_lerp(
    output, output_offset,
    input,
    plane_min_offset,
    plane_max_offset,
    section0, section1
) {

    assert.isArrayLike(input, 'input');
    assert.isNonNegativeInteger(plane_min_offset, 'plane_min_offset');
    assert.isNonNegativeInteger(plane_max_offset, 'plane_max_offset');
    assert.isNumber(section0, 'section0');
    assert.isNumber(section1, 'section1');

    const p0_nx = input[plane_min_offset];
    const p0_ny = input[plane_min_offset + 1];
    const p0_nz = input[plane_min_offset + 2];
    const p0_c = input[plane_min_offset + 3];

    const p1_nx = input[plane_max_offset];
    const p1_ny = input[plane_max_offset + 1];
    const p1_nz = input[plane_max_offset + 2];
    const p1_c = input[plane_max_offset + 3];

    plane3_lerp(
        output, output_offset,
        p0_nx, p0_ny, p0_nz, p0_c,
        -p1_nx, -p1_ny, -p1_nz, -p1_c,
        section0
    );

    plane3_lerp(
        output, output_offset + 4,
        -p0_nx, -p0_ny, -p0_nz, -p0_c,
        p1_nx, p1_ny, p1_nz, p1_c,
        section1
    );
}

/**
 * Carves out a slice of a frustum, given a normalized set of intervals [0,1] for each axis.
 * Works with perspective and orthographic frustums.
 * Input frustum is assumed to have planes in the following order [x0, x1, y0, y1, z0, z1]
 * @param {number[]|Float32Array} output
 * @param {number} output_offset
 * @param {number[]|Float32Array} frustum
 * @param {number} x0
 * @param {number} y0
 * @param {number} z0
 * @param {number} x1
 * @param {number} y1
 * @param {number} z1
 */
export function frustum_slice(
    output, output_offset,
    frustum,
    x0, y0, z0,
    x1, y1, z1,
) {
    // X planes
    frustum_plane_pair_lerp(
        output, output_offset,
        frustum,
        0, 4, x0, x1,
    );

    // Y planes
    frustum_plane_pair_lerp(
        output, output_offset + 8,
        frustum,
        8, 12, y0, y1,
    );

    // Z planes
    frustum_plane_pair_lerp(
        output, output_offset + 16,
        frustum,
        16, 20, z0, z1,
    );

}