/**
 * The string grid filter allows you to create a filter selection that limits results
 * to values matching a particular string.  The filter can be set programmatically or via 
 * user input with a configurable {@link Ext.form.field.Text text field} in the filter section 
 * of the column header.
 *
 * Example String Filter Usage:
 *
 *     @example
 *     var shows = Ext.create('Ext.data.Store', {
 *         fields: ['id','show'],
 *         data: [
 *             {id: 0, show: 'Battlestar Galactica'},
 *             {id: 1, show: 'Doctor Who'},
 *             {id: 2, show: 'Farscape'},
 *             {id: 3, show: 'Firefly'},
 *             {id: 4, show: 'Star Trek'},
 *             {id: 5, show: 'Star Wars: Christmas Special'}
 *         ]
 *     });
 *   
 *     Ext.create('Ext.grid.Panel', {
 *         renderTo: Ext.getBody(),
 *         title: 'Sci-Fi Television',
 *         height: 250,
 *         width: 250,
 *         store: shows,
 *         plugins: 'gridfilters',
 *         columns: [{
 *             dataIndex: 'id',
 *             text: 'ID',
 *             width: 50
 *         },{
 *             dataIndex: 'show',
 *             text: 'Show',
 *             flex: 1,
 *             filter: {
 *                 // required configs
 *                 type: 'string',
 *                 // optional configs
 *                 value: 'star',  // setting a value makes the filter active. 
 *                 itemDefaults: {
 *                     // any Ext.form.field.Text configs accepted
 *                 }
 *             }
 *         }]
 *     }); 
 */
Ext.define('Ext.grid.filters.filter.String', {
    extend: 'Ext.grid.filters.filter.SingleFilter',
    alias: 'grid.filter.string',
 
    type: 'string',
 
    operator: 'like',
 
    /**
     * @cfg {String} emptyText 
     * The empty text to show for each field.
     * @locale
     */
    emptyText: 'Enter Filter Text...',
 
    itemDefaults: {
        xtype: 'textfield',
        enableKeyEvents: true,
        hideEmptyLabel: false,
        iconCls: Ext.baseCSSPrefix + 'grid-filters-find',
        labelSeparator: '',
        labelWidth: 29,
        margin: 0,
        selectOnFocus: true
    },
 
    menuDefaults: {
        // A menu with only form fields needs some body padding. Normally this padding 
        // is managed by the items, but we have no normal menu items. 
        bodyPadding: 3,
        showSeparator: false
    },
 
    /**
     * @private
     * Template method that is to initialize the filter and install required menu items.
     */
    createMenu: function () {
        var me = this,
            config;
 
        me.callParent();
 
        config = Ext.apply({}, me.getItemDefaults());
        if (config.iconCls && !('labelClsExtra' in config)) {
            config.labelClsExtra = Ext.baseCSSPrefix + 'grid-filters-icon ' + config.iconCls;
        }
        delete config.iconCls;
 
        config.emptyText = config.emptyText || me.emptyText;
        me.inputItem = me.menu.add(config);
 
        me.inputItem.on({
            scope: me,
            keyup: me.onValueChange,
            el: {
                click: function(e) {
                    e.stopPropagation();
                }
            }
        });
    },
 
    /**
     * @private
     * Template method that is to set the value of the filter.
     * @param {Object} value The value to set the filter.
     */
    setValue: function (value) {
        var me = this;
 
        if (me.inputItem) {
            me.inputItem.setValue(value);
        }
 
        me.filter.setValue(value);
 
        if (value && me.active) {
            me.value = value;
            me.updateStoreFilter();
        } else {
            me.setActive(!!value);
        }
    },
 
    activateMenu: function () {
        this.inputItem.setValue(this.filter.getValue());
    },
    
    createFilter: function(config, key) {
        var me = this;
        
        if (me.filterFn) {
            return new Ext.util.Filter({
                filterFn: function(rec) {
                    return Ext.callback(me.filterFn, me.scope, [rec, me.inputItem.getValue()]);
                }
            });
        } else {
            return me.callParent([config, key]);
        }
    }
});