import { CanvasConfig } from './CanvasConfig.js';
export class RevealBoundaryStore {
    constructor(id) {
        // The current cursor position relative to window.
        this.clientX = -1000;
        this.clientY = -1000;
        // The cursor position of painted reveal effect.
        this.paintedClientX = -1000;
        this.paintedClientY = -1000;
        this.mouseInBoundary = false;
        this.canvasList = [];
        this.animationQueue = new Set();
        this.animationFrame = null;
        this.dirty = false;
        this.mouseUpClientX = null;
        this.mouseUpClientY = null;
        this.mouseDownAnimateStartFrame = null;
        this.mouseDownAnimateCurrentFrame = null;
        this.mouseDownAnimateReleasedFrame = null;
        this.mouseDownAnimateLogicFrame = null;
        this.mousePressed = false;
        this.mouseReleased = false;
        this.addReveal = ($el) => {
            const canvasConfig = new CanvasConfig(this, $el);
            canvasConfig.cacheCanvasPaintingStyle();
            canvasConfig.cacheRevealBitmaps();
            this.canvasList.push(canvasConfig);
        };
        this.removeReveal = ($el) => {
            this.canvasList = this.canvasList.filter((config) => {
                return config && config.canvas === $el;
            });
        };
        this.onPointerEnterBoundary = () => {
            this.mouseInBoundary = true;
            if (!this.animationFrame) {
                this.animationFrame = window.requestAnimationFrame(this.paintAll);
            }
        };
        this.onPointerLeaveBoundary = () => {
            this.mouseInBoundary = false;
            this.paintAll(0, true);
        };
        this.paintAll = (frame, force) => {
            if (!force && !this.mouseInBoundary && this.animationQueue.size === 0) {
                return;
            }
            this.animationQueue.forEach(config => {
                if (!frame || config.currentFrameId === frame) {
                    return;
                }
                config.currentFrameId = frame;
                if (config.mouseDownAnimateStartFrame === null) {
                    config.mouseDownAnimateStartFrame = frame;
                }
                const relativeFrame = frame - config.mouseDownAnimateStartFrame;
                config.mouseDownAnimateCurrentFrame = relativeFrame;
                const speed = config.cachedStyle.revealAnimateSpeed;
                const accelerateRate = config.cachedStyle.revealReleasedAccelerateRate;
                let unitLogicFrame = relativeFrame;
                if (config.mouseReleased && config.mouseDownAnimateReleasedFrame) {
                    unitLogicFrame += (relativeFrame - config.mouseDownAnimateReleasedFrame) * accelerateRate;
                }
                config.mouseDownAnimateLogicFrame = unitLogicFrame / speed;
                if (config.mouseDownAnimateLogicFrame > 1) {
                    this.cleanUpAnimation(config);
                }
            });
            this.canvasList.forEach((config) => {
                config.currentFrameId = frame;
                config.paint(force);
            });
            this.dirty = true;
            this.paintedClientX = this.clientX;
            this.paintedClientY = this.clientY;
            if (this.mouseInBoundary || this.animationQueue.size !== 0) {
                this.animationFrame = window.requestAnimationFrame(this.paintAll);
            }
            else {
                this.animationFrame = null;
            }
        };
        this.resetAll = () => {
            this.canvasList.forEach(config => {
                config.paint();
            });
        };
        this.initializeAnimation = () => {
            const config = this.canvasList.find(x => x.mouseInCanvas());
            if (!config)
                return;
            this.animationQueue.add(config);
            config.mouseDownAnimateStartFrame = null;
            config.mousePressed = true;
            config.mouseReleased = false;
        };
        this.switchAnimation = () => {
            this.animationQueue.forEach(config => {
                if (!config.mouseReleased) {
                    config.mouseReleased = true;
                    config.mouseDownAnimateReleasedFrame = config.mouseDownAnimateCurrentFrame;
                    config.mouseUpClientX = this.clientX;
                    config.mouseUpClientY = this.clientY;
                }
            });
        };
        this.cleanUpAnimation = (config) => {
            config.mouseUpClientX = null;
            config.mouseUpClientY = null;
            config.mouseDownAnimateStartFrame = null;
            config.mouseDownAnimateCurrentFrame = null;
            config.mouseDownAnimateReleasedFrame = null;
            config.mouseDownAnimateLogicFrame = null;
            config.mousePressed = false;
            config.mouseReleased = false;
            this.animationQueue.delete(config);
            config.paint(true);
        };
        this.getRevealAnimationConfig = () => {
            return this.canvasList.find(x => x.mouseInCanvas()) || null;
        };
        this.id = id;
    }
}
//# sourceMappingURL=RevealBoundryStore.js.map