'use strict';

var addPointerEvent = require('../../events/add-pointer-event.js');
var getContextWindow = require('../../utils/get-context-window.js');
var PanSession = require('./PanSession.js');
var Feature = require('../../../../../../../motion-dom@12.38.0/node_modules/motion-dom/dist/es/render/Feature.js');
var noop = require('../../../../../../../motion-utils@12.36.0/node_modules/motion-utils/dist/es/noop.js');
var frame = require('../../../../../../../motion-dom@12.38.0/node_modules/motion-dom/dist/es/frameloop/frame.js');

const asyncHandler = (handler) => (event, info) => {
    if (handler) {
        frame.frame.update(() => handler(event, info), false, true);
    }
};
class PanGesture extends Feature.Feature {
    constructor() {
        super(...arguments);
        this.removePointerDownListener = noop.noop;
    }
    onPointerDown(pointerDownEvent) {
        this.session = new PanSession.PanSession(pointerDownEvent, this.createPanHandlers(), {
            transformPagePoint: this.node.getTransformPagePoint(),
            contextWindow: getContextWindow.getContextWindow(this.node),
        });
    }
    createPanHandlers() {
        const { onPanSessionStart, onPanStart, onPan, onPanEnd } = this.node.getProps();
        return {
            onSessionStart: asyncHandler(onPanSessionStart),
            onStart: asyncHandler(onPanStart),
            onMove: asyncHandler(onPan),
            onEnd: (event, info) => {
                delete this.session;
                if (onPanEnd) {
                    frame.frame.postRender(() => onPanEnd(event, info));
                }
            },
        };
    }
    mount() {
        this.removePointerDownListener = addPointerEvent.addPointerEvent(this.node.current, "pointerdown", (event) => this.onPointerDown(event));
    }
    update() {
        this.session && this.session.updateHandlers(this.createPanHandlers());
    }
    unmount() {
        this.removePointerDownListener();
        this.session && this.session.end();
    }
}

exports.PanGesture = PanGesture;
