import { array_copy_entire } from "../../core/collection/array/array_copy_entire.js";
import { circle_intersects_circle } from "../../core/geom/2d/circle/circle_intersects_circle.js";
import Vector2 from "../../core/geom/Vector2.js";
import { Transform } from "../../engine/ecs/transform/Transform.js";

export class MarkerNode {

    /**
     * Processing order, higher priority nodes are processed first
     * @type {number}
     */
    priority = 0;

    /**
     *
     * @type {String}
     */
    type = null;

    /**
     *
     * @type {String[]}
     */
    tags = [];

    /**
     * Grid position
     * @type {Vector2}
     */
    position = new Vector2();

    /**
     * World transform, this can differ from the grid position
     * @type {Transform}
     */
    transform = new Transform();

    /**
     * Treated as a radius
     * Used for spatial resolution, to allow spacing markers
     * @type {number}
     */
    size = 0;

    /**
     *
     * @type {Object}
     */
    properties = {};


    /**
     *
     * @param {string} tag
     * @returns {boolean}
     */
    hasTag(tag) {
        return this.tags.includes(tag);
    }

    /**
     *
     * @param {string[]} tags
     * @returns {boolean}
     */
    hasAllTags(tags) {
        const n = tags.length;
        const this_tags = this.tags;

        for (let i = 0; i < n; i++) {
            if (!this_tags.includes(tags[i])) {
                return false;
            }
        }

        return true;
    }

    /**
     *
     * @returns {MarkerNode}
     */
    clone() {
        const r = new MarkerNode();

        r.copy(this);

        return r;
    }

    /**
     *
     * @param {MarkerNode} other
     */
    copy(other) {
        this.type = other.type;

        array_copy_entire(other.tags, this.tags);

        this.position.copy(other.position);

        this.transform.copy(other.transform);

        this.size = other.size;

        this.properties = Object.assign({}, other.properties);
    }

    /**
     *
     * @param {MarkerNode} other
     * @returns {boolean}
     */
    overlaps(other) {
        const p0 = this.transform.position;
        const p1 = other.transform.position;

        return circle_intersects_circle(p0.x, p0.y, this.size, p1.x, p1.y, other.size);
    }

}

/**
 * @readonly
 * @type {boolean}
 */
MarkerNode.prototype.isMarkerNode = true;
