import { Fun, Singleton } from '@ephox/katamari';
import * as AlloyEvents from '../../api/events/AlloyEvents';
import * as NativeEvents from '../../api/events/NativeEvents';
import * as Fields from '../../data/Fields';
import * as BlockerUtils from '../common/BlockerUtils';
import * as DraggingSchema from '../common/DraggingSchema';
import * as DragUtils from '../common/DragUtils';
import * as TouchBlockerEvents from './TouchBlockerEvents';
import * as TouchData from './TouchData';
const events = (dragConfig, dragState, updateStartState) => {
    const blockerSingleton = Singleton.value();
    const stopBlocking = (component) => {
        DragUtils.stop(component, blockerSingleton.get(), dragConfig, dragState);
        blockerSingleton.clear();
    };
    // Android fires events on the component at all times, while iOS initially fires on the component
    // but once moved off the component then fires on the element behind. As such we need to use
    // a blocker and then listen to both touchmove/touchend on both the component and blocker.
    return [
        AlloyEvents.run(NativeEvents.touchstart(), (component, simulatedEvent) => {
            simulatedEvent.stop();
            const stop = () => stopBlocking(component);
            const dragApi = {
                drop: stop,
                // delayDrop is not used by touch
                delayDrop: Fun.noop,
                forceDrop: stop,
                move: (event) => {
                    DragUtils.move(component, dragConfig, dragState, TouchData, event);
                }
            };
            const blocker = BlockerUtils.createComponent(component, dragConfig.blockerClass, TouchBlockerEvents.init(dragApi));
            blockerSingleton.set(blocker);
            const start = () => {
                updateStartState(component);
                BlockerUtils.instigate(component, blocker);
            };
            start();
        }),
        AlloyEvents.run(NativeEvents.touchmove(), (component, simulatedEvent) => {
            simulatedEvent.stop();
            DragUtils.move(component, dragConfig, dragState, TouchData, simulatedEvent.event);
        }),
        AlloyEvents.run(NativeEvents.touchend(), (component, simulatedEvent) => {
            simulatedEvent.stop();
            stopBlocking(component);
        }),
        AlloyEvents.run(NativeEvents.touchcancel(), stopBlocking)
    ];
};
const schema = [
    ...DraggingSchema.schema,
    Fields.output('dragger', {
        handlers: DragUtils.handlers(events)
    })
];
export { events, schema };
//# sourceMappingURL=TouchDragging.js.map