import { FrameRunner } from "../../../../../src/engine/graphics/FrameRunner.js";
import {
    convertTexture2Sampler2D
} from "../../../../../src/engine/graphics/texture/sampler/convertTexture2Sampler2D.js";
import { downloadSampler2DAsPNG } from "../../../../../src/engine/graphics/texture/sampler/downloadSamplerAsPNG.js";
import { Sampler2D } from "../../../../../src/engine/graphics/texture/sampler/Sampler2D.js";
import sampler2D2Canvas from "../../../../../src/engine/graphics/texture/sampler/sampler2d_to_html_canvas.js";
import { MouseEvents } from "../../../../../src/engine/input/devices/events/MouseEvents.js";
import { CanvasView } from "../../../../../src/view/elements/CanvasView.js";
import EmptyView from "../../../../../src/view/elements/EmptyView.js";
import { TypeEditor } from "../../TypeEditor.js";

const UPDATE_DELAY = 200;

export class TextureEditor extends TypeEditor {
    inline = true;

    build(parent, field, registry) {
        const size = 32;

        let texture = field.adapter.read(parent, field.name);
        let sampler;
        if (texture) {

            sampler = convertTexture2Sampler2D(texture, size, size)

        } else {
            sampler = Sampler2D.uint8(4, size, size);
            sampler.channelFill(3, 255);
        }

        const vContainer = new EmptyView({
            css: {
                width: "min-content",
                height: "min-content"
            }
        });

        const canvasView = new CanvasView();
        canvasView.css({
            position: "relative",
            background: 'black'
        });
        vContainer.addChild(canvasView);

        canvasView.size.set(sampler.width, sampler.height);


        let last_version = -1;
        let last_update_time = 0;
        let last_update_duration = 0;

        function draw() {
            const draw_start_time = performance.now();

            sampler = convertTexture2Sampler2D(texture, size, size);
            sampler2D2Canvas(sampler, 1, 0, canvasView.el);

            last_version = texture.version;

            const draw_end_time = performance.now();
            last_update_duration = draw_end_time - draw_start_time;

            last_update_time = draw_end_time;
        }


        function try_update() {
            const time_now = performance.now();

            if ((time_now - last_update_time) < UPDATE_DELAY) {
                return;
            }

            texture = field.adapter.read(parent, field.name);

            if (texture === undefined || texture === null) {
                sampler.fill(0);
                return;
            }

            if (texture.version !== last_version) {
                draw();
            }
        }

        const frameRunner = new FrameRunner(try_update);

        canvasView.on.linked.add(frameRunner.startup, frameRunner);
        canvasView.on.unlinked.add(frameRunner.shutdown, frameRunner);


        const allow_download = true;
        if (allow_download) {
            vContainer.el.addEventListener(MouseEvents.Click, () => {
                const texture = field.adapter.read(parent, field.name);
                if (texture === undefined || texture == null) {
                    return;
                }

                const sampler = convertTexture2Sampler2D(texture);

                downloadSampler2DAsPNG(sampler, field.name);
            });
            // add download marker
            vContainer.addClass('downloadable');
        }


        return vContainer;
    }
}
