"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var vdom_1 = require("@dojo/framework/core/vdom");
var icache_1 = require("@dojo/framework/core/middleware/icache");
function compareValidity(a, b) {
    if (typeof a === 'boolean' && typeof b === 'boolean') {
        return true;
    }
    if (typeof a === 'boolean' || typeof b === 'boolean') {
        return false;
    }
    if (b.valid === undefined) {
        return false;
    }
    return a.message === b.message;
}
exports.createFormMiddleware = function () {
    var icache = icache_1.createICacheMiddleware();
    var factory = vdom_1.create({ icache: icache });
    var formMiddleware = factory(function Form(_a) {
        var icache = _a.middleware.icache;
        var api = {
            value: function (values) {
                var currentValues = icache.getOrSet('values', {});
                if (values !== undefined) {
                    icache.set('values', values);
                    var newValues = tslib_1.__assign({}, currentValues, values);
                    var callbacks = icache.get('callbacks');
                    callbacks && callbacks.onValue && callbacks.onValue(newValues);
                    return newValues;
                }
                return currentValues;
            },
            submit: function (callback, defaults) {
                if (!this.valid()) {
                    return;
                }
                if (defaults) {
                    return callback(tslib_1.__assign({}, defaults, this.value()));
                }
                return callback(this.value());
            },
            onValue: function (callback) {
                icache.set('callbacks', { onValue: callback }, false);
            },
            disabled: function (disabled) {
                if (disabled !== undefined) {
                    icache.set('formDisabled', disabled);
                    return disabled;
                }
                return icache.getOrSet('formDisabled', false);
            },
            valid: function () {
                var values = icache.getOrSet('valid', {});
                var requiredValues = icache.getOrSet('required', {});
                return Object.keys(tslib_1.__assign({}, values, requiredValues)).every(function (key) {
                    var valid = values[key];
                    var value = typeof valid === 'boolean' || valid === undefined ? valid : valid.valid;
                    return (value === undefined && !requiredValues[key]) || Boolean(value);
                });
            },
            reset: function () {
                icache.set('values', {});
                var valid = {};
                var values = icache.getOrSet('valid', {});
                Object.keys(values).map(function (key) {
                    valid[key] = { valid: undefined, message: '' };
                });
                icache.set('valid', valid);
                icache.set('required', {});
                icache.set('formDisabled', false);
                icache.set('disabled', {});
            },
            field: function (name, required) {
                var _a, _b;
                if (required === void 0) { required = false; }
                var requiredValues = icache.getOrSet('required', {});
                if (requiredValues[name] === undefined) {
                    icache.set('required', tslib_1.__assign({}, requiredValues, (_a = {}, _a[name] = required, _a)));
                }
                var values = icache.getOrSet('values', {});
                if (!values.hasOwnProperty(name)) {
                    icache.set('values', tslib_1.__assign({}, values, (_b = {}, _b[name] = undefined, _b)));
                }
                return {
                    name: name,
                    value: function (newValue) {
                        var _a, _b;
                        var values = icache.getOrSet('values', {});
                        if (newValue !== undefined && values[name] !== newValue) {
                            icache.set('values', tslib_1.__assign({}, values, (_a = {}, _a[name] = newValue, _a)));
                            var callbacks = icache.get('callbacks');
                            callbacks &&
                                callbacks.onValue &&
                                callbacks.onValue((_b = {}, _b[name] = newValue, _b));
                            return newValue;
                        }
                        return values[name];
                    },
                    valid: function (valid, message) {
                        var _a, _b;
                        var newValue = valid || {
                            valid: valid,
                            message: message || ''
                        };
                        var values = icache.getOrSet('valid', {});
                        if (!values.hasOwnProperty(name)) {
                            icache.set('valid', tslib_1.__assign({}, values, (_a = {}, _a[name] = newValue, _a)));
                            return newValue;
                        }
                        if (valid !== undefined) {
                            if (!compareValidity(newValue, values[name])) {
                                icache.set('valid', tslib_1.__assign({}, values, (_b = {}, _b[name] = newValue, _b)));
                                return newValue;
                            }
                        }
                        return values[name];
                    },
                    required: function (required) {
                        var _a;
                        var values = icache.getOrSet('required', {});
                        if (required !== undefined && values[name] !== required) {
                            icache.set('required', tslib_1.__assign({}, values, (_a = {}, _a[name] = required, _a)));
                            return required;
                        }
                        return Boolean(values[name]);
                    },
                    disabled: function (disabled) {
                        var _a;
                        var formValue = icache.getOrSet('formDisabled', false);
                        var values = icache.getOrSet('disabled', {});
                        if (disabled !== undefined && values[name] !== disabled) {
                            icache.set('disabled', tslib_1.__assign({}, values, (_a = {}, _a[name] = disabled, _a)));
                            return formValue || disabled;
                        }
                        return formValue || Boolean(values[name]);
                    }
                };
            }
        };
        var apiFactory = function () {
            return api;
        };
        apiFactory.value = api.value;
        apiFactory.submit = api.submit;
        apiFactory.onValue = api.onValue;
        apiFactory.disabled = api.disabled;
        apiFactory.valid = api.valid;
        apiFactory.reset = api.reset;
        apiFactory.field = api.field;
        return apiFactory;
    });
    return formMiddleware;
};
exports.default = exports.createFormMiddleware;

/*# sourceMappingURL=middleware.js.map*/