import { EngineHarness } from "../../../../EngineHarness.js";
import Entity from "../../../../ecs/Entity.js";
import { SGMesh } from "../../mesh-v2/aggregate/SGMesh.js";
import { Transform } from "../../../../ecs/transform/Transform.js";
import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
import { GameAssetType } from "../../../../asset/GameAssetType.js";
import { FPDecalSystem } from "./FPDecalSystem.js";
import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
import { SGMeshSystem } from "../../mesh-v2/aggregate/SGMeshSystem.js";
import { ShadedGeometrySystem } from "../../mesh-v2/ShadedGeometrySystem.js";
import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
import ListView from "../../../../../view/common/ListView.js";
import List from "../../../../../core/collection/list/List.js";
import ImageView from "../../../../../view/elements/image/ImageView.js";
import GUIElement from "../../../../ecs/gui/GUIElement.js";
import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
import ObservedInteger from "../../../../../core/model/ObservedInteger.js";
import ObservedString from "../../../../../core/model/ObservedString.js";
import { MouseEvents } from "../../../../input/devices/events/MouseEvents.js";

class EditorState {
    selected_entity = new ObservedInteger(-1)

}

/**
 *
 * @param {Engine} engine
 * @param {ObservedString} selected
 * @returns {ImageView|ListView}
 */
function makeDecalSelector({ engine, selected }) {
    const decal_uris = new List(
        `data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_11_t.png`
            .trim()
            .split('\n')
            .map(s => s.trim())
            .filter(s => s.length > 0)
    );

    const listView = new ListView(decal_uris, {
        elementFactory(el) {
            const element_view = new ImageView(el);

            element_view.css({
                pointerEvents: 'auto',
                boxSizing: 'border-box',
            });

            element_view.size.setScalar(64);

            const process_selection = (e) => {
                const is_selected = e === el;

                element_view.css({
                    border: is_selected ? `2px solid red` : 'none'
                });
            };

            element_view.bindSignal(selected.onChanged, process_selection);
            process_selection(selected.getValue());

            element_view.el.addEventListener(MouseEvents.Click, () => {
                selected.set(el);
            });

            return element_view;
        }
    });

    listView.css({
        backgroundImage:
            `url(../data/textures/utility/checkers_white_grey_256x256.png)`,
        backgroundSize: "24px 24px", /* Must be a square */
        backgroundPosition: "0 0, 12px 0, 12px -12px, 0px 12px"
    });

    listView.size.set(600, 128);

    return listView;
}

/**
 *
 * @param {Engine} engine
 */
async function main(engine) {

    await EngineHarness.buildBasics({
        engine,
        enableWater: false,
        cameraFarDistance: 300
    });

    const ecd = engine.entityManager.dataset;

    new Entity()
        .add(SGMesh.fromURL("moicon/gnutti_not_optimized/model.gltf"))
        .add(Transform.fromJSON({
            position: { x: 10, y: 3, z: 10 },
            scale: 1.5
        }));

    // decal selector

    const selected_decal_uri = new ObservedString('');

    new Entity()
        .add(GUIElement.fromView(makeDecalSelector({ engine, selected: selected_decal_uri })))
        .build(ecd);

}

new EngineHarness()
    .initialize({
        configuration(config, engine) {
            const gltfAssetLoader = new GLTFAssetLoader();

            config.addLoader(GameAssetType.ModelGLTF_JSON, gltfAssetLoader);
            config.addLoader(GameAssetType.ModelGLTF, gltfAssetLoader);

            config.addSystem(new FPDecalSystem(engine));
            config.addSystem(new BehaviorSystem(engine))
            config.addSystem(new SGMeshSystem(engine));
            config.addSystem(new ShadedGeometrySystem(engine));
            config.addSystem(new TransformAttachmentSystem(engine));

            config.addSystem(new GUIElementSystem(engine.gui.view, engine));
        }
    }).then(main);
