import { WebGLRenderTarget } from "three";
import Vector2 from "../../../../core/geom/Vector2.js";

export class FrameBuffer {
    /**
     * is expected to be bound during initialization
     * @type {WebGLRenderTarget}
     */
    renderTarget = null;

    /**
     * Number of users of the frame buffer
     * @type {number}
     */
    referenceCount = 0;

    /**
     * Dependency frame buffers
     * @type {string[]}
     */
    dependencies = [];

    /**
     * Size of the frame buffer in pixels
     * @type {Vector2}
     */
    size = new Vector2(0, 0);

    /**
     *
     * @param {string} id
     * @constructor
     */
    constructor(id) {
        /**
         *
         * @type {string}
         */
        this.id = id;


    }

    /**
     *
     * @returns {WebGLRenderTarget|WebGLMultisampleRenderTarget}
     */
    getRenderTarget() {
        return this.renderTarget;
    }

    /**
     * Gets called once before frame buffer is used for the first time
     * @param {WebGLRenderer} renderer
     */
    initialize(renderer) {
        //override this method as needed
    }

    /**
     * Gets called after frame buffer is no longer needed. Frame buffer becomes unusable afterwards
     * @param {WebGLRenderer} renderer
     */
    finalize(renderer) {
        //override this method as needed
    }

    /**
     * This method is used to populate FrameBuffer with data. Typically this is done every frame.
     * @param {WebGLRenderer} renderer
     * @param {Camera} camera
     * @param {Scene} scene
     * @param {FrameBuffer[]} dependencies
     */
    render(renderer, camera, scene, dependencies) {
        const _renderTarget = renderer.getRenderTarget();

        renderer.setRenderTarget(this.renderTarget);
        renderer.clear();

        renderer.render(scene, camera);

        // restore state
        renderer.setRenderTarget(_renderTarget);
    }

    /**
     *
     * @param {number} x width
     * @param {number} y height
     */
    setSize(x, y) {
        const size = this.size;

        // clamp to 1: a 0-sized attachment trips GL_INVALID_FRAMEBUFFER_OPERATION on clear/draw
        const w = Math.max(1, x);
        const h = Math.max(1, y);

        if (w === size.x && h === size.y) {
            // nothing changed
            return;
        }

        this.renderTarget.setSize(w, h);
        size.set(w, h);
    }
}

