import { array_copy } from "../../../../core/collection/array/array_copy.js";
import { AttributeDataTexture } from "../../texture/AttributeDataTexture.js";

/**
 *
 * @param {LightProbeVolume} lpv
 * @param {number[]} atlas_data
 * @param {number} atlas_width
 */
export function octahedral_depth_to_atlas(lpv, atlas_data, atlas_width) {
    const tile_resolution = lpv.depth_map_resolution;
    const probe_count = lpv.count;
    const probe_depth = lpv.depth;

    const tiles_per_row = Math.floor(atlas_width / tile_resolution);

    // populate atlas
    for (let i = 0; i < probe_count; i++) {

        const tile_x = i % tiles_per_row;
        const tile_y = (i / tiles_per_row) >>> 0;

        for (let pixel_y = 0; pixel_y < tile_resolution; pixel_y++) {
            for (let pixel_x = 0; pixel_x < tile_resolution; pixel_x++) {

                const source_offset = i * tile_resolution * tile_resolution;

                const tile_pixel_index = pixel_y * tile_resolution + pixel_x;

                const source_pixel_index = source_offset + tile_pixel_index;

                const target_pixel_x = tile_x * tile_resolution + pixel_x;
                const target_pixel_y = tile_y * tile_resolution + pixel_y;

                const target_pixel_index = target_pixel_y * atlas_width + target_pixel_x;

                const target_pixel_address = target_pixel_index * 2;
                const source_pixel_address = source_pixel_index * 2;

                atlas_data[target_pixel_address] = probe_depth[source_pixel_address];
                atlas_data[target_pixel_address + 1] = probe_depth[source_pixel_address + 1];
            }
        }
    }
}


/**
 *
 * @param {AttributeDataTexture} target
 * @param {number[]} points
 * @param {number} point_count
 * @param {number} dimensions
 */
export function vector_buffer_to_attribute_texture(
    target,
    points,
    point_count,
    dimensions = 3
) {
    if (target.spec.itemSize !== dimensions) {
        throw new Error(`Expected spec.itemCount = ${dimensions} (number of dimensions), instead got ${target.spec.itemSize}`);
    }

    target.resize(point_count);

    array_copy(points, 0, target.data, 0, point_count * dimensions);

    target.texture.needsUpdate = true;
}