/**
 * This class allows you to define various settings for each configurator field.
 */
Ext.define('Ext.pivot.plugin.configurator.FieldSettings', {
    $configStrict: false,
 
    config: {
        /**
         * @cfg {String} cls 
         *
         * CSS class to add to this configurator field
         */
        cls: '',
 
        /**
         * @cfg {String/Object} style Similar to {@link Ext.Component#style Component style config}.
         */
        style: null,
 
        /**
         * @cfg {String/Array} fixed
         *
         * If you want a field to be fixed in a specific area then you must define those areas here.
         *
         * Possible values:
         *
         * - `aggregate`: "values" area;
         * - `leftAxis`: "row values" area;
         * - `topAxis`: "column values" area;
         *
         */
        fixed: [],
 
        /**
         * @cfg {String[]} allowed
         *
         * Define here the areas where this field can be used.
         *
         * Possible values:
         *
         * - `aggregate`: "values" area;
         * - `leftAxis`: "row values" area;
         * - `topAxis`: "column values" area;
         *
         */
        allowed: ['leftAxis', 'topAxis', 'aggregate'],
 
        /**
         * @cfg {String[]} aggregators
         *
         * Define here the functions that can be used when the dimension is configured as an aggregate.
         *
         * If you need to use your own function then you could override {@link Ext.pivot.Aggregators} like this:
         *
         *      Ext.define('overrides.pivot.Aggregators', {
         *          customFn: function(){
         *              // ... do your own calculation
         *          },
         *          customFnText: 'Custom fn'
         *      });
         *
         * Do not forget to define a text for your function. It will be displayed inside the 'Summarize by' field of
         * the FieldSettings window.
         *
         * If no text is defined then `Custom` will be used.
         *
         * You can also provide a function on the view controller and it will appear in the FieldSettings window as
         * "Custom".
         *
         */
        aggregators: [
            'sum', 'avg', 'min', 'max', 'count', 'countNumbers', 'groupSumPercentage', 'groupCountPercentage',
            'variance', 'varianceP', 'stdDev', 'stdDevP'
        ],
 
        /**
         * @cfg {Object} renderers 
         *
         * These renderers are used only on the aggregate dimensions.
         *
         * The expected value is an object. Each key of this object is a text that will be shown in the "Format as" field
         * in the FieldSettings window. Check out the {@link Ext.grid.column.Column#renderer grid column renderer}
         * to see what is supported.
         *
         *      renderers: {
         *          'Colored 0,000.00': 'coloredRenderer' // function on the controller
         *      }
         *
         */
        renderers: {},
 
        /**
         * @cfg {Object} formatters 
         *
         * Formatters are used only on the aggregate dimensions.
         *
         * The expected value is an object. Each key of this object is a text that will be shown in the "Format as" field
         * in the FieldSettings window. Check out the {@link Ext.grid.column.Column#formatter grid column formatter}
         * to see what is supported.
         *
         *      formatters: {
         *          '0': 'number("0")',
         *          '0%': 'number("0%")'
         *      }
         *
         */
        formatters: {}
    },
 
    isFieldSettings: true,
 
    constructor: function(config){
        this.initConfig(config || {});
        return this.callParent(arguments);
    },
 
    getDefaultEmptyArray: function(prop){
        var ret = this['_' + prop];
 
        if(!ret){
            ret = [];
            this['set' + Ext.String.capitalize(prop)](ret);
        }
 
        return ret;
    },
 
    applyArrayValues: function(prop, newValue, oldValue){
        if(newValue == null || (newValue && Ext.isArray(newValue))){
            return newValue;
        }
 
        if(newValue){
            if(!oldValue){
                oldValue = this['get' + Ext.String.capitalize(prop)]();
            }
 
            Ext.Array.splice(oldValue, 0, oldValue.length, newValue);
        }
 
        return oldValue;
    },
 
    getFixed: function(){
        return this.getDefaultEmptyArray('fixed');
    },
 
    applyFixed: function(newValue, oldValue){
        return this.applyArrayValues('fixed', newValue, oldValue);
    },
 
    getAllowed: function(){
        return this.getDefaultEmptyArray('allowed');
    },
 
    applyAllowed: function(newValue, oldValue){
        return this.applyArrayValues('allowed', newValue, oldValue);
    },
 
    getAggregators: function(){
        return this.getDefaultEmptyArray('aggregators');
    },
 
    applyAggregators: function(newValue, oldValue){
        return this.applyArrayValues('aggregators', newValue, oldValue);
    },
 
    /**
     * Check if this field is fixed in the specified container or not.
     *
     * @param {Ext.pivot.plugin.configurator.Container} fromContainer
     * @return {Boolean}
     */
    isFixed: function(fromContainer){
        var type;
 
        if(!fromContainer){
            return false;
        }
        type = fromContainer.getFieldType();
        return Ext.Array.indexOf(this.getFixed(), type) >= 0;
    },
 
    /**
     * Check if this field is allowed to be added to the specified container
     *
     * @param {Ext.pivot.plugin.configurator.Container} toContainer
     * @return {Boolean}
     */
    isAllowed: function(toContainer){
        var fixed = this.getFixed(),
            type;
 
        if(!toContainer){
            return false;
        }
 
        type = toContainer.getFieldType();
 
        if(fixed.length){
            // if we have 'fixed' constraints then we can only move there 
            return Ext.Array.indexOf(fixed, type) >= 0;
        }
 
        return (type === 'all') || (Ext.Array.indexOf(this.getAllowed(), type) >= 0);
    }
 
});