/**
 * @class Ext.DataView
 */
Ext.DataView.override({
    scroll: 'vertical',

    /**
     * @cfg {String} pressedCls
     * A CSS class to apply to an item on the view while it is being pressed (defaults to 'x-item-pressed').
     */
    pressedCls : "x-item-pressed",

    /**
     * @cfg {Number} pressedDelay
     * The amount of delay between the tapstart and the moment we add the pressedCls.
     * Settings this to true defaults to 100ms
     */
    pressedDelay: 100,
    
    /**
     * @cfg {Boolean} allowDeselect Only respected if {@link #singleSelect} is true. If this is set to false,
     * a selected item will not be deselected when tapped on, ensuring that once an item has been selected at
     * least one item will always be selected. Defaults to allowed (true).
     */
    allowDeselect: true,

    /**
     * @cfg {String} triggerEvent
     * Defaults to 'singletap'. Other valid options are 'tap'
     */
    triggerEvent: 'singletap',
    
    triggerCtEvent: 'containertap',
    
    
    // @private
    addCmpEvents: function() {
        //<deprecated since=0.99>
        if (Ext.isDefined(this.forceSelection)) {
            throw new Error("DataView: forceSelection has been replaced by allowDeselect.");
        }
        //</deprecated>

        this.addEvents(
            /**
             * @event itemtap
             * Fires when a node is tapped on
             * @param {Ext.DataView} this The DataView object
             * @param {Number} index The index of the item that was tapped
             * @param {Ext.Element} item The item element
             * @param {Ext.EventObject} e The event object
             */
            'itemtap',

            /**
             * @event itemdoubletap
             * Fires when a node is double tapped on
             * @param {Ext.DataView} this The DataView object
             * @param {Number} index The index of the item that was tapped
             * @param {Ext.Element} item The item element
             * @param {Ext.EventObject} e The event object
             */
            'itemdoubletap',

            /**
             * @event itemswipe
             * Fires when a node is swipped
             * @param {Ext.DataView} this The DataView object
             * @param {Number} index The index of the item that was tapped
             * @param {Ext.Element} item The item element
             * @param {Ext.EventObject} e The event object
             */
            'itemswipe',

            /**
             * @event containertap
             * Fires when a tap occurs and it is not on a template node.
             * @param {Ext.DataView} this
             * @param {Ext.EventObject} e The raw event object
             */
            "containertap",

            /**
             * @event selectionchange
             * Fires when the selected nodes change.
             * @param {Ext.DataViewSelectionModel} selectionModel The selection model of this DataView object
             * @param {Array} records Array of the selected records
             */
            "selectionchange",

            /**
             * @event beforeselect
             * Fires before a selection is made. If any handlers return false, the selection is cancelled.
             * @param {Ext.DataView} this
             * @param {HTMLElement} node The node to be selected
             * @param {Array} selections Array of currently selected nodes
             */
            "beforeselect"
        );

    },

    // @private
    afterRender: function() {
        var me = this;

        Ext.DataView.superclass.afterRender.call(me);

        var eventHandlers = {
            tapstart : me.onTapStart,
            tapcancel: me.onTapCancel,
            touchend : me.onTapCancel,
            doubletap: me.onDoubleTap,
            swipe    : me.onSwipe,
            scope    : me
        };
        eventHandlers[this.triggerEvent] = me.onTap;
        me.mon(me.getTargetEl(), eventHandlers);
        
        if (this.store) {
            this.bindStore(this.store, true);
        }
    },

    // @private
    onTap: function(e) {
        var item = this.findTargetByEvent(e);
        if (item) {
            Ext.fly(item).removeCls(this.pressedCls);
            var index = this.indexOf(item);
            if (this.onItemTap(item, index, e) !== false) {
                this.fireEvent("itemtap", this, index, item, e);
            }
        }
        else {
            if(this.fireEvent("containertap", this, e) !== false) {
                this.onContainerTap(e);
            }
        }
    },

    // @private
    onTapStart: function(e, t) {
        var me = this,
            item = this.findTargetByEvent(e);

        if (item) {
            if (me.pressedDelay) {
                if (me.pressedTimeout) {
                    clearTimeout(me.pressedTimeout);
                }
                me.pressedTimeout = setTimeout(function() {
                    Ext.fly(item).addCls(me.pressedCls);
                }, Ext.isNumber(me.pressedDelay) ? me.pressedDelay : 100);
            }
            else {
                Ext.fly(item).addCls(me.pressedCls);
            }
        }
    },

    // @private
    onTapCancel: function(e, t) {
        var me = this,
            item = this.findTargetByEvent(e);

        if (me.pressedTimeout) {
            clearTimeout(me.pressedTimeout);
            delete me.pressedTimeout;
        }

        if (item) {
            Ext.fly(item).removeCls(me.pressedCls);
        }
    },

    // @private
    onContainerTap: function(e) {
        //if (this.allowDeselect) {
        //    this.clearSelections();
        //}
    },

    // @private
    onDoubleTap: function(e) {
        var item = this.findTargetByEvent(e);
        if (item) {
            this.fireEvent("itemdoubletap", this, this.indexOf(item), item, e);
        }
    },

    // @private
    onSwipe: function(e) {
        var item = this.findTargetByEvent(e);
        if (item) {
            this.fireEvent("itemswipe", this, this.indexOf(item), item, e);
        }
    },

    // @private
    onItemTap: function(item, index, e) {
        if (this.pressedTimeout) {
            clearTimeout(this.pressedTimeout);
            delete this.pressedTimeout;
        }
        return true;
    }
});