import { assert } from "../../../../../../assert.js";
import { NULL_POINTER } from "../BinaryTopology.js";

/**
 * Temporary array to hold the coordinate data read from the vertex
 */
const scratch_coord = [0, 0, 0];

/**
 * Given a face, get the coordinates of its center.
 * @param {number[]|Float32Array} output 3d vector
 * @param {number} output_offset where to write
 * @param {BinaryTopology} mesh
 * @param {number} face_id
 * @returns {boolean} true if centroid computed, false if something went wrong and no result could be produced
 */
export function bt_face_get_centroid(
    output,
    output_offset,
    mesh,
    face_id
) {
    assert.isNonNegativeInteger(output_offset, "output_offset");
    assert.isNonNegativeInteger(face_id, "face_id");

    // 1. Get the starting loop for the face
    const first_loop_id = mesh.face_read_loop(face_id);

    // Fallback/safety check in case the face is uninitialized or has no loops
    if (first_loop_id === NULL_POINTER) {
        return false;
    }

    let current_loop_id = first_loop_id;
    let vertex_count = 0;

    let sum_x = 0;
    let sum_y = 0;
    let sum_z = 0;


    // 2. Circulate through all loops making up the face
    do {
        // Read the vertex ID associated with this loop
        const vertex_id = mesh.loop_read_vertex(current_loop_id);

        // Read the actual 3D coordinates of that vertex into our temp array
        mesh.vertex_read_coordinate(scratch_coord, 0, vertex_id);

        // Accumulate the positions
        sum_x += scratch_coord[0];
        sum_y += scratch_coord[1];
        sum_z += scratch_coord[2];

        vertex_count++;

        // Step to the next loop around the face boundary
        current_loop_id = mesh.loop_read_next(current_loop_id);

    } while (current_loop_id !== first_loop_id); // Stop when we complete the cycle

    // 3. Divide by the number of vertices to get the average (centroid)
    if (vertex_count > 0) {

        output[output_offset] = sum_x / vertex_count;
        output[output_offset + 1] = sum_y / vertex_count;
        output[output_offset + 2] = sum_z / vertex_count;

        return true;
    } else {
        // no vertices
        return false;
    }

}