import { Constants, ISize, RenderTargetTexture, Scalar, Scene, Texture } from './babylonjs-import';

export interface GpuPickingTarget {
    texture: RenderTargetTexture;
    width: number;
    height: number;
    rgbaPixels: Uint8Array;
    uint32Pixels: Uint32Array;
}

export class GpuPickingTargetCache {
    private _cache = new Map<string, GpuPickingTarget>();

    public constructor(private readonly _scene: Scene) {}

    public get(key: string, size: ISize): Readonly<GpuPickingTarget> {
        let target = this._cache.get(key);
        size = {
            width: Math.ceil(size.width),
            height: Math.ceil(size.height)
        };

        const isTargetCached =
            target &&
            Scalar.WithinEpsilon(target.width, size.width) &&
            Scalar.WithinEpsilon(target.height, size.height);
        if (isTargetCached) {
            return target!;
        }

        target?.texture?.dispose();
        const textureBuffer = new ArrayBuffer(size.width * size.height * 4);

        target = {
            texture: new RenderTargetTexture(
                `${key}_gpuPickingTarget`,
                size,
                this._scene,
                false,
                true,
                Constants.TEXTURETYPE_UNSIGNED_INT,
                false,
                Texture.NEAREST_NEAREST
            ),
            width: size.width,
            height: size.height,
            rgbaPixels: new Uint8Array(textureBuffer),
            uint32Pixels: new Uint32Array(textureBuffer)
        };

        target.texture.anisotropicFilteringLevel = 1;
        this._cache.set(key, target);
        return target;
    }

    public clear(): void {
        for (const t of this._cache.values()) {
            t.texture.dispose();
        }
        this._cache.clear();
    }
}
