import { defaults } from '../util/util';
import { PanRecognizer } from './recognizers';
import { pointerCoord } from '../util/dom';
import { UIEventManager } from './ui-event-manager';
export var PanGesture = (function () {
    /**
     * @param {?} plt
     * @param {?} element
     * @param {?=} opts
     */
    function PanGesture(plt, element, opts) {
        if (opts === void 0) { opts = {}; }
        this.plt = plt;
        this.element = element;
        defaults(opts, {
            threshold: 20,
            maxAngle: 40,
            direction: 'x',
            zone: true,
            capture: false,
            passive: false,
        });
        this.events = new UIEventManager(plt);
        if (opts.domController) {
            this.debouncer = opts.domController.debouncer();
        }
        this.gestute = opts.gesture;
        this.direction = opts.direction;
        this.eventsConfig = {
            element: this.element,
            pointerDown: this.pointerDown.bind(this),
            pointerMove: this.pointerMove.bind(this),
            pointerUp: this.pointerUp.bind(this),
            zone: opts.zone,
            capture: opts.capture,
            passive: opts.passive
        };
        if (opts.threshold > 0) {
            this.detector = new PanRecognizer(opts.direction, opts.threshold, opts.maxAngle);
        }
    }
    /**
     * @return {?}
     */
    PanGesture.prototype.listen = function () {
        if (!this.isListening) {
            this.pointerEvents = this.events.pointerEvents(this.eventsConfig);
            this.isListening = true;
        }
    };
    /**
     * @return {?}
     */
    PanGesture.prototype.unlisten = function () {
        if (this.isListening) {
            this.gestute && this.gestute.release();
            this.events.destroy();
            this.isListening = false;
        }
    };
    /**
     * @return {?}
     */
    PanGesture.prototype.destroy = function () {
        this.gestute && this.gestute.destroy();
        this.gestute = null;
        this.unlisten();
        this.element = null;
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.pointerDown = function (ev) {
        if (this.started) {
            return;
        }
        if (!this.canStart(ev)) {
            return false;
        }
        if (this.gestute) {
            // Release fallback
            this.gestute.release();
            // Start gesture
            if (!this.gestute.start()) {
                return false;
            }
        }
        this.started = true;
        this.captured = false;
        var /** @type {?} */ coord = pointerCoord(ev);
        if (this.detector) {
            this.detector.start(coord);
        }
        else {
            if (!this.tryToCapture(ev)) {
                this.started = false;
                this.captured = false;
                this.gestute.release();
                return false;
            }
        }
        return true;
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.pointerMove = function (ev) {
        var _this = this;
        (void 0) /* assert */;
        if (this.captured) {
            this.debouncer.write(function () {
                _this.onDragMove(ev);
            });
            return;
        }
        (void 0) /* assert */;
        var /** @type {?} */ coord = pointerCoord(ev);
        if (this.detector.detect(coord)) {
            if (this.detector.pan() !== 0) {
                if (!this.tryToCapture(ev)) {
                    this.abort(ev);
                }
            }
        }
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.pointerUp = function (ev) {
        (void 0) /* assert */;
        this.debouncer.cancel();
        this.gestute && this.gestute.release();
        if (this.captured) {
            this.onDragEnd(ev);
        }
        else {
            this.notCaptured(ev);
        }
        this.captured = false;
        this.started = false;
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.tryToCapture = function (ev) {
        (void 0) /* assert */;
        (void 0) /* assert */;
        if (this.gestute && !this.gestute.capture()) {
            return false;
        }
        this.onDragStart(ev);
        this.captured = true;
        return true;
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.abort = function (ev) {
        this.started = false;
        this.captured = false;
        this.gestute.release();
        this.pointerEvents.stop();
        this.notCaptured(ev);
    };
    /**
     * @return {?}
     */
    PanGesture.prototype.getNativeElement = function () {
        return this.element;
    };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.canStart = function (ev) { return true; };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.onDragStart = function (ev) { };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.onDragMove = function (ev) { };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.onDragEnd = function (ev) { };
    /**
     * @param {?} ev
     * @return {?}
     */
    PanGesture.prototype.notCaptured = function (ev) { };
    return PanGesture;
}());
function PanGesture_tsickle_Closure_declarations() {
    /** @type {?} */
    PanGesture.prototype.debouncer;
    /** @type {?} */
    PanGesture.prototype.events;
    /** @type {?} */
    PanGesture.prototype.pointerEvents;
    /** @type {?} */
    PanGesture.prototype.detector;
    /** @type {?} */
    PanGesture.prototype.started;
    /** @type {?} */
    PanGesture.prototype.captured;
    /** @type {?} */
    PanGesture.prototype.isListening;
    /** @type {?} */
    PanGesture.prototype.gestute;
    /** @type {?} */
    PanGesture.prototype.direction;
    /** @type {?} */
    PanGesture.prototype.eventsConfig;
    /** @type {?} */
    PanGesture.prototype.plt;
    /** @type {?} */
    PanGesture.prototype.element;
}
//# sourceMappingURL=drag-gesture.js.map