import { vec3 } from "gl-matrix";
import { DoubleSide, LineBasicMaterial, MeshStandardMaterial } from "three";
import '../../../../../../../../../css/game.scss';
import { makeHelperBoxGeometry } from "../../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
import { makeSolidArrowGeometry } from "../../../../../../editor/process/symbolic/makeSolidArrowGeometry.js";
import Quaternion from "../../../../../core/geom/Quaternion.js";
import { v2_distance } from "../../../../../core/geom/vec2/v2_distance.js";
import Vector2 from "../../../../../core/geom/Vector2.js";
import Vector3 from "../../../../../core/geom/Vector3.js";
import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
import { randomFromArray } from "../../../../../core/math/random/randomFromArray.js";
import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
import { countTask } from "../../../../../core/process/task/util/countTask.js";
import { TaskLoadingScreen } from "../../../../../view/task/TaskLoadingScreen.js";
import { GameAssetType } from "../../../../asset/GameAssetType.js";
import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
import Entity from "../../../../ecs/Entity.js";
import { EntityFlags } from "../../../../ecs/EntityFlags.js";
import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
import { Transform } from "../../../../ecs/transform/Transform.js";
import { EngineHarness } from "../../../../EngineHarness.js";
import { BehaviorComponent } from "../../../../intelligence/behavior/ecs/BehaviorComponent.js";
import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
import { RotationBehavior } from "../../../../intelligence/behavior/util/RotationBehavior.js";
import { OctahedralUvEncoder } from "../../../impostors/octahedral/grid/OctahedralUvEncoder.js";
import { ForwardPlusRenderingPlugin } from "../../../render/forward_plus/plugin/ForwardPlusRenderingPlugin.js";
import { Gizmo } from "../../../render/gizmo/Gizmo.js";
import { GizmoRenderingPlugin } from "../../../render/gizmo/GizmoRenderingPlugin.js";
import { SGMesh } from "../../mesh-v2/aggregate/SGMesh.js";
import { SGMeshSystem } from "../../mesh-v2/aggregate/SGMeshSystem.js";
import { DrawMode } from "../../mesh-v2/DrawMode.js";
import { ShadedGeometry } from "../../mesh-v2/ShadedGeometry.js";
import { ShadedGeometrySystem } from "../../mesh-v2/ShadedGeometrySystem.js";
import { Decal } from "./Decal.js";
import { FPDecalSystem } from "./FPDecalSystem.js";

