import Entity from "../../../ecs/Entity.js";
import GUIElement from "../../../ecs/gui/GUIElement.js";
import GUIElementSystem from "../../../ecs/gui/GUIElementSystem.js";
import ViewportPosition from "../../../ecs/gui/position/ViewportPosition.js";
import ViewportPositionSystem from "../../../ecs/gui/position/ViewportPositionSystem.js";
import { EngineConfiguration } from "../../../EngineConfiguration.js";
import { EngineHarness } from "../../../EngineHarness.js";
import { AnimationCurve } from "../AnimationCurve.js";
import { build_plot_entity_from_array } from "../draw/build_plot_entity_from_array.js";
import { Keyframe } from "../Keyframe.js";
import { CURVE_EASE_IN_OUT } from "../preset/CURVE_EASE_IN_OUT.js";
import { downsample_float_array_curve_by_error } from "./downsample_float_array_curve_by_error.js";
import { sample_animation_curve_to_float_array } from "./sample_animation_curve_to_float_array.js";
import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
import {CurveEditorView} from "../editor/CurveEditorView.js";

const eh = new EngineHarness();

async function init() {

    const config = new EngineConfiguration();

    const engine = eh.engine;

    config.addSystem(new GUIElementSystem(engine.gameView, engine));
    config.addSystem(new ViewportPositionSystem(engine.gameView.size));

    await config.apply(engine);

    await eh.initialize();

    main(engine);
}

function build_error_scale(ecd, curve) {
    const curve_data = [];
    sample_animation_curve_to_float_array(curve_data, 0, curve, 256);


    build_plot_entity_from_array({
        data: curve_data,
        x: 10, y: 0
    }).build(ecd);

    const compressed_01 = [];
    downsample_float_array_curve_by_error(compressed_01, 0, curve_data, 0, curve_data.length, 0.01);

    build_plot_entity_from_array({
        data: compressed_01,
        x: 10, y: 202,
        label: '1%'
    }).build(ecd);

    const compressed_03 = [];
    downsample_float_array_curve_by_error(compressed_03, 0, curve_data, 0, curve_data.length, 0.03);

    build_plot_entity_from_array({
        data: compressed_03,
        x: 10, y: 404,
        label: '3%'
    }).build(ecd);

    const compressed_05 = [];
    downsample_float_array_curve_by_error(compressed_05, 0, curve_data, 0, curve_data.length, 0.05);

    build_plot_entity_from_array({
        data: compressed_05,
        x: 10, y: 606,
        label: '5%'
    }).build(ecd);

    const compressed_10 = [];
    downsample_float_array_curve_by_error(compressed_10, 0, curve_data, 0, curve_data.length, 0.10);

    build_plot_entity_from_array({
        data: compressed_10,
        x: 10, y: 808,
        label: '10%'
    }).build(ecd);
}

async function main(engine) {

    // EngineHarness.buildBasics({ engine });
    function sample_curve_0() {

        const curve = new AnimationCurve();

        curve.keys.push(Keyframe.from(0, 0));
        curve.keys.push(Keyframe.from(1, 1));
        curve.keys.push(Keyframe.from(2, 0.5));

        return curve;
    }

    function sample_curve_1() {

        const curve = new AnimationCurve();

        curve.keys.push(Keyframe.from(0, 0));
        curve.keys.push(Keyframe.from(0.1, 1));
        curve.keys.push(Keyframe.from(2, 0.5));

        return curve;
    }

    function sample_curve_2() {

        const curve = new AnimationCurve();

        curve.keys.push(Keyframe.from(0, 1));
        curve.keys.push(Keyframe.from(1, 2));
        curve.keys.push(Keyframe.from(2, 3));
        curve.keys.push(Keyframe.from(3, 4));

        return curve;
    }

    function sample_curve_3() {

        const curve = new AnimationCurve();

        curve.keys.push(Keyframe.from(0, 1));
        curve.keys.push(Keyframe.from(1, 1));
        curve.keys.push(Keyframe.from(2, 1));
        curve.keys.push(Keyframe.from(3, 1));

        return curve;
    }

    function sample_curve_4() {

        const curve = new AnimationCurve();

        curve.keys.push(Keyframe.from(0, 1, 0, 1));
        // curve.keys.push(Keyframe.from(1, 2, 1, -1));
        curve.keys.push(Keyframe.from(1, 2, -1, 1));
        curve.keys.push(Keyframe.from(2, 1));

        return curve;
    }

    function sample_curve_5() {

        const curve = new AnimationCurve();

        curve.add(Keyframe.from(0, 1, 0, -1));
        curve.add(Keyframe.from(10, 1, 1, 0));

        return curve;
    }

    // const curve = sample_curve_0();

    // curve.smoothAllTangents();

    // const curve = sample_curve_5();
    // const curve = CURVE_EASE_IN_OUT;

    const curve = new AnimationCurve();

    // curve.add(Keyframe.from(0, 0, 0, 0));
    // curve.add(Keyframe.from(0.4, 0.5, -1.4, 1));
    // curve.add(Keyframe.from(0.5, 0.5, -1.4, 1));
    // curve.add(Keyframe.from(0.6, 0.5, -1.4, 1));
    // curve.add(Keyframe.from(0.7, 0.5, -1.4, 1));
    // curve.add(Keyframe.from(1, 1, 0, 0));

    curve.add(Keyframe.from(-0.2, 0, 0, 0));
    curve.add(Keyframe.from(0.1, 1.5, -1.4, 1));
    curve.add(Keyframe.from(0.5, 0.2, -1.4, 1));
    curve.add(Keyframe.from(0.8, -0.5, -1.4, 1));
    curve.add(Keyframe.from(1.0, 0.5, -1.4, 1));
    curve.add(Keyframe.from(1.5, 1, 0, 0));


    const ecd = engine.entityManager.dataset;

    // build_error_scale(ecd, curve);

    console.log(curve);

    const editor_view = new CurveEditorView({
        curve,
        enableEdit:true
    });

    new Entity()
        .add(ViewportPosition.fromJSON({
            offset: { x: 0, y: 0 }
        }))
        .add(GUIElement.fromView(editor_view))
        .build(ecd);

}

init();
