import { RevealBoundaryStore } from './RevealBoundryStore.js';
import { config } from './config.js';
export class RevealStateManager {
    constructor() {
        this._currentHashId = 0;
        this._storage = [];
        this.requestedTraverseBoundaries = false;
        this.cachedMouseX = -1;
        this.cachedMouseY = -1;
        this.pointerLeaveScheduled = false;
        this.handlePointerLeave = () => {
            if (this.pointerLeaveScheduled)
                return;
            window.requestAnimationFrame(() => {
                for (let i = 0; i < this._storage.length; i++) {
                    this._storage[i].onPointerLeaveBoundary();
                }
                this.pointerLeaveScheduled = false;
            });
        };
        this.handlePointerMove = (event) => {
            this.cachedMouseX = event.clientX;
            this.cachedMouseY = event.clientY;
            if (!this.requestedTraverseBoundaries) {
                window.requestAnimationFrame(this.traverseBoundaries);
                this.requestedTraverseBoundaries = true;
            }
        };
        this.traverseBoundaries = () => {
            this.requestedTraverseBoundaries = false;
            for (let i = 0; i < this._storage.length; i++) {
                this._storage[i].onPointerMoveOnScreen(this.cachedMouseX, this.cachedMouseY);
            }
        };
        this.newBoundary = ($el) => {
            const hashId = this._currentHashId++;
            const store = new RevealBoundaryStore(hashId, $el);
            this._storage.push(store);
            return store;
        };
        this.removeBoundary = (store) => {
            this._storage = this._storage.filter((x) => x !== store);
        };
        if (config.borderDetectionMode === 'experimentalAutoFit') {
            if (typeof Window === 'undefined')
                return;
            window.addEventListener('pointermove', this.handlePointerMove);
            // This is for touch screen
            // Window.pointerleave won't be triggered if the finger
            // leave the screen, so we use pointer up here.
            window.addEventListener('pointerup', (ev) => {
                if (ev.type !== 'mouse')
                    this.handlePointerLeave();
            });
            // This is for desktop
            // If the mouse leave the window, we need to terminate
            // all animations and clean up the canvas.
            window.addEventListener('pointerleave', (ev) => {
                if (ev.type === 'mouse')
                    this.handlePointerLeave();
            });
        }
    }
}
//# sourceMappingURL=RevealStateManager.js.map