import { buildObjectEditorFromRegistry } from "./createObjectEditor.js";
import { Transform } from "../../../src/engine/ecs/transform/Transform.js";
import Vector3 from "../../../src/core/geom/Vector3.js";
import Signal from "../../../src/core/events/signal/Signal.js";
import Quaternion from "../../../src/core/geom/Quaternion.js";
import { seededRandom } from "../../../src/core/math/random/seededRandom.js";
import Clock from "../../../src/engine/Clock.js";
import { TypeEditor } from "./TypeEditor.js";
import { Vector3Editor } from "./editors/geom/Vector3Editor.js";
import { QuaternionEditor } from "./editors/geom/QuaternionEditor.js";
import { noEditor } from "./editors/common/noEditor.js";
import { TransformEditor } from "./editors/ecs/TransformEditor.js";
import { Sampler2D } from "../../../src/engine/graphics/texture/sampler/Sampler2D.js";
import { Light } from "../../../src/engine/graphics/ecs/light/Light.js";
import { Sampler2DEditor } from "./editors/Sampler2DEditor.js";
import Vector1 from "../../../src/core/geom/Vector1.js";
import { Color } from "../../../src/core/color/Color.js";
import { ColorEditor } from "./editors/ColorEditor.js";
import { Vector1Editor } from "./editors/geom/Vector1Editor.js";
import ObservedBoolean from "../../../src/core/model/ObservedBoolean.js";
import ObservedEnum from "../../../src/core/model/ObservedEnum.js";
import { LightType } from "../../../src/engine/graphics/ecs/light/LightType.js";
import { ShadedGeometry } from "../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
import { BoxBufferGeometry, BufferGeometry, Material, MeshStandardMaterial, Texture } from "three";
import { SGMesh } from "../../../src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js";
import { ParticleEmitter } from "../../../src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js";
import { BufferGeometryEditor } from "./editors/three/BufferGeometryEditor.js";
import { MaterialEditor } from "./editors/three/MaterialEditor.js";
import { ObservedEnumEditor } from "./editors/ObservedEnumEditor.js";
import { ObservedBooleanEditor } from "./editors/ObservedBooleanEditor.js";
import { StringEditor } from "./editors/primitive/StringEditor.js";
import { BooleanEditor } from "./editors/primitive/BooleanEditor.js";
import { NumberEditor } from "./editors/primitive/NumberEditor.js";
import {
    ParameterLookupTable
} from "../../../src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js";
import { ParameterLookupTableEditor } from "./editors/ecs/ParameterLookupTableEditor.js";
import List from "../../../src/core/collection/list/List.js";
import { ParticleLayer } from "../../../src/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js";
import { NumericInterval } from "../../../src/core/math/interval/NumericInterval.js";
import { NumericIntervalEditor } from "./editors/NumericIntervalEditor.js";
import { ObjectEditor } from "./editors/primitive/ObjectEditor.js";
import { ListEditor } from "./editors/collection/ListEditor.js";
import Trail2D from "../../../src/engine/graphics/ecs/trail2d/Trail2D.js";
import { ParticleEmitterLayerEditor } from "./editors/ecs/ParticleEmitterLayerEditor.js";
import { ParticleEmitterEditor } from "./editors/ecs/ParticleEmitterEditor.js";
import Vector4 from "../../../src/core/geom/Vector4.js";
import { Vector4Editor } from "./editors/geom/Vector4Editor.js";
import { Trail2DEditor } from "./editors/ecs/Trail2DEditor.js";
import GridObstacle from "../../../src/engine/grid/obstacle/GridObstacle.js";
import { Vector2Editor } from "./editors/geom/Vector2Editor.js";
import Vector2 from "../../../src/core/geom/Vector2.js";
import { randomIntegerBetween } from "../../../src/core/math/random/randomIntegerBetween.js";
import { GridObstacleEditor } from "./editors/ecs/GridObstacleEditor.js";
import { EngineHarness } from "../../../src/engine/EngineHarness.js";
import Terrain from "../../../src/engine/ecs/terrain/ecs/Terrain.js";
import WorkerProxy from "../../../src/core/process/worker/WorkerProxy.js";
import { TextureEditor } from "./editors/three/TextureEditor.js";
import { HTMLElementEditor } from "./editors/HTMLElementEditor.js";
import { TerrainLayerEditor } from "./editors/ecs/terrain/TerrainLayerEditor.js";
import { TerrainLayer } from "../../../src/engine/ecs/terrain/ecs/layers/TerrainLayer.js";
import ObservedString from "../../../src/core/model/ObservedString.js";
import { ObservedStringEditor } from "./editors/ObservedStringEditor.js";
import { TerrainOverlay } from "../../../src/engine/ecs/terrain/overlay/TerrainOverlay.js";
import { TerrainOverlayEditor } from "./editors/ecs/terrain/TerrainOverlayEditor.js";
import { TerrainEditor } from "./editors/ecs/terrain/TerrainEditor.js";
import { SplatMapping } from "../../../src/engine/ecs/terrain/ecs/splat/SplatMapping.js";
import { SplatMappingEditor } from "./editors/ecs/terrain/SplatMappingEditor.js";
import { TerrainLayersEditor } from "./editors/ecs/terrain/TerrainLayersEditor.js";
import { TerrainLayers } from "../../../src/engine/ecs/terrain/ecs/layers/TerrainLayers.js";
import {
    SimulationStepDefinition
} from "../../../src/engine/graphics/particles/particular/engine/simulator/SimulationStepDefinition.js";
import { SimulationStepDefinitionEditor } from "./editors/ecs/SimulationStepDefinitionEditor.js";
import { ArrayEditor } from "./editors/primitive/ArrayEditor.js";
import { ParameterTrackEditor } from "./editors/ecs/ParameterTrackEditor.js";
import { ParameterTrack } from "../../../src/engine/graphics/particles/particular/engine/parameter/ParameterTrack.js";

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

