import { computeFrenetFrames } from "./computeFrenetFrames.js";
import { makeTubeGeometry } from "./makeTubeGeometry.js";
import Vector3 from "../../../../../../core/geom/Vector3.js";
import { PathNormalType } from "../PathNormalType.js";


const scratch_array_0 = [];
const scratch_array_1 = [];

const scratch_v3 = new Vector3();

/**
 *
 * @param {Path} path
 * @param {TubePathStyle} style
 * @param {number[]} shape
 * @param {number[]|Float32Array} shape_normal
 * @param {number[]} shape_transform
 * @param {number} segment_start
 * @param {number} segment_end
 * @return {THREE.BufferGeometry}
 */
export function build_geometry_linear(
    path, style,
    shape, shape_normal, shape_transform,
    segment_start, segment_end
) {
    const points = [];

    const path_length = path.length;

    path.find_index_and_normalized_distance(scratch_array_0, segment_start * path_length);
    path.find_index_and_normalized_distance(scratch_array_1, segment_end * path_length);

    let points_added = 0;

    if (scratch_array_0[1] !== 0) {
        path.sample_linear(scratch_v3, segment_start * path_length);

        scratch_v3.toArray(points, points_added * 3);
        points_added++;

        // offset first sampled point, we're already past it
        scratch_array_0[0]++;
    }

    const max_i = scratch_array_1[0];
    for (let i = scratch_array_0[0]; i <= max_i; i++) {
        path.readPositionToArray(i, points, points_added * 3);
        points_added++;
    }

    if (scratch_array_1[1] !== 0) {
        //add end
        path.sample_linear(scratch_v3, segment_end * path_length);

        scratch_v3.toArray(points, points_added * 3);
        points_added++;
    }

    const normal_hint = style.path_normal_type === PathNormalType.FixedStart ? style.path_normal : undefined;

    const frames = computeFrenetFrames(points, false, normal_hint);

    return makeTubeGeometry(
        points, frames.normals, frames.binormals, frames.tangents,
        shape, shape_normal, shape.length / 2, shape_transform,
        false, style.cap_type
    );
}