const decal_urls = `data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_13_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_02_t.png
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
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_13_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/artifact_14_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_10_b.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/bag_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_13_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_14_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_15_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_16_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/book_17_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/orb_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/potion_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/rune_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_12_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/scroll_13_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_01_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_02_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_03_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_04_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_05_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_06_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_07_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_08_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_09_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_10_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_11_t.png
data/textures/icons/FantasyIconsMegaPack/MagicItems/MagicItems_png/transparent/x64/staff_12_t.png
data/textures/icons/sci-fi-nathan/v6/Proc normal_3.png
data/textures/icons/sci-fi-nathan/v6/Proc strong_1.png
data/textures/icons/sci-fi-nathan/v6/Proc strong_2.png
data/textures/icons/sci-fi-nathan/v6/Proc strong_3.png
data/textures/icons/sci-fi-nathan/v6/Proc very strong_1.png
data/textures/icons/sci-fi-nathan/v6/Proc very strong_2.png
data/textures/icons/sci-fi-nathan/v6/Proc very strong_3.png
data/textures/icons/sci-fi-nathan/v6/Proc very weak_1.png
data/textures/icons/sci-fi-nathan/v6/Proc very weak_2.png
data/textures/icons/sci-fi-nathan/v6/Proc very weak_3.png
data/textures/icons/sci-fi-nathan/v6/Proc weak_1.png
data/textures/icons/sci-fi-nathan/v6/Proc weak_2.png
data/textures/icons/sci-fi-nathan/v6/Proc weak_3.png
data/textures/icons/sci-fi-nathan/v6/Core normal_1.png
data/textures/icons/sci-fi-nathan/v6/Core normal_2.png
data/textures/icons/sci-fi-nathan/v6/Core normal_3.png
data/textures/icons/sci-fi-nathan/v6/Core strong_1.png
data/textures/icons/sci-fi-nathan/v6/Core strong_2.png
data/textures/icons/sci-fi-nathan/v6/Core strong_3.png
data/textures/icons/sci-fi-nathan/v6/Core very strong_1.png
data/textures/icons/sci-fi-nathan/v6/Core very strong_2.png
data/textures/icons/sci-fi-nathan/v6/Core very strong_3.png
data/textures/icons/sci-fi-nathan/v6/Core very weak_1.png
data/textures/icons/sci-fi-nathan/v6/Core very weak_2.png
data/textures/icons/sci-fi-nathan/v6/Core very weak_3.png
data/textures/icons/sci-fi-nathan/v6/Core weak_1.png
data/textures/icons/sci-fi-nathan/v6/Core weak_2.png
data/textures/icons/sci-fi-nathan/v6/Core weak_3.png
data/textures/icons/sci-fi-nathan/v6/Memory normal_1.png
data/textures/icons/sci-fi-nathan/v6/Memory normal_2.png
data/textures/icons/sci-fi-nathan/v6/Memory normal_3.png
data/textures/icons/sci-fi-nathan/v6/Memory strong_1.png
data/textures/icons/sci-fi-nathan/v6/Memory strong_2.png
data/textures/icons/sci-fi-nathan/v6/Memory strong_3.png
data/textures/icons/sci-fi-nathan/v6/Memory very strong_1.png
data/textures/icons/sci-fi-nathan/v6/Memory very strong_2.png
data/textures/icons/sci-fi-nathan/v6/Memory very strong_3.png
data/textures/icons/sci-fi-nathan/v6/Memory very weak_1.png
data/textures/icons/sci-fi-nathan/v6/Memory very weak_2.png
data/textures/icons/sci-fi-nathan/v6/Memory very weak_3.png
data/textures/icons/sci-fi-nathan/v6/Memory weak_1.png
data/textures/icons/sci-fi-nathan/v6/Memory weak_2.png
data/textures/icons/sci-fi-nathan/v6/Memory weak_3.png
data/textures/icons/sci-fi-nathan/v6/Module normal_1.png
data/textures/icons/sci-fi-nathan/v6/Module normal_2.png
data/textures/icons/sci-fi-nathan/v6/Module normal_3.png
data/textures/icons/sci-fi-nathan/v6/Module strong_1.png
data/textures/icons/sci-fi-nathan/v6/Module strong_2.png
data/textures/icons/sci-fi-nathan/v6/Module strong_3.png
data/textures/icons/sci-fi-nathan/v6/Module very strong_1.png
data/textures/icons/sci-fi-nathan/v6/Module very strong_2.png
data/textures/icons/sci-fi-nathan/v6/Module very strong_3.png
data/textures/icons/sci-fi-nathan/v6/Module very weak_1.png
data/textures/icons/sci-fi-nathan/v6/Module very weak_2.png
data/textures/icons/sci-fi-nathan/v6/Module very weak_3.png
data/textures/icons/sci-fi-nathan/v6/Module weak_1.png
data/textures/icons/sci-fi-nathan/v6/Module weak_2.png
data/textures/icons/sci-fi-nathan/v6/Module weak_3.png
data/textures/icons/sci-fi-nathan/v6/Power normal_1.png
data/textures/icons/sci-fi-nathan/v6/Power normal_2.png
data/textures/icons/sci-fi-nathan/v6/Power normal_3.png
data/textures/icons/sci-fi-nathan/v6/Power strong_1.png
data/textures/icons/sci-fi-nathan/v6/Power strong_2.png
data/textures/icons/sci-fi-nathan/v6/Power strong_3.png
data/textures/icons/sci-fi-nathan/v6/Power very strong_1.png
data/textures/icons/sci-fi-nathan/v6/Power very strong_2.png
data/textures/icons/sci-fi-nathan/v6/Power very strong_3.png
data/textures/icons/sci-fi-nathan/v6/Power very weak_1.png
data/textures/icons/sci-fi-nathan/v6/Power very weak_2.png
data/textures/icons/sci-fi-nathan/v6/Power very weak_3.png
data/textures/icons/sci-fi-nathan/v6/Power weak_1.png
data/textures/icons/sci-fi-nathan/v6/Power weak_2.png
data/textures/icons/sci-fi-nathan/v6/Power weak_3.png
data/textures/icons/sci-fi-nathan/v6/Proc normal_1.png
data/textures/icons/sci-fi-nathan/v6/Proc normal_2.png
data/textures/utility/sampling-test.png`
    .split('\n')
    .map(a => a.trim());