registry.set(Terrain, new TerrainEditor());
registry.set(TerrainLayer, new TerrainLayerEditor());
registry.set(SplatMapping, new SplatMappingEditor());
registry.set(TerrainOverlay, new TerrainOverlayEditor());
registry.set(TerrainLayers, new TerrainLayersEditor());

registry.set(GridObstacle, new GridObstacleEditor());

registry.set(ParticleLayer, new ParticleEmitterLayerEditor());
registry.set(ParticleEmitter, new ParticleEmitterEditor());
registry.set(ParameterTrack, new ParameterTrackEditor());
registry.set(SimulationStepDefinition, new SimulationStepDefinitionEditor());

registry.set(Trail2D, new Trail2DEditor());

registry.set(Number, new NumberEditor());
registry.set(Boolean, new BooleanEditor());
registry.set(String, new StringEditor());
registry.set(Array, new ArrayEditor());
registry.set(Object, new ObjectEditor());

registry.set(NumericInterval, new NumericIntervalEditor());
registry.set(List, new ListEditor());
registry.set(ObservedBoolean, new ObservedBooleanEditor());
registry.set(ObservedEnum, new ObservedEnumEditor());
registry.set(Material, new MaterialEditor());
registry.set(BufferGeometry, new BufferGeometryEditor());
registry.set(Texture, new TextureEditor());
registry.set(Color, new ColorEditor());
registry.set(Vector4, new Vector4Editor());
registry.set(Vector3, new Vector3Editor());
registry.set(Vector2, new Vector2Editor());
registry.set(Vector1, new Vector1Editor());
registry.set(ObservedString, new ObservedStringEditor());

registry.set(Quaternion, new QuaternionEditor());
registry.set(Transform, new TransformEditor());
registry.set(ParameterLookupTable, new ParameterLookupTableEditor());
registry.set(Sampler2D, new Sampler2DEditor());

registry.set(HTMLElement, new HTMLElementEditor());
registry.set(HTMLCanvasElement, new HTMLElementEditor());

registry.set(WorkerProxy, noEditor());
registry.set(Signal, noEditor());

registry.set(Uint8Array, noEditor());
registry.set(Uint16Array, noEditor());
registry.set(Uint32Array, noEditor());

registry.set(Int8Array, noEditor());
registry.set(Int16Array, noEditor());
registry.set(Int32Array, noEditor());

registry.set(Float32Array, noEditor());
registry.set(Float64Array, noEditor());

registry.set(CanvasRenderingContext2D, noEditor());


const random = seededRandom(7);

const transform = new Transform();

const light = new Light();
light.type.set(LightType.SPOT);
light.color.parse('rgb(255,145,0)');

