mergeInto(LibraryManager.library, {
    SetWebGLCameraSettings: function (settings) {
        return;
        window.webGLCamera.setWebGLCameraSettings(UTF8ToString(settings));
    },
    WebGLStartCamera: function () {
        return;
        window.StartWebcam();
    },
    WebGLStopCamera: function () {
        return;
        window.StopWebcam();
    },
    WebGLIsCameraStarted: function () {
        return true;
        if (!window.webGLCamera) {
            console.error('%cwebGLCamera not found! Please make sure to use the correct WebGLTemplate in your ProjectSettings', 'font-size: 32px; font-weight: bold');
            throw new Error("webGLCamera not found! Please make sure to use the correct WebGLTemplate in your ProjectSettings");
            return;
        }
        return webGLCamera.isCameraStarted;
    },
    WebGLGetCameraFov: function () {
        return window.webGLCamera.FOV;
    },
    WebGLUnpauseCamera: function () {
        return;
        window.webGLCamera.unpauseCamera();
    },
    WebGLPauseCamera: function () {
        return;
        window.webGLCamera.pauseCamera();
    },
    WebGLFlipCamera: function () {
        return;
        window.FlipCam();
    },
    WebGLIsCameraFlipped: function () {
        return false;
        return window.webGLCamera.videoCanvas.style.transform == "scaleX(-1)";
    },
    WebGLGetVideoDims: function () {
        if (typeof (window.unityWebXRTextureProperty) == "undefined" || window.unityWebXRTextureProperty == null)
            var data = "0,0";
        else
            var data = window.unityWebXRTextureProperty.width + "," + window.unityWebXRTextureProperty.height;

        var bufferSize = lengthBytesUTF8(data) + 1;
        var buffer = _malloc(bufferSize);
        stringToUTF8(data, buffer, bufferSize);
        return buffer;
    },
    WebGLSubscribeVideoTexturePtr: function (textureId) {
        //        window.updateUnityVideoTextureCallback = ()=>{
        //            return;
        //            var videoCanvas = window.webGLCamera.VIDEO//videoCapture;
        //            textureObj = GL.textures[textureId];

        //            if (videoCanvas == null || textureObj == null) return;      

        //            GLctx.bindTexture(GLctx.TEXTURE_2D, textureObj);
        //            GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_WRAP_S, GLctx.CLAMP_TO_EDGE);
        //            GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_WRAP_T, GLctx.CLAMP_TO_EDGE);
        //            GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_MIN_FILTER, GLctx.LINEAR);
        //            GLctx.pixelStorei(GLctx.UNPACK_FLIP_Y_WEBGL, true); 
        //            GLctx.texSubImage2D(GLctx.TEXTURE_2D, 0, 0, 0, GLctx.RGBA, GLctx.UNSIGNED_BYTE, videoCanvas);
        //            GLctx.pixelStorei(GLctx.UNPACK_FLIP_Y_WEBGL, false);

        //            //console.log("updateUnityVideoTextureCallback - webcam texture updated " + textureId);
        //        };
        window.updateUnityVideoTextureFromWebGLTextureCallback = (sourceTexture, width, height) => {
            //console.log(`Texture size: ${width}x${height}`);

            const ratio = 540 / 960;
            const cropWidth = Math.round(height * ratio) < width ? Math.round(height * ratio) : width;
            const cropHeight = Math.round(width / ratio) < height ? Math.round(width / ratio) : height;

            //console.log(`Texture size crop: ${cropWidth}x${cropHeight}`);

            unityTexture = GL.textures[textureId];

            if (typeof (window.intermediateTex) == "undefined" || window.intermediateTex == null) {
                window.intermediateTex = GLctx.createTexture();
                GLctx.bindTexture(GLctx.TEXTURE_2D, window.intermediateTex);
                GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, cropWidth, cropHeight, 0, GLctx.RGBA, GLctx.UNSIGNED_BYTE, null);
                GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_MIN_FILTER, GLctx.LINEAR);
                GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_MAG_FILTER, GLctx.LINEAR);
                GLctx.bindTexture(GLctx.TEXTURE_2D, null);
            }

            if (sourceTexture == null) return;
            if (unityTexture == null) {
                window.unityInstance.SendMessage("Main Camera", "SetVideoDims");
            }

            // Crop texture

            if (typeof (window.srcFBO) == "undefined" || window.srcFBO == null) {
                window.srcFBO = GLctx.createFramebuffer();
                window.intermediateFOB = GLctx.createFramebuffer();
                window.dstFBO = GLctx.createFramebuffer();
            }

            GLctx.bindFramebuffer(GLctx.READ_FRAMEBUFFER, window.srcFBO);
            GLctx.framebufferTexture2D(GLctx.READ_FRAMEBUFFER, GLctx.COLOR_ATTACHMENT0, GLctx.TEXTURE_2D, sourceTexture, 0);

            GLctx.bindFramebuffer(GLctx.DRAW_FRAMEBUFFER, window.intermediateFOB);
            GLctx.framebufferTexture2D(GLctx.DRAW_FRAMEBUFFER, GLctx.COLOR_ATTACHMENT0, GLctx.TEXTURE_2D, window.intermediateTex, 0);

            const cropX = Math.round((width - cropWidth) / 2);
            const cropY = Math.round((height - cropHeight) / 2);

            //console.log(`Texture size crop center: ${cropX}x${cropY}`);

            // Blit (copy) framebuffer contents
            GLctx.blitFramebuffer(
                cropX, cropY, cropX + cropWidth, cropY + cropHeight, // Source rect
                0, 0, cropWidth, cropHeight, // Destination rect
                GLctx.COLOR_BUFFER_BIT,  // What to copy
                GLctx.LINEAR            // Filter (NEAREST for pixel-perfect copy)
            );
            // End Crop texture

            // Attach textures to framebuffers
            GLctx.bindFramebuffer(GLctx.READ_FRAMEBUFFER, window.intermediateFOB);
            GLctx.framebufferTexture2D(GLctx.READ_FRAMEBUFFER, GLctx.COLOR_ATTACHMENT0, GLctx.TEXTURE_2D, window.intermediateTex, 0);

            GLctx.bindFramebuffer(GLctx.DRAW_FRAMEBUFFER, window.dstFBO);
            GLctx.framebufferTexture2D(GLctx.DRAW_FRAMEBUFFER, GLctx.COLOR_ATTACHMENT0, GLctx.TEXTURE_2D, unityTexture, 0);

            // Blit (copy) framebuffer contents
            GLctx.blitFramebuffer(
                0, 0, cropWidth, cropHeight, // Source rect
                0, 0, 540, 960, // Destination rect
                //0, 0, 640, 480, // Destination rect
                GLctx.COLOR_BUFFER_BIT,  // What to copy
                GLctx.LINEAR            // Filter (NEAREST for pixel-perfect copy)
            );
            // console.log("After blit, WebGL error:", GLctx.getError());
            // Cleanup
            GLctx.bindFramebuffer(GLctx.FRAMEBUFFER, null);
        };
    },
    WebGLGetCameraTexture: function (textureId) {
        return;
        var videoCanvas = window.webGLCamera.VIDEO;
        textureObj = GL.textures[textureId];

        if (canvas == null || textureObj == null) return;

        GLctx.bindTexture(GLctx.TEXTURE_2D, textureObj);
        GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_WRAP_S, GLctx.CLAMP_TO_EDGE);
        GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_WRAP_T, GLctx.CLAMP_TO_EDGE);
        GLctx.texParameteri(GLctx.TEXTURE_2D, GLctx.TEXTURE_MIN_FILTER, GLctx.LINEAR);
        GLctx.pixelStorei(GLctx.UNPACK_FLIP_Y_WEBGL, true);
        GLctx.texSubImage2D(GLctx.TEXTURE_2D, 0, 0, 0, GLctx.RGBA, GLctx.UNSIGNED_BYTE, videoCanvas);
        GLctx.pixelStorei(GLctx.UNPACK_FLIP_Y_WEBGL, false);

        console.log("WebGLGetCameraTexture " + textureId, videoCanvas);

    },

    IsWebcamPermissionGranted: function () {
        return true;
        return (window.webcamStream != null);
    },
}); 