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

export class EntityEventBinding {
    entity = -1
    event = ""
    handler = null
    context = null
    /**
     *
     * @type {EntityComponentDataset|null}
     */
    ecd = null

    #linked = false

    /**
     *
     * @param {number} entity
     * @param {string} event
     * @param {function} handler
     * @param {*} [context]
     * @returns {EntityEventBinding}
     */
    static from(
        entity, event, handler, context
    ) {
        assert.isNonNegativeInteger(entity, 'entity');
        assert.isString(event, 'event');
        assert.isFunction(handler, 'handler');

        const r = new EntityEventBinding();

        r.entity = entity;
        r.event = event;
        r.handler = handler;
        r.context = context;

        return r;
    }

    /**
     *
     * @param {EntityComponentDataset} ecd
     */
    link(ecd) {
        if (this.#linked) {
            if (this.ecd === ecd) {
                return;
            }

            this.unlink();
        }

        this.#linked = true;
        this.ecd = ecd;

        ecd.addEntityEventListener(this.entity, this.event, this.handler, this.context);
    }

    unlink() {
        if (!this.#linked) {
            return;
        }

        const ecd = this.ecd;

        if (ecd.entityExists(this.entity)) {
            ecd.removeEntityEventListener(this.entity, this.event, this.handler, this.context);
        }

        this.#linked = false;
        this.ecd = null;
    }
}
