import '../../../assert/js/assert.js';
import '../../../tandem/js/PhetioIDUtils.js';
import '../../../globals.js';
// Copyright 2022-2024, University of Colorado Boulder
/**
 * Pooled structure to record batched events efficiently. How it calls the callback is based on the type
 * (pointer/mspointer/touch/mouse). There is one BatchedDOMEvent for each DOM Event (not for each touch).
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import Enumeration from '../../../phet-core/js/Enumeration.js';
import EnumerationValue from '../../../phet-core/js/EnumerationValue.js';
import Pool from '../../../phet-core/js/Pool.js';
import { Input, scenery } from '../imports.js';
export class BatchedDOMEventType extends EnumerationValue {
}
BatchedDOMEventType.POINTER_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.MS_POINTER_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.TOUCH_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.MOUSE_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.WHEEL_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.ALT_TYPE = new BatchedDOMEventType();
BatchedDOMEventType.enumeration = new Enumeration(BatchedDOMEventType, {
    phetioDocumentation: 'The type of batched event'
});
class BatchedDOMEvent {
    constructor(eventContext, type, callback) {
        this.initialize(eventContext, type, callback);
    }
    initialize(eventContext, type, callback) {
        // called multiple times due to pooling, this should be re-entrant
        assert && assert(eventContext.domEvent, 'for some reason, there is no DOM event?');
        this.eventContext = eventContext;
        this.type = type;
        this.callback = callback;
        return this;
    }
    run(input) {
        sceneryLog && sceneryLog.InputEvent && sceneryLog.InputEvent('Running batched event');
        sceneryLog && sceneryLog.InputEvent && sceneryLog.push();
        const callback = this.callback;
        // process whether anything under the pointers changed before running additional input events
        input.validatePointers();
        //OHTWO TODO: switch? https://github.com/phetsims/scenery/issues/1581
        if (this.type === BatchedDOMEventType.POINTER_TYPE) {
            const context = this.eventContext;
            const pointerEvent = context.domEvent;
            callback.call(input, pointerEvent.pointerId, pointerEvent.pointerType, input.pointFromEvent(pointerEvent), context);
        }
        else if (this.type === BatchedDOMEventType.MS_POINTER_TYPE) {
            const context = this.eventContext;
            const pointerEvent = context.domEvent;
            callback.call(input, pointerEvent.pointerId, Input.msPointerType(pointerEvent), input.pointFromEvent(pointerEvent), context);
        }
        else if (this.type === BatchedDOMEventType.TOUCH_TYPE) {
            const context = this.eventContext;
            const touchEvent = context.domEvent;
            for (let i = 0; i < touchEvent.changedTouches.length; i++) {
                // according to spec (http://www.w3.org/TR/touch-events/), this is not an Array, but a TouchList
                const touch = touchEvent.changedTouches.item(i);
                callback.call(input, touch.identifier, input.pointFromEvent(touch), context);
            }
        }
        else if (this.type === BatchedDOMEventType.MOUSE_TYPE) {
            const context = this.eventContext;
            const point = input.pointFromEvent(context.domEvent);
            if (callback === input.mouseDown) {
                callback.call(input, null, point, context);
            }
            else {
                callback.call(input, point, context);
            }
        }
        else if (this.type === BatchedDOMEventType.WHEEL_TYPE || this.type === BatchedDOMEventType.ALT_TYPE) {
            callback.call(input, this.eventContext);
        }
        else {
            throw new Error(`bad type value: ${this.type}`);
        }
        sceneryLog && sceneryLog.InputEvent && sceneryLog.pop();
    }
    /**
     * Releases references
     */
    dispose() {
        // clear our references
        this.eventContext = null;
        this.callback = null;
        this.freeToPool();
    }
    freeToPool() {
        BatchedDOMEvent.pool.freeToPool(this);
    }
}
BatchedDOMEvent.pool = new Pool(BatchedDOMEvent);
export default BatchedDOMEvent;
scenery.register('BatchedDOMEvent', BatchedDOMEvent);
//# sourceMappingURL=BatchedDOMEvent.js.map