const sg = ShadedGeometry.from(new BoxBufferGeometry(), new MeshStandardMaterial({
    color: 0xFFFF00
}));
const sgMesh = SGMesh.fromURL('bla-bla');
const particleEmitter = ParticleEmitter.fromJSON({
    "position": {
        "x": 22,
        "y": 0,
        "z": 18
    },
    "scale": {
        "x": 0.25,
        "y": 0.25,
        "z": 0.25
    },
    "rotation": {
        "x": 0,
        "y": -0.4073445409440101,
        "z": 0,
        "w": 0.9132745616533474
    },
    "parameters": [
        {
            "name": "scale",
            "itemSize": 1,
            "defaultTrackValue": {
                "itemSize": 1,
                "data": [
                    1
                ],
                "positions": [
                    0
                ]
            }
        },
        {
            "name": "color",
            "itemSize": 4,
            "defaultTrackValue": {
                "itemSize": 4,
                "data": [
                    1,
                    1,
                    1,
                    1
                ],
                "positions": [
                    0
                ]
            }
        }
    ],
    "preWarm": true,
    "readDepth": true,
    "softDepth": true,
    "velocityAlign": false,
    "receiveLight": true,
    "blendingMode": 0,
    "layers": [
        {
            "imageURL": "data/textures/particle/UETools/x64/Smoke_14.png",
            "particleLife": {
                "min": 6,
                "max": 8
            },
            "particleSize": {
                "min": 0.4,
                "max": 0.4
            },
            "particleRotation": {
                "min": 0,
                "max": 0
            },
            "particleRotationSpeed": {
                "min": 0,
                "max": 0
            },
            "emissionShape": 3,
            "emissionFrom": 1,
            "emissionRate": 2,
            "emissionImmediate": 0,
            "parameterTracks": [
                {
                    "name": "color",
                    "track": {
                        "itemSize": 4,
                        "data": [
                            0.45,
                            0.45,
                            0.45,
                            0,

                            0.6,
                            0.6,
                            0.6,
                            0.3,

                            0.6,
                            0.6,
                            0.6,
                            0.2,

                            0.6,
                            0.6,
                            0.6,
                            0
                        ],
                        "positions": [
                            0,
                            0.2,
                            0.7,
                            1
                        ]
                    }
                },
                {
                    "name": "scale",
                    "track": {
                        "itemSize": 1,
                        "data": [
                            0.2493331876981993,
                            0.6134230340328317,
                            1.0759788492641973,
                            1.261059004570864
                        ],
                        "positions": [
                            0,
                            0.4176470588235294,
                            0.7588235294117648,
                            1
                        ]
                    }
                }
            ],
            "position": {
                "x": 2.7,
                "y": 2.3,
                "z": 1.5
            },
            "scale": {
                "x": 1,
                "y": 1,
                "z": 1
            },
            "particleVelocityDirection": {
                "direction": {
                    "x": 0,
                    "y": 1,
                    "z": 0
                },
                "angle": 0.1
            },
            "particleSpeed": {
                "min": 0.2,
                "max": 0.22
            },
            "steps": [
                {
                    "type": "FixedPhysics",
                    "parameters": []
                }
            ]
        },

    ]
});

const trail2D = new Trail2D();

const gridObstacle = new GridObstacle();
gridObstacle.resize(10, 10);
gridObstacle.traverseMask(0, 0, (x, y) => {
    gridObstacle.writePoint(x, y, randomIntegerBetween(random, 0, 1))
});


async function makeTerrain() {
    const harness = new EngineHarness();

    await harness.initialize()

    const engine = harness.engine;

    engine.viewStack.el.parentElement.removeChild(engine.viewStack.el);

    return await EngineHarness.buildTerrain({ engine: engine })
}

async function exec() {

    // const terrain = await makeTerrain();

    const object = particleEmitter;


// transform.rotation.random(random);

    const view = buildObjectEditorFromRegistry(object, registry);

    console.warn(object);

    document.body.append(view.el);

    document.body.style.background = 'rgb(37,73,0)';

    view.link();

    view.css({
        background: 'grey'
    });
}

exec();

const clock = new Clock();
clock.start();

function animate() {
    requestAnimationFrame(animate);

    const delta = clock.getDelta();
    const time = clock.getElapsedTime();

    // transform.rotation.lookAt(Vector3.zero, new Vector3(Math.cos(time), Math.sin(time), time % 10))
}

animate();
