import { System } from "../../../../ecs/System.js";
import Highlight from "../../highlight/Highlight.js";
import { SGMesh } from "./SGMesh.js";
import { SGMeshEvents } from "./SGMeshEvents.js";

export class SGMeshHighlightSystem extends System {
    constructor() {
        super();

        this.dependencies = [Highlight, SGMesh];
    }

    /**
     *
     * @param event
     * @param {number} entity
     * @private
     */
    __apply_highlight(event, entity) {
        const ecd = this.entityManager.dataset;

        const sg_mesh = ecd.getComponent(entity, SGMesh);

        if (sg_mesh === undefined) {
            return;
        }

        const highlight = ecd.getComponent(entity, Highlight);

        if (highlight === undefined) {
            return;
        }

        const node = sg_mesh.__node;

        if (node === null) {
            // not loaded yet
            console.warn(`SGMesh is not loaded yet: ${sg_mesh.url}`);
            return;
        }

        node.traverse(t => {
            t.entity.add(highlight);
        });
    }

    /**
     *
     * @param event
     * @param {number} entity
     * @private
     */
    __remove_highlight(event, entity) {

        const ecd = this.entityManager.dataset;

        const sg_mesh = ecd.getComponent(entity, SGMesh);

        const node = sg_mesh.__node;

        node.traverse(t => {
            t.entity.removeComponent(Highlight);
        });
    }

    /**
     *
     * @param {Highlight} highlight
     * @param {SGMesh} mesh
     * @param {number} entity
     */
    link(highlight, mesh, entity) {
        if (mesh.__node !== null) {
            this.__apply_highlight(undefined, entity);
        }

        const ecd = this.entityManager.dataset;

        ecd.addEntityEventListener(entity, SGMeshEvents.AssetLoaded, this.__apply_highlight, this);
    }

    /**
     *
     * @param {Highlight} highlight
     * @param {SGMesh} mesh
     * @param {number} entity
     */
    unlink(highlight, mesh, entity) {
        const ecd = this.entityManager.dataset;
        ecd.removeEntityEventListener(entity, SGMeshEvents.AssetLoaded, this.__apply_highlight, this);

        if (mesh.__node !== null) {
            this.__remove_highlight(undefined, entity);
        }
    }
}
