"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useImageFx = void 0;
const react_1 = require("react");
const effects_1 = require("@cntrl-site/effects");
const rangeMap_1 = require("../rangeMap");
const PATTERN_URL = 'https://cdn.cntrl.site/client-app-files/texture2.png';
const PATTERN_2_URL = 'https://cdn.cntrl.site/client-app-files/bayer16.png';
function useImageFx(canvas, enabled, { imageUrl, fragmentShader, cursor, controls }, width, height) {
    const [isFXAllowed, setIsFXAllowed] = (0, react_1.useState)(true);
    const mousePos = (0, react_1.useRef)([0.0, 0.0]);
    const imageFx = (0, react_1.useMemo)(() => {
        if (!imageUrl || !cursor || !enabled)
            return undefined;
        const { type, x, y } = cursor;
        return new effects_1.ImageEffect(imageUrl, PATTERN_URL, PATTERN_2_URL, fragmentShader, Object.assign({ time: 0, cursor: type === 'mouse' ? mousePos.current : [x, y] }, controls), width, height);
    }, [imageUrl, fragmentShader, width, height, enabled]);
    (0, react_1.useEffect)(() => {
        if (!cursor || cursor.type !== 'mouse' || !canvas || !imageFx)
            return;
        const handleMouseMove = (evt) => {
            const rect = canvas.getBoundingClientRect();
            const x = (0, rangeMap_1.rangeMap)(evt.clientX, rect.left, rect.left + rect.width, 0, 1, true);
            const y = (0, rangeMap_1.rangeMap)(evt.clientY, rect.top, rect.top + rect.height, 0, 1, true);
            imageFx.setParam('cursor', [x, y]);
        };
        window.addEventListener('mousemove', handleMouseMove, { capture: true, passive: true });
        return () => {
            window.removeEventListener('mousemove', handleMouseMove);
        };
    }, [canvas, imageFx, cursor === null || cursor === void 0 ? void 0 : cursor.type]);
    (0, react_1.useEffect)(() => {
        const gl = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('webgl2');
        if (!enabled || !canvas || !gl || !imageFx)
            return;
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
        let running = false;
        let time = 0;
        let frame;
        const renderFrame = () => {
            time += 0.1;
            imageFx.setViewport(Math.floor(canvas.width), Math.floor(canvas.height));
            imageFx.setParam('time', time);
            try {
                imageFx.render(gl);
            }
            catch (e) {
                setIsFXAllowed(false);
            }
            frame = requestAnimationFrame(renderFrame);
        };
        const observer = new IntersectionObserver(([entry]) => {
            if (entry.isIntersecting && !running) {
                frame = requestAnimationFrame(renderFrame);
                running = true;
                return;
            }
            if (!entry.isIntersecting && running) {
                window.cancelAnimationFrame(frame);
                running = false;
            }
        });
        observer.observe(canvas);
        try {
            imageFx.prepare(gl);
        }
        catch (e) {
            setIsFXAllowed(false);
        }
        return () => {
            window.cancelAnimationFrame(frame);
            observer.disconnect();
        };
    }, [canvas, imageFx, enabled]);
    return isFXAllowed;
}
exports.useImageFx = useImageFx;
