/**
 * Aggregates and transforms <input> elements in the given scope (determined by the passed {@link ChoiceContainer} Element)
 * to {@link ChoiceResult} objects.
 *
 * If the choice container is marked with the data attribute data-sieve non checked inputs are filtered
 * @see {@link ChoiceResult#filter}
 *
 * The return object has the following structure:
 *  { "someName" : [
 *      {"name": "first", "checked": true},
 *      {"name": "second", "checked": false}
 *  ]}
 *
 *  If multiple containers share the same name the array containing the {@link ChoiceResult} objects is overwritten.
 */
import { SubmitState } from "./SubmitState";
var ChoiceAggregator = /** @class */ (function () {
    function ChoiceAggregator() {
    }
    /**
     * Returns an {@link ChoiceAggregationResult} containing the permission to be submitted and the attributes.
     *
     * @param choiceContainers
     */
    ChoiceAggregator.aggregate = function (choiceContainers) {
        var _this = this;
        var choices = {};
        var allowed = true;
        choiceContainers.forEach(function (container) {
            var name = container.dataset.name;
            var required = JSON.parse(container.dataset.required || "false");
            if (name === undefined) {
                throw new Error("name is undefined");
            }
            _this.addToContainer(name, _this.toChoiceResults(container, "input[type='checkbox']"), choices);
            _this.addToContainer(name, _this.toChoiceResults(container, "input[type='radio']"), choices);
            if (required && !Object.keys(choices).find(function (choice) { return choice === name; }))
                allowed = false;
        });
        return { state: allowed ? SubmitState.ALLOWED : SubmitState.SUBMIT_REQUIRED_ERROR, attributes: choices };
    };
    ChoiceAggregator.addToContainer = function (name, items, container) {
        if (items.length > 0) {
            if (container[name] !== undefined) {
                console.info("duplicated name: " + name + " - multiple container share the same name => results overwritten.");
            }
            container[name] = items;
        }
    };
    /**
     * Transforms items matching the given selector to an array of {@link ChoiceResult} and filters
     * based on the sieve data attribute
     * @see {@link ChoiceAggregator#filter}
     * @param container
     * @param selector
     */
    ChoiceAggregator.toChoiceResults = function (container, selector) {
        return this.querySelectorAll(container, selector)
            .filter(this.filter(container))
            .map(function (e) { return new ChoiceResult(e.dataset.name || "", e.checked); });
    };
    /**
     * Returns a filter that either filters 'unchecked' input elements or not depending on
     * the sieve data attribute
     * @param container the choice container element {@link ChoiceContainer}
     */
    ChoiceAggregator.filter = function (container) {
        if (container.dataset.sieve === "true") {
            return function (e) { return e.checked; };
        }
        return function (e) { return true; };
    };
    /**
     * Transforms a {@link NodeListOf<Element>} to an array of {@link Element}
     * @param element
     * @param selector
     */
    ChoiceAggregator.querySelectorAll = function (element, selector) {
        return [].slice.call(element.querySelectorAll(selector));
    };
    return ChoiceAggregator;
}());
export { ChoiceAggregator };
/**
 * Tuple that represents a choice result by its name and its boolean value
 */
var ChoiceResult = /** @class */ (function () {
    function ChoiceResult(name, value) {
        this.name = name;
        this.value = value;
    }
    return ChoiceResult;
}());
//# sourceMappingURL=ChoiceAggregator.js.map