function promise_time_out(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}

/**
 *
 * @param ecd
 * @param {number} x
 * @param {number} y
 * @param {number} size_x
 * @param {number} size_y
 * @param {number} spacing
 * @param {string[]} textures
 */
function grid(ecd, offset_x, offset_y, x, y, size_x, size_y, spacing, textures) {

    const random = seededRandom();

    for (let i = 0; i < x; i++) {
        for (let j = 0; j < y; j++) {

            const decal = new Decal();

            decal.uri = randomFromArray(random, textures);

            const entity = new Entity();

            entity.clearFlag(EntityFlags.WatchDestruction);

            const transform = new Transform();
            transform.position.set(
                i * (size_x + spacing) + offset_x,
                0,
                j * (size_y + spacing) + offset_y,
            );
            // transform.rotation.alignToDirection(Vector3.down);
            // transform.rotation.set(0,0,-0.7,0.7);
            // transform.rotation.set(0,0.7,0,0.7);
            transform.rotation.set(-0.7, 0, 0, 0.7);
            // transform.rotation.random(random);
            transform.scale.set(size_x, size_y, 1);
            // transform.scale.setScalar(1);

            entity
                .add(transform)
                .add(decal)
                .build(ecd);

        }
    }

}

function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
    const uv = new OctahedralUvEncoder();

    const GRID_SIZE = 16;

    const CELL_SIZE = 1;

    const SPACING = CELL_SIZE * 1.2;
    // const SPACING = CELL_SIZE * 0.6;

    const DEBUG_BOX = makeHelperBoxGeometry();

    const random = seededRandom(7);

    for (let i = 0; i < GRID_SIZE; i++) {
        for (let j = 0; j < GRID_SIZE; j++) {

            const direction = [];

            uv.uv_to_unit(direction, [i / (GRID_SIZE - 1), j / (GRID_SIZE - 1)]);

            vec3.negate(direction, direction);

            const decal = new Decal();

            // decal.uri = decal_urls[1];
            decal.uri = 'moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Emergency/400px/E001 – Emergency exit (left hand).png';

            const entity = new Entity();

            entity.clearFlag(EntityFlags.WatchDestruction);

            const transform = new Transform();
            transform.position.set(
                SPACING * i,
                SPACING * j,
                0,
            );
            transform.scale.setScalar(CELL_SIZE);
            transform.rotation._lookRotation(direction[0], direction[2], direction[1], 0, 1, 0);

            transform.multiplyTransforms(root_transform, transform);


            entity
                .add(ShadedGeometry.from(DEBUG_BOX, new LineBasicMaterial(), DrawMode.LineSegments))
                .add(transform)
                .add(decal)
                .build(ecd);

            // setInterval(()=>{
            //     decal.priority = Math.random();
            // },7000);

            // decal.priority = randomIntegerBetween(random,0,4096);
            decal.priority = v2_distance(i, j, GRID_SIZE * 0.5, GRID_SIZE * 0.5);


            // make an arrow helper
            const arrow_transform = Transform.fromJSON({
                position: new Vector3(0, 0, -0.5)
            });
            arrow_transform.multiplyTransforms(transform, arrow_transform);

            new Entity()
                .add(ShadedGeometry.from(makeSolidArrowGeometry(), new MeshStandardMaterial({
                    side: DoubleSide
                }), DrawMode.Triangles))
                .add(arrow_transform)
                .build(ecd);
        }
    }
}

/**
 * @returns {Entity}
 */
function makeNormalTestDecal() {
    const decal = new Decal();

    decal.uri = decal_urls[1];

    const entity = new Entity();

    entity.clearFlag(EntityFlags.WatchDestruction);

    const transform = new Transform();
    transform.position.set(
        5,
        0,
        5
    );
    transform.scale.setScalar(1);
    transform.rotation.lookRotation(Vector3.down);

    entity
        .add(ShadedGeometry.from(DEBUG_BOX, new LineBasicMaterial(), DrawMode.LineSegments))
        .add(transform)
        .add(decal)
        .add(BehaviorComponent.from(RotationBehavior.fromJSON({ speed: 1, axis: Vector3.left })))

    return entity;
}

