"use strict";
/* TODO auto-generated eslint ignore, please fix! */
/**
 * Sorting with multiple criteria
 *
 *  Copyright (C) 2010-2019 R-T Specialty, LLC.
 *
 *  This file is part of liza.
 *
 *  liza is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 *  A simple recursive sorter with support for multiple criteria
 *
 *  For simplicity's sake, this simply uses JavaScript's built-in sort()
 *  method using the supplied predicates. It then iterates through the sorted
 *  result and, using the supplied predicates, determines how the results
 *  should be grouped for sub-sorting. Because of this extra iteration, this
 *  isn't a very efficient algorithm, but it doesn't need to be for our
 *  purposes.
 *
 *
 * @needsLove
 *   - References to "quote" should be replaced with generic terminology
 *     representing a document.
 *   - Dependencies need to be liberated:
 *       - BucketDataValidator.
 *   - Global references (e.g. jQuery) must be removed.
 *   - Checkbox-specific logic must be extracted.
 *   - This class is doing too much.
 * @end needsLove
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.multiSort = void 0;
/**
 * Recursively sorts the given data using the provided predicates
 *
 * The predicate used depends on the depth of the sort. Results will be
 * grouped according to similarity and recursively sorted until either no
 * predicates remain or until the results are so dissimilar that they cannot
 * be further sorted.
 *
 * @param data  - data to be sorted
 * @param preds - predicates for arbitrary depth
 *
 * @return sorted data
 */
function multiSort(data, preds) {
    // nothing can be done if we (a) don't have a length (non-array?), (b)
    // the array is empty or (c) if we have no more preds
    if (preds.length === 0 || data.length < 2) {
        return data;
    }
    var sorted = data.slice(), pred = preds[0], next_preds = preds.slice(1);
    // sort according to the current predicate
    sorted.sort(pred);
    // if we cannot do any more sub-sorting, then simply return this sorted
    // result
    if (preds.length === 1) {
        return sorted;
    }
    return multiSubSort(sorted, pred, next_preds);
}
exports.multiSort = multiSort;
/**
 * Recursively sorts sorted results by grouping similar elements
 */
function multiSubSort(sorted, pred, next_preds) {
    var i = 0;
    var len = sorted.length;
    var result = [];
    var cur = [sorted[0]];
    // note that this increment is intentional---at the bottom of this loop,
    // we push the current element into the current group. Therefore, this
    // extra step (past the end of the sorted array) ensures that the last
    // element will be properly processed as part of the last group. The
    // fact that we push undefined onto cur before returning is of no
    // consequence.
    while (i++ < len) {
        // if we are at the last element in the array OR if the current
        // element is to be sorted differently than the previous, process
        // the current group of elements before continuing
        if (i === len || pred(sorted[i - 1], sorted[i]) !== 0) {
            // the element is different; sub-sort
            var sub = cur.length > 1 ? multiSort(cur, next_preds) : cur;
            for (var j in sub) {
                result.push(sub[j]);
            }
            cur = [];
        }
        cur.push(sorted[i]);
    }
    return result;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXVsdGlTb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiTXVsdGlTb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxvREFBb0Q7QUFDcEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Q0c7OztBQU1IOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxJQUFXLEVBQUUsS0FBa0I7SUFDdkQsc0VBQXNFO0lBQ3RFLHFEQUFxRDtJQUNyRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3pDLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRCxJQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQ3pCLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQ2YsVUFBVSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFOUIsMENBQTBDO0lBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEIsdUVBQXVFO0lBQ3ZFLFNBQVM7SUFDVCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1FBQ3RCLE9BQU8sTUFBTSxDQUFDO0tBQ2Y7SUFFRCxPQUFPLFlBQVksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFyQkQsOEJBcUJDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxNQUFXLEVBQUUsSUFBZSxFQUFFLFVBQXVCO0lBQ3pFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNWLElBQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFFMUIsSUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFdEIsd0VBQXdFO0lBQ3hFLHNFQUFzRTtJQUN0RSxzRUFBc0U7SUFDdEUsb0VBQW9FO0lBQ3BFLGlFQUFpRTtJQUNqRSxlQUFlO0lBQ2YsT0FBTyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUU7UUFDaEIsK0RBQStEO1FBQy9ELGlFQUFpRTtRQUNqRSxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNyRCxxQ0FBcUM7WUFDckMsSUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUU5RCxLQUFLLElBQU0sQ0FBQyxJQUFJLEdBQUcsRUFBRTtnQkFDbkIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNyQjtZQUVELEdBQUcsR0FBRyxFQUFFLENBQUM7U0FDVjtRQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDckI7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIn0=