"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "AggregatedCollection", {
    enumerable: true,
    get: function() {
        return AggregatedCollection;
    }
});
const _mapCollection = require("./mapCollection");
const _array = require("../../helpers/array");
const _mixed = require("../../helpers/mixed");
class AggregatedCollection extends _mapCollection.MapCollection {
    /**
   * Get merged values for all indexes.
   *
   * @param {boolean} [readFromCache=true] Determine if read results from the cache.
   * @returns {Array}
   */ getMergedValues(readFromCache = true) {
        if (readFromCache === true) {
            return this.mergedValuesCache;
        }
        if (this.getLength() === 0) {
            return [];
        }
        // Below variable stores values for every particular map. Example describing situation when we have 2 registered maps,
        // with length equal to 5.
        //
        // +---------+---------------------------------------------+
        // |         |                  indexes                    |
        // +---------+---------------------------------------------+
        // |   maps  |     0    |   1   |    2  |   3   |    4     |
        // +---------+----------+-------+-------+-------+----------+
        // |    0    | [[ value,  value,  value,  value,  value ], |
        // |    1    | [  value,  value,  value,  value,  value ]] |
        // +---------+----------+-------+-------+-------+----------+
        const mapsValuesMatrix = (0, _array.arrayMap)(this.get(), (map)=>map.getValues());
        // Below variable stores values for every particular index. Example describing situation when we have 2 registered maps,
        // with length equal to 5.
        //
        // +---------+---------------------+
        // |         |         maps        |
        // +---------+---------------------+
        // | indexes |     0    |    1     |
        // +---------+----------+----------+
        // |    0    | [[ value,  value ], |
        // |    1    | [  value,  value ], |
        // |    2    | [  value,  value ], |
        // |    3    | [  value,  value ], |
        // |    4    | [  value,  value ]] |
        // +---------+----------+----------+
        const indexesValuesMatrix = [];
        const mapsLength = (0, _mixed.isDefined)(mapsValuesMatrix[0]) && mapsValuesMatrix[0].length || 0;
        for(let index = 0; index < mapsLength; index += 1){
            const valuesForIndex = [];
            for(let mapIndex = 0; mapIndex < this.getLength(); mapIndex += 1){
                valuesForIndex.push(mapsValuesMatrix[mapIndex][index]);
            }
            indexesValuesMatrix.push(valuesForIndex);
        }
        return (0, _array.arrayMap)(indexesValuesMatrix, this.aggregationFunction);
    }
    /**
   * Get merged value for particular index.
   *
   * @param {number} index Index for which we calculate single result.
   * @param {boolean} [readFromCache=true] Determine if read results from the cache.
   * @returns {*}
   */ getMergedValueAtIndex(index, readFromCache) {
        const valueAtIndex = this.getMergedValues(readFromCache)[index];
        return (0, _mixed.isDefined)(valueAtIndex) ? valueAtIndex : this.fallbackValue;
    }
    /**
   * Rebuild cache for the collection.
   */ updateCache() {
        this.mergedValuesCache = this.getMergedValues(false);
    }
    constructor(aggregationFunction, fallbackValue){
        super(), /**
   * List of merged values. Value for each index is calculated using values inside registered maps.
   *
   * @type {Array}
   */ this.mergedValuesCache = [];
        this.aggregationFunction = aggregationFunction;
        this.fallbackValue = fallbackValue;
    }
}
