import { Vector2 as ThreeVector2 } from "three";
import { EnginePlugin } from "../../../../plugin/EnginePlugin.js";
import { LightManager } from "../LightManager.js";
import { MaterialTransformer } from "./MaterialTransformer.js";


export class ForwardPlusRenderingPlugin extends EnginePlugin {
    constructor() {
        super();

        const lightManager = new LightManager();
        lightManager.setTileMapResolution(12, 6, 4);

        this.__light_manager = lightManager;

        this.__resolution = new ThreeVector2();

        //transformer
        this.__material_transformer = new MaterialTransformer({
            light_manager: this.__light_manager,
            resolution: this.__resolution
        });
    }

    /**
     * Set resolution of the cluster texture, higher resolution will result in less load on the GPU, but will take up more RAM to represent and more time to build the clusters each frame
     * @param {number} x
     * @param {number} y
     * @param {number} z
     */
    setClusterResolution(x, y, z) {
        this.__light_manager.setTileMapResolution(x, y, z);
    }

    /**
     *
     * @param {CameraView} view
     * @private
     */
    __prepare_for_render(view) {
        this.__material_transformer.updateCamera(view);

        this.__light_manager.buildTiles(view.camera);
    }

    updateResolution() {
        const graphics = this.engine.graphics;

        graphics.getResolution(this.__resolution);
    }

    async startup() {
        const graphics = this.engine.graphics;

        graphics.getMaterialManager().addCompileStep(this.__material_transformer);

        graphics.viewport.size.onChanged.add(this.updateResolution, this);
        graphics.pixelRatio.onChanged.add(this.updateResolution, this);


        graphics.main_view.on.preRender.add(this.__prepare_for_render, this);

        this.updateResolution();

        await super.startup();
    }

    async shutdown() {
        const graphics = this.engine.graphics;

        const is_material_removed = graphics.getMaterialManager().removeCompileStep(this.__material_transformer);

        if (!is_material_removed) {
            console.warn('Failed to remove material transformer');
        }

        graphics.viewport.size.onChanged.remove(this.updateResolution, this);
        graphics.pixelRatio.onChanged.remove(this.updateResolution, this);

        graphics.on.preRender.remove(this.__prepare_for_render, this);

        // release memory
        this.__light_manager.dispose();

        await super.shutdown();
    }

    getLightManager() {
        return this.__light_manager;
    }

}
