text: /**
   * Filter by a configurable Ext.picker.DatePicker menu
   *
   * Example Usage:
   *
   *     var grid = Ext.create('Ext.grid.Panel', {
   *         ...
   *         columns: [{
   *             // required configs
   *             text: 'Date Added',
   *             dataIndex: 'dateAdded',
   *
   *             filter: {
   *                 type: 'date',
   *      
   *                 // optional configs
   *                 dateFormat: 'm/d/Y',  // default
   *                 pickerDefaults: {
   *                     // any DatePicker configs
   *                 },
   *      
   *                 active: true // default is false
   *             }
   *         }],
   *         ...
   *     });
   */
  Ext.define('Ext.grid.filters.filter.Date', {
      extend: 'Ext.grid.filters.filter.TriFilter',
      alias: 'grid.filter.date',
      uses: ['Ext.picker.Date', 'Ext.menu.Menu'],
  
      type: 'date',
  
      config: {
          /**
           * @cfg {Object} [fields]
           * Configures field items individually. These properties override those defined
           * by `{@link #itemDefaults}`.
           *
           * Example usage:
           *      fields: {
           *          gt: { // override fieldCfg options
           *              width: 200
           *          }
           *      },
           */
          fields: {
              lt: {text: 'Before'},
              gt: {text: 'After'},
              eq: {text: 'On'}
          },
  
          /**
           * @cfg {Object} pickerDefaults
           * Configuration options for the date picker associated with each field.
           */
          pickerDefaults: {
              xtype: 'datepicker',
              border: 0
          }
      },
  
      itemDefaults: {
          xtype: 'menucheckitem',
          selectOnFocus: true,
          width: 125,
          menu: {
              layout: 'auto',
              plain: true
          }
      },
  
      /**
       * @cfg {String} dateFormat
       * The date format to return when using getValue.
       * Defaults to {@link Ext.Date.defaultFormat}.
       */
      dateFormat: null,
  
      /**
       * @cfg {Date} maxDate
       * Allowable date as passed to the Ext.DatePicker
       * Defaults to undefined.
       */
  
      /**
       * @cfg {Date} minDate
       * Allowable date as passed to the Ext.DatePicker
       * Defaults to undefined.
       */
      
      /**
       * @private
       * Will convert a timestamp to a Date object or vice-versa.
       * @param {Date/Number} value
       * @param {Boolean} [convertToDate]
       * @return {Date/Number}
       */
      convertValue: function (value, convertToDate) {
          if (convertToDate && !Ext.isDate(value)) {
              value = Ext.isDate(value);
          } else if (!convertToDate && Ext.isDate(value)) {
              value = (+value);
          }
  
          return value;
      },
  
      /**
       * @private
       * Template method that is to initialize the filter and install required menu items.
       */
      createMenu: function (config) {
          var me = this,
              listeners = {
                  scope: me,
                  checkchange: me.onCheckChange
              },
              fields, itemDefaults, pickerCfg, i, len,
              key, item, cfg, field;
  
          me.callParent(arguments);
  
          itemDefaults = me.getItemDefaults();
          fields = me.getFields();
  
          if (!me.dateFormat) {
              me.dateFormat = Ext.Date.defaultFormat;
          }
  
          pickerCfg = Ext.apply({
              minDate: me.minDate,
              maxDate: me.maxDate,
              format:  me.dateFormat,
              listeners: {
                  scope: me,
                  select: me.onMenuSelect
              }
          }, me.getPickerDefaults());
  
          me.fields = {};
  
          for (i = 0, len = me.menuItems.length; i < len; i++) {
              key = me.menuItems[i];
              if (key !== '-') {
                  cfg = {
                      menu: {
                          items: [
                              Ext.apply({
                                  itemId: key
                              }, pickerCfg)
                          ]
                      }
                  };
  
                  if (itemDefaults) {
                      Ext.merge(cfg, itemDefaults);
                  }
  
                  if (fields) {
                      Ext.merge(cfg, fields[key]);
                  }
  
                  item = me.menu.add(cfg);
                  // Date filter types need the field to be the datepicker in TriFilter.setValue().
                  field = me.fields[key] = item.down('datepicker');
                  field.filter = me.filter[key];
                  field.filterKey = key;
  
                  item.on(listeners);
              }
          }
      },
  
      /**
       * Gets the menu picker associated with the passed field
       * @param {String} item The field identifier ('lt', 'gt', 'eq')
       * @return {Object} The menu picker
       */
      getPicker: function (item){
          return this.fields[item];
      },
  
      /**
       * @private
       * Remove the filter from the store but don't update its value or the field UI.
      */
      onCheckChange: function (field, checked) {
          // Only do something if unchecked.  If checked, it doesn't mean anything at this point since the column's store filter won't have
          // any value (i.e., if a user checked this from an unchecked state, the corresponding field won't have a value for its filter).
          var filter = field.down('datepicker').filter,
              v;
  
          // Only proceed if unchecked AND there's a filter value (i.e., there's something to do!).
          if (!checked && filter.getValue()) {
              // Normally we just want to remove the filter from the store, not also to null out the filter value. But, we want to call setValue()
              // which will take care of unchecking the top-level menu item if it's been determined that Date* doesn't have any filters.
              v = {};
              v[filter.getOperator()] = null;
              this.setValue(v);
          }
      },
  
      onFilterRemove: function (operator) {
          var v = {};
  
          v[operator] = null;
          this.setValue(v);
          this.fields[operator].up('menuitem').setChecked(false, /*suppressEvents*/ true);
      },
  
      /**
       * Handler for when the DatePicker for a field fires the 'select' event
       * @param {Ext.picker.Date} picker
       * @param {Object} date
       */
      onMenuSelect: function (picker, date) {
          var fields = this.fields,
              field = fields[picker.itemId],
              gt = fields.gt,
              lt = fields.lt,
              eq = fields.eq,
              v = {};
  
          field.up('menuitem').setChecked(true, /*suppressEvents*/ true);
  
          if (field === eq) {
              lt.up('menuitem').setChecked(false, true);
              gt.up('menuitem').setChecked(false, true);
          } else {
              eq.up('menuitem').setChecked(false, true);
              if (field === gt && (+lt.value < +date)) {
                  lt.up('menuitem').setChecked(false, true);
              } else if (field === lt && (+gt.value > +date)) {
                  gt.up('menuitem').setChecked(false, true);
              }
          }
  
          v[field.filterKey] = date;
          this.setValue(v);
  
          picker.up('menu').hide();
        }
  });
  