import { v3_length } from "../../vec3/v3_length.js";

/**
 *
 * @param {number[]} mat4
 * @param {Vector3|{set(x:number,y:number,z:number)}} position
 * @param {Quaternion} rotation
 * @param {Vector3|{set(x:number,y:number,z:number)}} scale
 */
export function decompose_matrix_4_array(mat4, position, rotation, scale) {
    const m11 = mat4[0];
    const m12 = mat4[1];
    const m13 = mat4[2];

    const scale_x = v3_length(m11, m12, m13);

    const m21 = mat4[4];
    const m22 = mat4[5];
    const m23 = mat4[6];

    const scale_y = v3_length(m21, m22, m23);

    const m31 = mat4[8];
    const m32 = mat4[9];
    const m33 = mat4[10];

    const scale_z = v3_length(m31, m32, m33);

    // extract rotation matrix
    // take care of potential division by 0 when scale is 0. Result is inexact, but we get don't break the system at least
    const is1 = scale_x !== 0 ? 1 / scale_x : 1e7;
    const is2 = scale_y !== 0 ? 1 / scale_y : 1e7;
    const is3 = scale_z !== 0 ? 1 / scale_z : 1e7;

    const sm11 = m11 * is1;
    const sm12 = m12 * is1;
    const sm13 = m13 * is1;

    const sm21 = m21 * is2;
    const sm22 = m22 * is2;
    const sm23 = m23 * is2;

    const sm31 = m31 * is3;
    const sm32 = m32 * is3;
    const sm33 = m33 * is3;

    // write out results

    position.set(
        mat4[12],
        mat4[13],
        mat4[14]
    );

    scale.set(
        scale_x,
        scale_y,
        scale_z
    );

    rotation.__setFromRotationMatrix(
        sm11, sm21, sm31,
        sm12, sm22, sm32,
        sm13, sm23, sm33
    );
}
