import { assert } from "../../../../core/assert.js";
import { Behavior } from "../Behavior.js";

/**
 * Abstract base class
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2026
 */
export class CompositeBehavior extends Behavior {

    /**
     *
     * @type {Behavior[]}
     * @protected
     */
    __children = [];

    /**
     *
     * @param {Behavior} child
     */
    addChild(child) {
        assert.defined(child, 'child');
        assert.notNull(child, 'child');
        assert.equal(child.isBehavior, true, 'child is not a Behavior');
        assert.arrayHasNo(this.__children, child, 'child already added');

        this.__children.push(child);
    }

    /**
     *
     * @param {Behavior[]} children
     */
    addChildren(children) {
        assert.isArray(children, 'children');

        const n = children.length;

        for (let i = 0; i < n; i++) {

            const e = children[i];
            this.addChild(e);

        }

    }

    /**
     * Do not modify directly. Use {@link addChild} and {@link removeChild} instead
     * @return {Behavior[]}
     */
    get children() {
        return this.__children;
    }

    /**
     * @deprecated use {@link children} accessor instead
     * @return {Behavior[]}
     */
    getChildren() {
        return this.children;
    }

    /**
     *
     * @param {Behavior} child
     * @returns {boolean}
     */
    removeChild(child) {
        const i = this.__children.indexOf(child);

        if (i === -1) {
            //child is not found
            return false;
        } else {
            this.__children.splice(i, 1);

            return true;
        }
    }

    clearChildren() {
        this.__children = [];
    }
}

/**
 * @readonly
 * @type {boolean}
 */
CompositeBehavior.prototype.isCompositeBehavior = true;
