import { __decorate, __metadata } from "tslib";
import { ChangeDetectorRef, Directive, ElementRef, Inject, Injector, Input, Optional } from '@angular/core';
import { AbstractControl, FormControl, Validators } from '@angular/forms';
import { LayoutComponentBase } from '@anglr/dynamic/layout';
import { LOGGER } from '@anglr/common';
import { DynamicOutput } from '@anglr/dynamic/relations';
import { FORM_COMPONENT_CONTROL } from '../../misc/tokens';
import { FormComponentControlType } from '../../misc/enums';
import { getControlForType, getFormControl } from '../../misc/utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
/**
 * Base component for form component
 */
export class FormComponentBase extends LayoutComponentBase {
    //######################### public properties - inputs #########################
    /**
     * Form component value
     */
    set value(value) {
        var _a;
        const oldValue = this.value;
        this.valueOutput = value;
        if (value !== oldValue) {
            (_a = this.control) === null || _a === void 0 ? void 0 : _a.patchValue(value);
        }
    }
    get value() {
        return this.valueOutput;
    }
    /**
     * Indication whether form component is required
     */
    set required(value) {
        var _a, _b;
        this._required = value;
        if (value === true) {
            (_a = this.control) === null || _a === void 0 ? void 0 : _a.addValidators(Validators.required);
            return;
        }
        (_b = this.control) === null || _b === void 0 ? void 0 : _b.removeValidators(Validators.required);
    }
    get required() {
        return this._required;
    }
    /**
     * Indication whether form component is disabled
     */
    set disabled(value) {
        var _a, _b;
        this._disabled = value;
        if (value === true) {
            (_a = this.control) === null || _a === void 0 ? void 0 : _a.disable();
            return;
        }
        (_b = this.control) === null || _b === void 0 ? void 0 : _b.enable();
    }
    get disabled() {
        return this._disabled;
    }
    //######################### constructor #########################
    constructor(_changeDetector, _element, _injector, _parentControl, _logger) {
        super(_changeDetector, _element, _injector, _logger);
        this._parentControl = _parentControl;
        //######################### protected properties #########################
        /**
         * Form component control
         */
        this.control = new FormControl();
    }
    //######################### protected methods - _onOptionsSet implementation #########################
    /**
     * @inheritdoc
     */
    onOptionsSet() {
        var _a, _b, _c, _d;
        if (!this.options) {
            return;
        }
        (_a = this.controlSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
        this.controlSubscription = null;
        this.control = this._getFormControl((_b = this.options) === null || _b === void 0 ? void 0 : _b.controlName, this._parentControl, FormComponentControlType.FormControl, this.value);
        this._registerValidations();
        this.controlSubscription = (_d = (_c = this.control) === null || _c === void 0 ? void 0 : _c.valueChanges) === null || _d === void 0 ? void 0 : _d.subscribe(value => {
            this.valueOutput = value;
        });
    }
    //######################### protected methods #########################
    /**
     * Registers component-specific validators
     */
    _registerValidations() { }
    //######################### private methods #########################
    /**
     * Gets form component control for control name
     * @param controlName Form component control name
     * @param parentControl Parent form control
     * @param defaultControlType Default control type when parent does not exists or not contains control with specified name
     * @param initValue Initial value for control
     * @returns Specified type of control
     */
    _getFormControl(controlName, parentControl, defaultControlType = FormComponentControlType.FormControl, initValue) {
        var _a;
        let control = getFormControl(controlName, parentControl, defaultControlType, initValue);
        if (!control) {
            (_a = this.logger) === null || _a === void 0 ? void 0 : _a.warn('FormComponentBase: Unable to find control with name {{@name}}', { name: controlName });
            control = getControlForType(defaultControlType, initValue);
        }
        if (this.required) {
            control.addValidators(Validators.required);
        }
        if (this.disabled) {
            control.disable();
        }
        return control;
    }
}
FormComponentBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: FormComponentBase, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }, { token: FORM_COMPONENT_CONTROL, optional: true }, { token: LOGGER, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
FormComponentBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.4", type: FormComponentBase, inputs: { value: "value", required: "required", disabled: "disabled" }, usesInheritance: true, ngImport: i0 });
__decorate([
    DynamicOutput(),
    __metadata("design:type", Object)
], FormComponentBase.prototype, "valueOutput", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: FormComponentBase, decorators: [{
            type: Directive
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }, { type: i1.AbstractControl, decorators: [{
                    type: Inject,
                    args: [FORM_COMPONENT_CONTROL]
                }, {
                    type: Optional
                }] }, { type: undefined, decorators: [{
                    type: Inject,
                    args: [LOGGER]
                }, {
                    type: Optional
                }] }], propDecorators: { value: [{
                type: Input
            }], required: [{
                type: Input
            }], disabled: [{
                type: Input
            }], valueOutput: [] } });
//# sourceMappingURL=formComponentBase.js.map