function sample_grid(ecd) {
    const q_down = new Quaternion();
    q_down.lookRotation(Vector3.down)

    makeNormalTestGridDecal(ecd, Transform.fromJSON({
        position: new Vector3(5, 0, 5),
        rotation: q_down
    }));


    const q_forward = new Quaternion();
    q_forward.lookRotation(Vector3.forward)

    const t_forward_grid = Transform.fromJSON({
        position: new Vector3(5, 4, 5),
        rotation: q_forward
    });
    makeNormalTestGridDecal(ecd, t_forward_grid);

    new Entity()
        .add(SGMesh.fromURL('data/models/snaps/cube_white.gltf'))
        .add(Transform.fromJSON({
            position: new Vector3(14, 1, 4.8),
            rotation: t_forward_grid.rotation,
            scale: new Vector3(25, 25, 0.1)
        }))
        .build(ecd);
}

function raycast_tool(engine) {
    let hits = [];

    engine.graphics.on.preRender.add(() => {

        hits.forEach(hit => {

            Gizmo.draw_solid_sphere(hit.contact.position.asArray(), 0.1);

        });

    });

    engine.devices.pointer.position.onChanged.add(() => {
        const ray_origin = new Vector3();
        const ray_direction = new Vector3();


        const pointer = engine.devices.pointer.position;

        const ndc = new Vector2();

        engine.graphics.normalizeViewportPoint(pointer, ndc);
        engine.graphics.viewportProjectionRay(ndc.x, ndc.y, ray_origin, ray_direction);

        hits = engine.entityManager.getSystem(FPDecalSystem)?.raycast(
            ray_origin.x, ray_origin.y, ray_origin.z,
            ray_direction.x, ray_direction.y, ray_direction.z
        );

        console.warn(hits);

    });
}

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

    const fpp = engine.plugins.getPlugin(ForwardPlusRenderingPlugin);
    fpp.setClusterResolution(12, 8, 1);

    const TERRAIN_SIZE = 1000;

    await EngineHarness.buildBasics({
        engine,
        enableWater: false,
        cameraFarDistance: 300,
        terrainResolution: 1,
        terrainSize: new Vector2(TERRAIN_SIZE, TERRAIN_SIZE)
    });

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


    const random = seededRandom();

    const ENTITY_COUNT = 100000;

    const ecd = engine.entityManager.dataset;

    console.log('Decal image pool size:', decal_urls.length);

    function makeOne() {
        const decal = new Decal();

        decal.uri = randomFromArray(random, decal_urls);

        const entity = new Entity();

        entity.clearFlag(EntityFlags.WatchDestruction);

        const transform = new Transform();
        transform.position.set(
            randomFloatBetween(random, 0, TERRAIN_SIZE),
            randomFloatBetween(random, 0, 0),
            randomFloatBetween(random, 0, TERRAIN_SIZE)
        );
        transform.rotation._lookRotation(0, -1, 0, 0, 1, 0);
        transform.scale.set(1,1,0.5);

        entity
            .add(transform)
            .add(decal)
        // .add(BehaviorComponent.fromOne(RotationBehavior.fromJSON({ speed: 1 })))

        entity.build(ecd);
    }

    // for (let i = 0; i < ENTITY_COUNT; i++) {
    //     makeOne();
    //
    // }

    const task = countTask(0, ENTITY_COUNT, makeOne);

    //sample_grid(ecd);

    TaskLoadingScreen.instance.load(engine, task);

    // console.profile('spawn');

    task.promise().then(() => {
        // console.profileEnd('spawn');
    });

    engine.executor.run(task);


    //grid(engine.entityManager.dataset, 20,10,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));

    //grid(engine.entityManager.dataset, 20,30,80, 25, .4, .6, .1, decal_urls.slice(105, 105+3));
    // await promise_time_out(10);
    // raycast_tool(engine);

}

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

            config.addPlugin(GizmoRenderingPlugin);

            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));
        }
    }).then(main);
