import { assert } from "../../../assert.js";
import { max2 } from "../../../math/max2.js";
import { min2 } from "../../../math/min2.js";
import { qt_collect_by_box } from "../../2d/quad-tree/qt_collect_by_box.js";
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
import { removeRedundantBoxesArray } from "./removeRedundantBoxesArray.js";

/**
 * Cut out a region from given set of boxes
 * @param {AABB2} scissor area to be cut out
 * @param {QuadTreeNode} boxes
 */
export function cutArea(
    scissor,
    boxes
) {

    assert.defined(scissor, 'scissor');
    assert.defined(boxes, 'boxes');

    /**
     *
     * @type {QuadTreeDatum[]}
     */
    const additions = [];

    /**
     *
     * @type {QuadTreeDatum[]}
     */
    const removals = [];

    const overlap_box_count = qt_collect_by_box(removals,0,boxes,scissor.x0, scissor.y0, scissor.x1, scissor.y1);

    for (let j = 0; j < overlap_box_count; j++) {
        const box = removals[j];

        //compute overlap region
        const x0 = max2(scissor.x0, box.x0);
        const x1 = min2(scissor.x1, box.x1);

        const y0 = max2(scissor.y0, box.y0);
        const y1 = min2(scissor.y1, box.y1);


        //create 4 boxes around overlap
        if (x0 > box.x0) {
            //add left box
            additions.push(new QuadTreeDatum(box.x0, box.y0, x0, box.y1));
        }

        if (x1 < box.x1) {
            //add right box
            additions.push(new QuadTreeDatum(x1, box.y0, box.x1, box.y1));
        }

        if (y0 > box.y0) {
            //add top box
            additions.push(new QuadTreeDatum(box.x0, box.y0, box.x1, y0));
        }

        if (y1 < box.y1) {
            //add bottom box
            additions.push(new QuadTreeDatum(box.x0, y1, box.x1, box.y1));
        }

    }

    let i, l;
    //perform removals
    for (i = 0, l = removals.length; i < l; i++) {
        const removal = removals[i];
        removal.disconnect();
    }

    //drop potential overlaps between additions
    removeRedundantBoxesArray(additions);

    //perform additions
    for (i = 0, l = additions.length; i < l; i++) {
        const addition = additions[i];

        boxes.insertDatum(addition);
    }
}
