import { array_copy } from "../../../../../core/collection/array/array_copy.js";
import { compute_polygon_area_2d } from "../../../../../core/geom/2d/compute_polygon_area_2d.js";
import { convex_hull_jarvis_2d } from "../../../../../core/geom/2d/convex-hull/convex_hull_jarvis_2d.js";
import { fixed_convex_hull_relaxation } from "../../../../../core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js";
import {
    make_edge_condition_channel_threshold
} from "../../../texture/sampler/search/make_edge_condition_channel_threshold.js";
import { sampler2d_find_pixels } from "../../../texture/sampler/search/sampler2d_find_pixels.js";

/**
 *
 * @param {Sampler2D} accumulator
 * @param {number} vertex_limit
 * @param {number} frame_size
 * @returns {Float32Array}
 */
export function sampler2d_build_cutout(accumulator, vertex_limit, frame_size) {
    const edge_pixels = sampler2d_find_pixels(accumulator, make_edge_condition_channel_threshold(0, 5));

    // filtered pixels
    const filtered_edge_pixels = [];

    const half_pixel = 0.5;

    for (let i = 0; i < edge_pixels.length; i += 2) {
        const x = edge_pixels[i];
        const y = edge_pixels[i + 1];

        filtered_edge_pixels.push(x - half_pixel, y - half_pixel);
        filtered_edge_pixels.push(x + half_pixel, y - half_pixel);
        filtered_edge_pixels.push(x + half_pixel, y + half_pixel);
        filtered_edge_pixels.push(x - half_pixel, y + half_pixel);
    }

    const hull_point_indices = convex_hull_jarvis_2d(filtered_edge_pixels, filtered_edge_pixels.length / 2);

    const hull_points = [];

    for (let i = 0; i < hull_point_indices.length; i++) {
        const hpi = hull_point_indices[i];

        array_copy(filtered_edge_pixels, hpi * 2, hull_points, i * 2, 2);
    }

    const cutout_points = new Float32Array(vertex_limit * 2);

    fixed_convex_hull_relaxation(cutout_points, 0, vertex_limit, hull_points, hull_point_indices.length);

    const area = compute_polygon_area_2d(cutout_points, vertex_limit);

    console.log(`Cutout area: ${area}`);

    if (area >= 0.99 && vertex_limit >= 4) {
        // default back to aligned quad, produced result is a degradation
        return new Float32Array([
            0, 0,
            accumulator.width, 0,
            accumulator.width, accumulator.height,
            0, accumulator.height
        ]);
    }

    return cutout_points;
}