import { Tag } from "../../src/engine/ecs/components/Tag.js";
import { EventType } from "../../src/engine/ecs/EventType.js";
import { Camera } from "../../src/engine/graphics/ecs/camera/Camera.js";
import { Light } from "../../src/engine/graphics/ecs/light/Light.js";
import Mesh from "../../src/engine/graphics/ecs/mesh/Mesh.js";
import { ParticleEmitter } from "../../src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js";
import LabelView from "../../src/view/common/LabelView.js";
import EmptyView from "../../src/view/elements/EmptyView.js";
import ImageView from "../../src/view/elements/image/ImageView.js";

/**
 *
 * @return {(function(entity:number, ecd:EntityComponentDataset, view:View):void)[]}
 */
export function makeEntityDecorators() {

    /**
     *
     * @param {number} entity
     * @param {EntityComponentDataset} ecd
     * @param {View} view
     */
    function decorate_tags(entity, ecd, view) {
        const tag = ecd.getComponent(entity, Tag);

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

        const vTags = new EmptyView({ classList: ['tag-container'] });

        view.addChild(vTags);

        tag.traverse(n => {

            const lTag = new LabelView(n, {
                classList: ['tag']
            });

            vTags.addChild(lTag);
        });
    }

    const component_icons = new Map([
        [Mesh, "data/textures/icons/editor/cube-shaded-v1.png"],
        [ParticleEmitter, "data/textures/icons/editor/particles.png"],
        [Light, "data/textures/icons/editor/light.png"],
        [Camera, "data/textures/icons/editor/camera.png"],
        [Tag, "data/textures/icons/editor/tag-v0.png"],
    ]);

    /**
     *
     * @param {number} entity
     * @param {EntityComponentDataset} ecd
     * @param {View} view
     */
    function decorate_component_icons(entity, ecd, view) {

        const vIconContainer = new EmptyView({
            css: {
                pointerEvents: "none",
                display: "flex",
                flexDirection: "row",
                justifyContent: "flex-end",
                filter: "drop-shadow(0 0 2px rgba(0,0,0,0.6))"
            }
        });

        /**
         *
         * @type {Map<any, View>}
         */
        const icons = new Map();

        function update() {

            for (const [Klass, icon_url] of component_icons) {

                const has_icon = icons.has(Klass);
                const has_component = ecd.hasComponent(entity, Klass);

                if (!has_icon && has_component) {

                    const icon = new ImageView(icon_url);

                    icon.size.set(18, 18);

                    vIconContainer.addChild(icon);

                    icons.set(Klass, icon);

                } else if (has_icon && !has_component) {
                    vIconContainer.removeChild(icons.get(Klass));

                    icons.delete(Klass);
                }

            }
        }

        function subscribe() {
            ecd.addEntityEventListener(entity, EventType.ComponentAdded, update);
            ecd.addEntityEventListener(entity, EventType.ComponentRemoved, update);
        }

        function unsubscribe() {
            ecd.removeEntityEventListener(entity, EventType.ComponentAdded, update);
            ecd.removeEntityEventListener(entity, EventType.ComponentRemoved, update);
        }

        view.on.linked.add(subscribe);
        view.on.linked.add(update);
        view.on.unlinked.add(unsubscribe);

        view.addChild(vIconContainer);


    }

    return [
        // decorate_tags,
        decorate_component_icons
    ];
}
