import { Sprite, SpriteMaterial } from "three";
import { assert } from "../../../src/core/assert.js";
import Entity from "../../../src/engine/ecs/Entity.js";
import Renderable from "../../../src/engine/ecs/renderable/Renderable.js";
import { Transform } from "../../../src/engine/ecs/transform/Transform.js";
import { make3DSymbolicDisplay } from "./make3DSymbolicDisplay.js";
import { synchronizeTransform } from "./synchronizeTransform.js";

const SPRITE_SIZE = 0.3;

/**
 * @template C,T
 * @param {Engine} engine
 * @param {string} iconURL
 * @param {C} ComponentClass
 * @returns {ComponentSymbolicDisplay}
 */
export function makePositionedIconDisplaySymbol(engine, iconURL, ComponentClass) {
    assert.defined(engine, 'engine');
    assert.ok(engine.isEngine, 'engine.isEngine');

    const assetManager = engine.assetManager;

    const spriteMaterial = new SpriteMaterial();
    spriteMaterial.depthTest = false;
    spriteMaterial.transparent = true;
    spriteMaterial.depthWrite = true;

    assetManager.promise(iconURL, 'texture').then(asset => {

        spriteMaterial.map = asset.create();
        spriteMaterial.needsUpdate = true;
    });

    return make3DSymbolicDisplay({
        engine,
        /**
         *
         * @param component
         * @param transform
         * @param entity
         * @param {SymbolicDisplayInternalAPI} api
         * @return {Entity}
         */
        factory([component, transform, entity], api) {

            const b = new Entity();

            const sprite = new Sprite(spriteMaterial);
            sprite.frustumCulled = false;
            sprite.matrixAutoUpdate = false;
            //draw on top of everything else
            sprite.renderOrder = 9999;

            const cR = new Renderable(sprite);
            const cT = new Transform();


            //sprite size
            cT.scale.set(SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE);
            cR.boundingBox.setBounds(-0.5, -0.5, -0.5, 0.5, 0.5, 0.5);

            synchronizeTransform(transform, cT, api.bindings, true, false, false);

            b.add(cR);
            b.add(cT);

            api.emit(b);
        },
        components: [ComponentClass, Transform]
    });
}
