import { aabb2_distance_sqr_to_point } from "../aabb/aabb2_distance_sqr_to_point.js";

/**
 *
 * @type {QuadTreeNode[]}
 */
const node_stack = [];

/**
 * @template N
 * @param {QuadTreeNode<N>} tree
 * @param {number} x
 * @param {number} y
 * @param {number} [max_distance]
 * @returns {QuadTreeDatum<N>}
 */
export function qt_query_data_nearest_to_point(tree, x, y, max_distance = Infinity) {

    let stack_pointer = 1;

    node_stack[0] = tree;

    let best_leaf_data = undefined;
    let best_distance_sqr = max_distance * max_distance;

    while (stack_pointer-- > 0) {

        const node = node_stack[stack_pointer];

        const distance_sqr = aabb2_distance_sqr_to_point(node.x0, node.y0, node.x1, node.y1, x, y);

        if (distance_sqr >= best_distance_sqr) {
            // too far
            continue;
        }

        const data = node.data;
        const data_count = data.length;

        for (let i = 0; i < data_count; i++) {
            const datum = data[i];

            const distance_sqr = aabb2_distance_sqr_to_point(datum.x0, datum.y0, datum.x1, datum.y1, x, y);

            if (distance_sqr < best_distance_sqr) {
                best_leaf_data = datum;
                best_distance_sqr = distance_sqr;
            }
        }

        if (node.isSplit()) {
            node_stack[stack_pointer++] = node.topLeft;
            node_stack[stack_pointer++] = node.topRight;
            node_stack[stack_pointer++] = node.bottomLeft;
            node_stack[stack_pointer++] = node.bottomRight;
        }
    }

    return best_leaf_data;
}
