import { BehaviorSubject } from 'rxjs';
import { ValidateOption } from '../validate';
import { None } from '../maybe';
import uniqueId from '../../../utils/uniqueId';
import { REF_ID } from './is';
var ModelRef = (function () {
    function ModelRef(current, initialValue, owner) {
        if (current === void 0) { current = null; }
        if (initialValue === void 0) { initialValue = None(); }
        this.initialValue = initialValue;
        this.patchedValue = None();
        this.id = uniqueId('model-ref-');
        this._owner = null;
        this.model$ = new BehaviorSubject(current);
        this.owner = owner;
    }
    Object.defineProperty(ModelRef.prototype, "owner", {
        get: function () {
            return this._owner;
        },
        set: function (owner) {
            this._owner = owner;
            var model = this.getModel();
            if (model) {
                model.owner = owner;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModelRef.prototype, "form", {
        get: function () {
            var _a;
            return (_a = this.owner) === null || _a === void 0 ? void 0 : _a.form;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ModelRef.prototype, "validators", {
        get: function () {
            var _a, _b;
            return (_b = (_a = this.model$.getValue()) === null || _a === void 0 ? void 0 : _a.validators) !== null && _b !== void 0 ? _b : [];
        },
        set: function (validators) {
            var model = this.model$.getValue();
            if (model) {
                model.validators = validators;
            }
        },
        enumerable: false,
        configurable: true
    });
    ModelRef.prototype.getModel = function () {
        return this.model$.getValue();
    };
    ModelRef.prototype.setModel = function (model) {
        var current = this.getModel();
        if (current) {
            current.dispose();
        }
        if (model) {
            model.owner = this.owner;
        }
        this.model$.next(model);
    };
    ModelRef.prototype.getParent = function () {
        return this.owner;
    };
    ModelRef.prototype.dirty = function () {
        var current = this.getModel();
        if (!current) {
            return false;
        }
        return current.dirty();
    };
    ModelRef.prototype.touched = function () {
        var current = this.getModel();
        if (!current) {
            return false;
        }
        return current.touched();
    };
    ModelRef.prototype.validate = function (option) {
        if (option === void 0) { option = ValidateOption.Default; }
        var current = this.getModel();
        if (!current) {
            return Promise.resolve();
        }
        return current.validate(option);
    };
    ModelRef.prototype.getRawValue = function () {
        var _a;
        return (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.getRawValue();
    };
    ModelRef.prototype.pristine = function () {
        var current = this.getModel();
        if (current) {
            return current.pristine();
        }
        return true;
    };
    ModelRef.prototype.valid = function () {
        var current = this.getModel();
        if (current) {
            return current.valid();
        }
        return true;
    };
    Object.defineProperty(ModelRef.prototype, "error", {
        get: function () {
            var _a;
            return (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.error;
        },
        set: function (error) {
            var current = this.getModel();
            if (current) {
                current.error = error;
            }
        },
        enumerable: false,
        configurable: true
    });
    ModelRef.prototype.patchValue = function (value) {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.patchValue(value);
    };
    ModelRef.prototype.initialize = function (value) {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.initialize(value);
    };
    ModelRef.prototype.reset = function () {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.reset();
    };
    ModelRef.prototype.clear = function () {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.clear();
    };
    ModelRef.prototype.clearError = function () {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.clearError();
    };
    ModelRef.prototype.dispose = function () {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.dispose();
        this.model$.next(null);
    };
    ModelRef.prototype.getSubmitValue = function () {
        var _a;
        (_a = this.getModel()) === null || _a === void 0 ? void 0 : _a.getSubmitValue();
    };
    return ModelRef;
}());
ModelRef.prototype[REF_ID] = true;
export { ModelRef };
