    /*!
     * Ext JS Library 3.3.0
     * Copyright(c) 2006-2010 Ext JS, Inc.
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.ux.grid.filter.NumericFilter
     * @extends Ext.ux.grid.filter.Filter
     * Filters using an Ext.ux.menu.RangeMenu.
     * Example Usage:
     *
    var filters = new Ext.ux.grid.GridFilters({
        ...
        filters: [{
            type: 'numeric',
            dataIndex: 'price'
        }]
    });
     *
     */
    Ext.ux.grid.filter.NumericFilter = Ext.extend(Ext.ux.grid.filter.Filter, {

        /**
         * @cfg {Object} fieldCls
         * The Class to use to construct each field item within this menu
         * Defaults to:
         * fieldCls : Ext.form.NumberField
         *
         */
        fieldCls : Ext.form.NumberField,
        /**
         * @cfg {Object} fieldCfg
         * The default configuration options for any field item unless superseded
         * by the {@link #fields} configuration.
         * Defaults to:
         * fieldCfg : {}
         *
         * Example usage:
         *
    fieldCfg : {
        width: 150,
    },
         *
         */
        /**
         * @cfg {Object} fields
         * The field items may be configured individually
         * Defaults to undefined.
         * Example usage:
         *
    fields : {
        gt: { // override fieldCfg options
            width: 200,
            fieldCls: Ext.ux.form.CustomNumberField // to override default {@link #fieldCls}
        }
    },
         *
         */
        /**
         * @cfg {Object} iconCls
         * The iconCls to be applied to each comparator field item.
         * Defaults to:
    iconCls : {
        gt : 'ux-rangemenu-gt',
        lt : 'ux-rangemenu-lt',
        eq : 'ux-rangemenu-eq'
    }
         *
         */
        iconCls : {
            gt : 'ux-rangemenu-gt',
            lt : 'ux-rangemenu-lt',
            eq : 'ux-rangemenu-eq'
        },

        /**
         * @cfg {Object} menuItemCfgs
         * Default configuration options for each menu item
         * Defaults to:
    menuItemCfgs : {
        emptyText: 'Enter Filter Text...',
        selectOnFocus: true,
        width: 125
    }
         *
         */
        menuItemCfgs : {
            emptyText: 'Enter Filter Text...',
            selectOnFocus: true,
            width: 125
        },

        /**
         * @cfg {Array} menuItems
         * The items to be shown in this menu.  Items are added to the menu
         * according to their position within this array. Defaults to:
         * menuItems : ['lt','gt','-','eq']
         *
         */
        menuItems : ['lt', 'gt', '-', 'eq'],

        /**
         * @private
         * Template method that is to initialize the filter and install required menu items.
         */
        init : function (config) {
            // if a menu already existed, do clean up first
            if (this.menu){
                this.menu.destroy();
            }
            this.menu = new Ext.ux.menu.RangeMenu(Ext.apply(config, {
                // pass along filter configs to the menu
                fieldCfg : this.fieldCfg || {},
                fieldCls : this.fieldCls,
                fields : this.fields || {},
                iconCls: this.iconCls,
                menuItemCfgs: this.menuItemCfgs,
                menuItems: this.menuItems,
                updateBuffer: this.updateBuffer
            }));
            // relay the event fired by the menu
            this.menu.on('update', this.fireUpdate, this);
        },

        /**
         * @private
         * Template method that is to get and return the value of the filter.
         * @return {String} The value of this filter
         */
        getValue : function () {
            return this.menu.getValue();
        },

        /**
         * @private
         * Template method that is to set the value of the filter.
         * @param {Object} value The value to set the filter
         */
        setValue : function (value) {
            this.menu.setValue(value);
        },

        /**
         * @private
         * Template method that is to return true if the filter
         * has enough configuration information to be activated.
         * @return {Boolean}
         */
        isActivatable : function () {
            var values = this.getValue();
            for (key in values) {
                if (values[key] !== undefined) {
                    return true;
                }
            }
            return false;
        },

        /**
         * @private
         * Template method that is to get and return serialized filter data for
         * transmission to the server.
         * @return {Object/Array} An object or collection of objects containing
         * key value pairs representing the current configuration of the filter.
         */
        getSerialArgs : function () {
            var key,
                args = [],
                values = this.menu.getValue();
            for (key in values) {
                args.push({
                    type: 'numeric',
                    comparison: key,
                    value: values[key]
                });
            }
            return args;
        },

        /**
         * Template method that is to validate the provided Ext.data.Record
         * against the filters configuration.
         * @param {Ext.data.Record} record The record to validate
         * @return {Boolean} true if the record is valid within the bounds
         * of the filter, false otherwise.
         */
        validateRecord : function (record) {
            var val = record.get(this.dataIndex),
                values = this.getValue();
            if (values.eq !== undefined && val != values.eq) {
                return false;
            }
            if (values.lt !== undefined && val >= values.lt) {
                return false;
            }
            if (values.gt !== undefined && val <= values.gt) {
                return false;
            }
            return true;
        }
    });