/**
 * A base class for all gesture recognizers.
 *
 * The following gestures are enabled by default in both Ext JS and Sencha Touch:
 *
 * * {@link Ext.event.gesture.Tap}
 * * {@link Ext.event.gesture.DoubleTap}
 * * {@link Ext.event.gesture.LongPress}
 * * {@link Ext.event.gesture.Drag}
 * * {@link Ext.event.gesture.Swipe}
 * * {@link Ext.event.gesture.Pinch}
 * * {@link Ext.event.gesture.Rotate}
 * * {@link Ext.event.gesture.EdgeSwipe}
 *
 * @abstract
 * @private
 */
Ext.define('Ext.event.gesture.Recognizer', {
    requires: ['Ext.event.publisher.Gesture'],
    mixins: ['Ext.mixin.Identifiable'],
 
    /**
     * @property {Number}
     * The priority of the recognizer. Determines the order in which it recognizes gestures
     * relative to other recognizers.  The default recognizers use the following priorities:
     *
     * - Ext.event.gesture.Drag: 100
     * - Ext.event.gesture.Tap: 200
     * - Ext.event.gesture.DoubleTap: 300
     * - Ext.event.gesture.LongPress: 400
     * - Ext.event.gesture.EdgeSwipe: 500
     * - Ext.event.gesture.Swipe: 600
     * - Ext.event.gesture.Pinch: 700
     * - Ext.event.gesture.Rotate: 800
     */
    priority: 0,
 
    handledEvents: [],
 
    isStarted: false,
 
    config: {
        onRecognized: Ext.emptyFn,
        callbackScope: null
    },
 
    constructor: function(config) {
        this.initConfig(config);
        Ext.event.publisher.Gesture.instance.registerRecognizer(this);
    },
 
    onStart: Ext.emptyFn,
 
    onEnd: Ext.emptyFn,
 
    onTouchStart: Ext.emptyFn,
 
    onTouchMove: Ext.emptyFn,
 
    onTouchEnd: function() {
        return this.reset();
    },
 
    onTouchCancel: function(e) {
        return this.cancel(e);
    },
 
    fire: function(eventName, e, info, isCancel) {
        this.getOnRecognized().call(this.getCallbackScope(), this, eventName, e, info, isCancel);
    },
 
    cancel: function(e) {
        if (this.isStarted) {
            // If the recognizer is started, that is to say, it has already begun publishing
            // events for the current gesture, then we need to make sure it fires a "cancel"
            // event (implementation determined by subclasses).
            this.onCancel(e);
        }
 
        return this.reset();
    },
 
    onCancel: Ext.emptyFn,
 
    reset: function() {
        this.isStarted = false;
        return false;
    }
});