import { assert } from "../../../assert.js";
import { sign_not_zero } from "../../../math/sign_not_zero.js";
import { v3_dot } from "../../vec3/v3_dot.js";

/**
 *
 * @param {number[]} out_uv
 * @param {number} out_offset
 * @param {number[]} in_direction
 * @param {number} in_offset
 */
export function octahedral_direction_to_uv(
    out_uv, out_offset,
    in_direction, in_offset
) {

    assert.isNonNegativeInteger(out_offset, 'out_offset');
    assert.isNonNegativeInteger(in_offset, 'in_offset');

    const input_x = in_direction[in_offset + 0];
    const input_y = in_direction[in_offset + 1];
    const input_z = in_direction[in_offset + 2];

    const octant_x = sign_not_zero(input_x);
    const octant_y = sign_not_zero(input_y);
    const octant_z = sign_not_zero(input_z);

    // |x| + |y| + |z| = 1
    const sum = v3_dot(
        input_x, input_y, input_z,
        octant_x, octant_y, octant_z
    );

    let octahedron_x = input_x / sum;
    const octahedron_y = input_y / sum;
    let octahedron_z = input_z / sum;

    if (octahedron_y < 0) {
        const absolute_x = Math.abs(octahedron_x);
        const absolute_z = Math.abs(octahedron_z);

        octahedron_x = octant_x * (1 - absolute_z);
        octahedron_z = octant_z * (1 - absolute_x);
    }

    out_uv[out_offset + 0] = octahedron_x;
    out_uv[out_offset + 1] = octahedron_z;
}