/**
 * This class is used for creating a configurator field component.
 *
 * @private
 */
Ext.define('Ext.pivot.plugin.configurator.Column',{
    extend: 'Ext.Component',
    
    requires: [
        'Ext.menu.Menu',
        'Ext.menu.CheckItem',
        'Ext.menu.Item',
        'Ext.menu.Separator',
        'Ext.pivot.plugin.configurator.Field',
        'Ext.pivot.plugin.configurator.window.FilterLabel',
        'Ext.pivot.plugin.configurator.window.FilterValue',
        'Ext.pivot.plugin.configurator.window.FilterTop',
        'Ext.pivot.plugin.configurator.window.FieldSettings'
    ],
    
    alias: 'widget.pivotconfigfield',
 
    childEls: ['textCol', 'filterCol', 'sortCol', 'customCol'],
 
    tabIndex:               0,
    focusable:              true,
    isConfiguratorField:    true,
 
    renderTpl:
        '<div id="{id}-configCol" role="button" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-inner" >' +
            '<span id="{id}-customCol" role="presentation" data-ref="customCol" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-customize ' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-image"></span>' +
            '<span id="{id}-sortCol" role="presentation" data-ref="sortCol" class="' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn"></span>' +
            '<span id="{id}-filterCol" role="presentation" data-ref="filterCol" class="' + Ext.baseCSSPrefix + 'border-box ' + Ext.baseCSSPrefix + 'pivot-grid-config-column-btn"></span>' +
            '<span id="{id}-textCol" role="presentation" data-ref="textCol" data-qtip="{header}" class="' + Ext.baseCSSPrefix + 'pivot-grid-config-column-text ' + Ext.baseCSSPrefix + 'column-header-text ' + Ext.baseCSSPrefix + 'border-box">' +
                '{header}' +
            '</span>' +
        '</div>',
        
    header:                     '&#160;',
    minWidth:                   80,
 
    sortAscText:                'Sort A to Z',
    sortDescText:               'Sort Z to A',
    sortClearText:              'Disable sorting',
    clearFilterText:            'Clear filter from "{0}"',
    labelFiltersText:           'Label filters',
    valueFiltersText:           'Value filters',
    equalsText:                 'Equals...',
    doesNotEqualText:           'Does not equal...',
    beginsWithText:             'Begins with...',
    doesNotBeginWithText:       'Does not begin with...',
    endsWithText:               'Ends with...',
    doesNotEndWithText:         'Does not end with...',
    containsText:               'Contains...',
    doesNotContainText:         'Does not contain...',
    greaterThanText:            'Greater than...',
    greaterThanOrEqualToText:   'Greater than or equal to...',
    lessThanText:               'Less than...',
    lessThanOrEqualToText:      'Less than or equal to...',
    betweenText:                'Between...',
    notBetweenText:             'Not between...',
    top10Text:                  'Top 10...',
 
    equalsLText:                'equals',
    doesNotEqualLText:          'does not equal',
    beginsWithLText:            'begins with',
    doesNotBeginWithLText:      'does not begin with',
    endsWithLText:              'ends with',
    doesNotEndWithLText:        'does not end with',
    containsLText:              'contains',
    doesNotContainLText:        'does not contain',
    greaterThanLText:           'is greater than',
    greaterThanOrEqualToLText:  'is greater than or equal to',
    lessThanLText:              'is less than',
    lessThanOrEqualToLText:     'is less than or equal to',
    betweenLText:               'is between',
    notBetweenLText:            'is not between',
    top10LText:                 'Top 10...',
    topOrderTopText:            'Top',
    topOrderBottomText:         'Bottom',
    topTypeItemsText:           'Items',
    topTypePercentText:         'Percent',
    topTypeSumText:             'Sum',
 
    baseCls:            Ext.baseCSSPrefix + 'pivot-grid-config-column',
    btnIconCls:         Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-image',
    setFilterIconCls:   Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-filter-set',
    clearFilterIconCls: Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-filter-clear',
    ascSortIconCls:     Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-asc',
    descSortIconCls:    Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-desc',
    clearSortIconCls:   Ext.baseCSSPrefix + 'pivot-grid-config-column-btn-sort-clear',
    overCls:            Ext.baseCSSPrefix + 'pivot-grid-config-column-over',
    cls:                Ext.baseCSSPrefix + 'unselectable',
 
    config: {
        /**
         * @cfg {String} fieldType
         *
         * Defines in which area this configurator field exists.
         *
         * Possible values:
         *
         * - `all` = the field is located in the "all fields" area;
         * - `aggregate` = the field is located in the "values" area;
         * - `leftAxis` = the field is located in the "row values" area;
         * - `topAxis` = the field is located in the "column values" area;
         *
         */
        fieldType:  'all',
        /**
         * @cfg {Ext.pivot.plugin.configurator.Field} field
         *
         * Reference to the configured dimension on this configurator field.
         */
        field:      null
    },
 
    destroy: function(){
        this.setField(null);
        this.callParent();
    },
    
    initRenderData: function() {
        var dim = this.getField();
 
        return Ext.apply(this.callParent(arguments), {
            header:         this.getFieldType() == 'aggregate' ? dim.getFieldText() : dim.getHeader(),
            dimension:      dim
        });
    },
 
    afterRender: function(){
        var me = this,
            dim = me.getField(),
            settings = dim.getSettings();
        
        me.callParent();
 
        if(Ext.Array.indexOf(['leftAxis', 'topAxis'], me.getFieldType()) >= 0){
 
            if( !Ext.isDefined(dim.sortable) || dim.sortable ){
                me.addSortCls(dim.direction);
            }
            
            if(dim.filter){
                me.addFilterCls();
            }
        }
 
        // the custom style we configure it on the textCol since that one is one level deeper
        me.textCol.setStyle(settings.getStyle());
        // but the custom class we configure it on the component itself since it's more flexible this way
        me.addCls(settings.getCls());
    },
 
    getMenuConfig: function(){
        var fieldType = this.getFieldType();
 
        if(fieldType == 'leftAxis' || fieldType == 'topAxis'){
            return this.getColMenuConfig();
        }
    },
 
    addSortCls: function(direction){
        var me = this;
 
        if(!me.sortCol){
            return;
        }
 
        if(direction === 'ASC' || !direction){
            me.sortCol.addCls(me.ascSortIconCls);
            me.sortCol.removeCls(me.descSortIconCls);
        }else{
            me.sortCol.addCls(me.descSortIconCls);
            me.sortCol.removeCls(me.ascSortIconCls);
        }
        me.sortCol.addCls(me.btnIconCls);
    },
 
    removeSortCls: function(direction){
        var me = this;
 
        if(!me.sortCol){
            return;
        }
 
        if(direction === 'ASC'){
            me.sortCol.removeCls(me.ascSortIconCls);
        }else{
            me.sortCol.removeCls(me.descSortIconCls);
        }
        me.sortCol.removeCls(me.btnIconCls);
 
    },
 
    addFilterCls: function(){
        var me = this;
 
        if(me.filterCol && !me.filterCol.hasCls(me.setFilterIconCls)){
            me.filterCol.addCls(me.setFilterIconCls);
            me.filterCol.addCls(me.btnIconCls);
        }
    },
 
    removeFilterCls: function(){
        var me = this;
 
        if(me.filterCol){
            me.filterCol.removeCls(me.setFilterIconCls);
            me.filterCol.removeCls(me.btnIconCls);
        }
    },
 
    getColMenuConfig: function(){
        var me = this,
            items = [],
            labelItems, valueItems, commonItems, i,
            filter = me.getField().filter;
 
        // check if the dimension is sortable
        items.push({
            text:       me.sortAscText,
            direction:  'ASC',
            iconCls:    me.ascSortIconCls,
            handler:    me.sortMe
        }, {
            text:       me.sortDescText,
            direction:  'DESC',
            iconCls:    me.descSortIconCls,
            handler:    me.sortMe
        }, {
            text:       me.sortClearText,
            direction:  '',
            disabled:   me.getField().sortable === false,
            iconCls:    me.clearSortIconCls,
            handler:    me.sortMe
        },{
            xtype:  'menuseparator'
        });
 
        commonItems = [{
            text:       me.equalsText,
            operator:   '='
        },{
            text:       me.doesNotEqualText,
            operator:   '!='
        },{
            xtype:  'menuseparator'
        },{
            text:       me.greaterThanText,
            operator:   '>'
        },{
            text:       me.greaterThanOrEqualToText,
            operator:   '>='
        },{
            text:       me.lessThanText,
            operator:   '<'
        },{
            text:       me.lessThanOrEqualToText,
            operator:   '<='
        },{
            xtype:  'menuseparator'
        },{
            text:       me.betweenText,
            operator:   'between'
        },{
            text:       me.notBetweenText,
            operator:   'not between'
        }];
 
        labelItems = Ext.clone(commonItems);
        Ext.Array.insert(labelItems, 3, [{
            text:       me.beginsWithText,
            operator:   'begins'
        },{
            text:       me.doesNotBeginWithText,
            operator:   'not begins'
        },{
            text:       me.endsWithText,
            operator:   'ends'
        },{
            text:       me.doesNotEndWithText,
            operator:   'not ends'
        },{
            xtype:  'menuseparator'
        },{
            text:       me.containsText,
            operator:   'contains'
        },{
            text:       me.doesNotContainText,
            operator:   'not contains'
        },{
            xtype:  'menuseparator'
        }]);
 
        for(= 0; i < labelItems.length; i++){
            labelItems[i]['checked'] = (filter && filter.type == 'label' && filter.operator == labelItems[i].operator);
        }
 
        valueItems = Ext.clone(commonItems);
        valueItems.push({
            xtype:  'menuseparator'
        },{
            text:       me.top10Text,
            operator:   'top10'
        });
 
        for(= 0; i < valueItems.length; i++){
            valueItems[i]['checked'] = (filter && filter.type == 'value' && filter.operator == valueItems[i].operator);
        }
 
        items.push({
            text:       Ext.String.format(me.clearFilterText, me.header),
            iconCls:    me.clearFilterIconCls,
            disabled:   !filter,
            handler:    me.onRemoveFilter
        },{
            text:   me.labelFiltersText,
            menu: {
                defaults: {
                    handler:    me.onShowFilter,
                    scope:      me,
                    xtype:      'menucheckitem',
                    group:      'filterlabel',
                    type:       'label'
                },
                items: labelItems
            }
        },{
            text:   me.valueFiltersText,
            menu: {
                defaults: {
                    handler:    me.onShowFilter,
                    scope:      me,
                    xtype:      'menucheckitem',
                    group:      'filtervalue',
                    type:       'value'
                },
                items: valueItems
            }
        });
 
        return {
            defaults: {
                scope:      me
            },
            items: items
        };
    },
 
    sortMe: function(btn){
        var me = this,
            field = me.getField();
 
        if(Ext.isEmpty(btn.direction)){
            //disable sorting
            field.setSortable(false);
            me.removeSortCls(field.getDirection());
        }else{
            field.setSortable(true);
            me.addSortCls(btn.direction);
            field.setDirection(btn.direction);
        }
        me.applyChanges();
    },
 
    onShowFilter: function(btn){
        var me = this,
            panel = me.up('pivotconfigpanel'),
            dataAgg = [],
            winCfg = {},
            filter = me.getField().getFilter(),
            values = {
                type:           btn.type,
                operator:       btn.operator,
                value:          (filter ? filter.value : ''),
                from:           (filter ? (Ext.isArray(filter.value) ? filter.value[0] : '') : ''),
                to:             (filter ? (Ext.isArray(filter.value) ? filter.value[1] : '') : ''),
                caseSensitive:  (filter ? filter.caseSensitive : false),
                topSort:        (filter ? filter.topSort : false)
            },
            items = panel.getAggregateContainer().items,
            len = items.getCount(),
            win, winClass, data, i, field;
 
        for(= 0; i < len; i++){
            field = items.getAt(i).getField();
            dataAgg.push([field.getHeader(), field.getId()]);
        }
 
        if(btn.type == 'label' || (btn.type == 'value' && btn.operator != 'top10')){
            data = [
                [me.equalsLText, '='],
                [me.doesNotEqualLText, '!='],
                [me.greaterThanLText, '>'],
                [me.greaterThanOrEqualToLText, '>='],
                [me.lessThanLText, '<'],
                [me.lessThanOrEqualToLText, '<='],
                [me.betweenLText, 'between'],
                [me.notBetweenLText, 'not between']
            ];
 
            if(btn.type == 'label'){
                Ext.Array.insert(data, 3, [
                    [me.beginsWithLText, 'begins'],
                    [me.doesNotBeginWithLText, 'not begins'],
                    [me.endsWithLText, 'ends'],
                    [me.doesNotEndWithLText, 'not ends'],
                    [me.containsLText, 'contains'],
                    [me.doesNotContainLText, 'not contains']
                ]);
                winClass = 'Ext.pivot.plugin.configurator.window.FilterLabel';
            }else{
                winClass = 'Ext.pivot.plugin.configurator.window.FilterValue';
                Ext.apply(values, {
                    dimensionId:    (filter ? filter.dimensionId : '')
                });
 
                winCfg.storeAgg = new Ext.data.ArrayStore({
                    fields: ['text', 'value'],
                    data:   dataAgg
                });
            }
 
            winCfg.store = new Ext.data.ArrayStore({
                fields: ['text', 'value'],
                data:   data
            });
        }else{
            winClass = 'Ext.pivot.plugin.configurator.window.FilterTop';
            data = [];
 
            Ext.apply(winCfg, {
                storeTopOrder: new Ext.data.ArrayStore({
                    fields: ['text', 'value'],
                    data:[
                        [me.topOrderTopText, 'top'],
                        [me.topOrderBottomText, 'bottom']
                    ]
                }),
                storeTopType: new Ext.data.ArrayStore({
                    fields: ['text', 'value'],
                    data:[
                        [me.topTypeItemsText, 'items'],
                        [me.topTypePercentText, 'percent'],
                        [me.topTypeSumText, 'sum']
                    ]
                }),
                storeAgg: new Ext.data.ArrayStore({
                    fields: ['text', 'value'],
                    data:   dataAgg
                })
            });
 
            Ext.apply(values, {
                operator:       'top10',
                dimensionId:    (filter ? filter.dimensionId : ''),
                topType:        (filter ? filter.topType : 'items'),
                topOrder:       (filter ? filter.topOrder : 'top')
            });
        }
 
        win = Ext.create(winClass, Ext.apply(winCfg || {}, {
            title:      me.header,
            listeners: {
                applysettings: Ext.bind(me.onApplyFilterSettings, me)
            }
        }));
 
        win.loadSettings(values);
        win.show();
    },
 
    onApplyFilterSettings: function(win, filter){
        var me = this;
 
        win.close();
        me.addFilterCls();
        me.getField().setFilter(filter);
        me.applyChanges();
    },
 
    onRemoveFilter: function(){
        var me = this;
 
        me.removeFilterCls();
        me.getField().setFilter(null);
        me.applyChanges();
    },
 
    /**
     * This is used for firing the 'configchange' event
     *
     */
    applyChanges: function(){
        if(this.ownerCt) {
            this.ownerCt.applyChanges(this);
        }
    }
});