/**
 * This class stores the matrix results. When the pivot component uses the
 * {@link Ext.pivot.matrix.Local} matrix then this class does
 * calculations in the browser.
 */
Ext.define('Ext.pivot.result.Collection', {
    alternateClassName: [
        'Mz.aggregate.matrix.Results'
    ],
 
    requires: [
        'Ext.pivot.MixedCollection',
        'Ext.pivot.result.Base'
    ],
 
    /**
     * @cfg {String} resultType
     *
     * Define here what class to be used when creating {@link Ext.pivot.result.Base Result} objects
     */
    resultType: 'base',
 
    /**
     * @property {Ext.pivot.MixedCollection} items
     *
     * Collection of {@link Ext.pivot.result.Base Result} objects
     *
     * @private
     */
    items: null,
 
    /**
     * @cfg {Ext.pivot.matrix.Base} matrix
     *
     * Reference to the matrix object
     */
    matrix: null,
 
    constructor: function(config) {
        var me = this;
 
        Ext.apply(me, config || {});
 
        me.items = new Ext.pivot.MixedCollection();
 
        me.items.getKey = function(obj) {
            return obj.leftKey + '/' + obj.topKey;
        };
 
        return me.callParent(arguments);
    },
 
    destroy: function() {
        var me = this;
 
        Ext.destroy(me.items);
        me.matrix = me.items = null;
 
        me.callParent(arguments);
    },
 
    /**
     * Clear all calculated results.
     *
     */
    clear: function() {
        this.items.clear();
    },
 
    /**
     * Add a new Result object by left/top axis keys.
     *
     * If there is already a Result object for the left/top axis pair then return that one.
     *
     * @param leftKey
     * @param topKey
     * @returns {Ext.pivot.result.Base} 
     */
    add: function(leftKey, topKey) {
        var obj = this.get(leftKey, topKey);
 
        if (!obj) {
 
            obj = this.items.add(Ext.Factory.pivotresult({
                type: this.resultType,
                leftKey: leftKey,
                topKey: topKey,
                matrix: this.matrix
            }));
        }
 
        return obj;
    },
 
    /**
     * Returns the Result object for the specified left/top axis keys
     *
     * @param leftKey
     * @param topKey
     * @returns {Ext.pivot.result.Base} 
     */
    get: function(leftKey, topKey) {
        return this.items.getByKey(leftKey + '/' + topKey);
    },
 
    remove: function(leftKey, topKey) {
        this.items.removeAtKey(leftKey + '/' + topKey);
    },
 
    /**
     * Return all Result objects for the specified leftKey
     *
     * @param leftKey
     * @returns Array
     */
    getByLeftKey: function(leftKey) {
        var col = this.items.filterBy(function(item, key) {
            var keys = String(key).split('/');
 
            return (leftKey === keys[0]);
        });
 
        return col.getRange();
    },
 
    /**
     * Return all Result objects for the specified topKey
     *
     * @param topKey
     * @returns Array
     */
    getByTopKey: function(topKey) {
        var col = this.items.filterBy(function(item, key) {
            var keys = String(key).split('/');
 
            return (keys.length > 1 && topKey === keys[1]);
        });
 
        return col.getRange();
    },
 
    /**
     * Calculate aggregate values for each available Result object
     *
     */
    calculate: function() {
        var len = this.items.getCount(),
            i;
 
        for (= 0; i < len; i++) {
            this.items.getAt(i).calculate();
        }
    }
});