/** @internal NOTE: Internal APIs. Subject to change. Use of these APIs in production applications is not supported. */ /** */
import { LazyResizableRawTexture } from '../LazyResizableRawTexture';
import { ProductMeshesGroupRenderInfo } from '../ProductMeshesGroupRenderInfo';
import { AbstractMesh, Mesh, Scene } from '../babylonjs-import';
import { UniformsAndDefinesAndSamplers } from './CullingMaterial';
import { BABYLON_MESH_ALPHA, CustomDepthMaterial, IS_BABYLON_MESH } from './CustomDepthMaterial';

export class BabylonMeshDepthMaterial extends CustomDepthMaterial {
    constructor(
        name: string,
        scene: Scene,
        renderingInfo: ProductMeshesGroupRenderInfo,
        diffuseTexture: LazyResizableRawTexture
    ) {
        super(name, scene, renderingInfo, diffuseTexture);
    }

    readonly _type = 'BabylonMeshDepthMaterial';

    override getUniformsAndDefinesAndSamplers(): UniformsAndDefinesAndSamplers {
        const uniformsAndDefines = super.getUniformsAndDefinesAndSamplers();

        uniformsAndDefines.uniforms.push(BABYLON_MESH_ALPHA);
        uniformsAndDefines.defines.push(IS_BABYLON_MESH);

        return uniformsAndDefines;
    }

    override bindFunction(mesh: AbstractMesh): void {
        super.bindFunction(mesh);
        const effect = this.getEffect();

        //check if mesh is a twinfinity or babylon mesh
        if (mesh instanceof Mesh) {
            const isTwinfintySubMesh = !!mesh.twinfinity?.ifc;
            if (!isTwinfintySubMesh) {
                effect.setFloat('babylonMeshAlpha', mesh.material?.alpha ?? 1.0);
            } else {
                throw new Error(
                    'The mesh bound to this material is an IFC mesh, IFC meshes should not be assigned the Babylon mesh depth material (this material)'
                );
            }
        }
    }
}
