import { __awaiter, __extends, __generator, __spreadArrays } from "tslib";
import Vue from 'vue';
import { AbstractControl } from './abstract-control';
var FormGroup = /** @class */ (function (_super) {
    __extends(FormGroup, _super);
    function FormGroup(_controls, validators, options) {
        if (validators === void 0) { validators = []; }
        var _this = _super.call(this, validators, options) || this;
        _this._controls = _controls;
        _this.validators = validators;
        _this.setupControlsParent();
        return _this;
    }
    Object.defineProperty(FormGroup.prototype, "value", {
        /**
         * Return an agregate values of all enabled controls.
         */
        get: function () {
            var _this = this;
            var values = {};
            var enabledControls = Object.keys(this._controls)
                .filter(function (c) { return _this._controls[c].enabled; })
                .reduce(function (obj, key) {
                obj[key] = _this._controls[key];
                return obj;
            }, {});
            Object.keys(enabledControls).map(function (c) { return values[c] = enabledControls[c].value; });
            return values;
        },
        set: function (value) {
            throw Error('Assigning a value to a FormGroup is not yet implemented');
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "valid", {
        get: function () {
            if (!this.enabled || this.readonly) {
                return true;
            }
            else {
                return (this.validators.every(function (v) { return !!v.lastCheck; })
                    &&
                        this.controls.every(function (c) { return c.valid; }));
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "enabled", {
        get: function () {
            return this._enabled;
        },
        set: function (isEnabled) {
            this._enabled = isEnabled;
            this.controls.forEach(function (c) { return c.enabled = isEnabled; });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "waiting", {
        get: function () {
            return this._waiting;
        },
        set: function (isWaiting) {
            this._waiting = isWaiting;
            this.controls.forEach(function (c) { return c.waiting = isWaiting; });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "readonly", {
        get: function () {
            return this._readonly;
        },
        set: function (isReadonly) {
            this._readonly = isReadonly;
            this.controls.forEach(function (c) { return c.readonly = isReadonly; });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "errors", {
        get: function () {
            return (this.enabled && !this.readonly) ? this._errors : [];
        },
        set: function (errors) {
            this._errors = __spreadArrays(errors);
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "errorsDeep", {
        get: function () {
            if (!this.enabled || this.readonly) {
                return [];
            }
            var errors = __spreadArrays(this.errors);
            this.controls.forEach(function (control) {
                errors = __spreadArrays(errors, control.errorsDeep);
            });
            return errors;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(FormGroup.prototype, "touched", {
        get: function () {
            return this.controls.every(function (c) { return c.touched; });
        },
        enumerable: false,
        configurable: true
    });
    FormGroup.prototype.submit = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        _super.prototype.submit.call(this);
                        return [4 /*yield*/, Promise.all(this.controls.map(function (c) { return c.submit(); }))];
                    case 1:
                        _a.sent();
                        if (!!this._hasAnyControlsInError()) return [3 /*break*/, 3];
                        this.validate();
                        return [4 /*yield*/, this.validateAsync()];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3: return [2 /*return*/];
                }
            });
        });
    };
    FormGroup.prototype.reset = function () {
        _super.prototype.reset.call(this);
        this.controls.forEach(function (c) { return c.reset(); });
    };
    FormGroup.prototype.endEdition = function () {
        if (!this.touched) {
            return;
        }
        _super.prototype.endEdition.call(this);
    };
    Object.defineProperty(FormGroup.prototype, "controls", {
        get: function () {
            return Object.values(this._controls);
        },
        enumerable: false,
        configurable: true
    });
    FormGroup.prototype.containsControl = function (name) {
        return typeof this._controls[name] !== 'undefined';
    };
    FormGroup.prototype.getControl = function (name) {
        if (this._controls[name] !== undefined) {
            return this._controls[name];
        }
        else {
            throw Error("There is no control with the name " + name + " in this group");
        }
    };
    FormGroup.prototype.addControl = function (name, control) {
        if (this._controls[name] !== undefined) {
            throw Error("There is already a control with name " + name + " in this group");
        }
        control.parent = this;
        Vue.prototype.$set(this._controls, name, control);
    };
    FormGroup.prototype.setControl = function (name, control) {
        control.parent = this;
        Vue.prototype.$set(this._controls, name, control);
    };
    FormGroup.prototype.removeControl = function (name) {
        Vue.prototype.$delete(this._controls, name);
    };
    FormGroup.prototype.setupControlsParent = function () {
        var _this = this;
        this.controls.forEach(function (c) { return c.parent = _this; });
    };
    FormGroup.prototype._hasAnyControlsInError = function () {
        return this.controls.some(function (c) { return c.hasError(); });
    };
    return FormGroup;
}(AbstractControl));
export { FormGroup };
//# sourceMappingURL=form-group.js.map