import { Behavior } from './behavior';
import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs';
import { FormControl, ValidatorFn } from '@angular/forms';
import { Change } from './changed-fields';
import { Layout } from './layout';
import { ConfigurationService } from '../../configuration/configuration.service';
import { Component } from './component';
import { Validation } from './validation';
import { ElementRef } from "@angular/core";
import { UpdateOnStrategy } from "./update-strategy";
/**
 * Holds the logic common to all data field Model objects.
 * @typeparam T - type of the `value` property of the data field
 */
export declare abstract class DataField<T> {
    private _stringId;
    private _title;
    private _behavior;
    private _placeholder?;
    private _description?;
    private _layout?;
    validations?: Array<Validation>;
    private _component?;
    private _parentTaskId?;
    private _parentCaseId?;
    /**
     * @ignore
     * Current value of the data field
     */
    protected _value: BehaviorSubject<T>;
    /**
     * @ignore
     * Previous value of the data field
     */
    protected _previousValue: BehaviorSubject<T>;
    /**
     * @ignore
     * Whether the data field Model object was initialized, we push that info into stream
     *
     * See [registerFormControl()]{@link DataField#registerFormControl} for more information.
     */
    protected _initialized$: BehaviorSubject<boolean>;
    /**
     * @ignore
     * Whether the field fulfills all of it's validators.
     */
    private _valid;
    /**
     * @ignore
     * Whether the `value` of the field changed recently. The flag is cleared when changes are send to backend.
     */
    private _changed;
    /**
     * @ignore
     * Data field subscribes this stream.
     * The data field updates it's Validators, validity and enabled/disabled according to it's behavior.
     */
    protected _update: Subject<void>;
    /**
     * @ignore
     * Data field subscribes this stream. When a `true` value is received the data field disables itself.
     * When a `false`value is received data field disables/enables itself based on it's behavior.
     */
    protected _block: Subject<boolean>;
    /**
     * @ignore
     * When a `true` value is there, the data field is disabled.
     * When a `false` value is received, data field is disabled/enabled based on it's behavior.
     */
    protected _blocked: boolean;
    /**
     * @ignore
     * Data field subscribes this stream. Sets the state of the data field to "touched" or "untouched" (`true`/`false`).
     * Validity of the data field is not checked in an "untouched" state.
     * All fields are touched before a task is finished to check their validity.
     */
    protected _touch: Subject<boolean>;
    protected _updateSubscription: Subscription;
    protected _blockSubscription: Subscription;
    protected _touchSubscription: Subscription;
    protected _formControlValueSubscription: Subscription;
    protected _myValueSubscription: Subscription;
    /**
     * @ignore
     * Appearance of dataFields, possible values - outline, standard, fill, legacy
     */
    materialAppearance: string;
    /**
     * @ignore
     * Whether the field fulfills required validator.
     */
    private _validRequired;
    /**
     * Whether invalid field values should be sent to backend.
     */
    private _sendInvalidValues;
    /**
     * Flag that is set during reverting
     */
    private _reverting;
    /**
     * Validators resolved from field validations
     */
    protected _validators: Array<ValidatorFn>;
    /**
     * Stores the last subscription to the [_initialized$]{@link AbstractDataField#_initialized$} Stream, to prevent multiple block events
     * from executing at the same time
     */
    protected _initializedSubscription: Subscription;
    /**
     * @ignore
     * Whether the changes from has been requested. The flag is cleared when changes are received from backend.
     */
    private _waitingForResponse;
    /**
     * Stores a copy of the fields layout, that can be modified by the layouting algorithm as needed
     * without affecting the base configuration.
     */
    protected _localLayout: Layout;
    /**
     * Listens for layout changes
     */
    protected layoutSubject: BehaviorSubject<Layout>;
    /**
     * Reference to rendered element
     * */
    private _input;
    /**
     * Reference to form control
     * */
    private _formControlRef;
    /**
     * change of component
     * */
    private _componentChange$;
    /**
     * @param _stringId - ID of the data field from backend
     * @param _title - displayed title of the data field from backend
     * @param initialValue - initial value of the data field
     * @param _behavior - data field behavior
     * @param _placeholder - placeholder displayed in the datafield
     * @param _description - tooltip of the datafield
     * @param _layout - information regarding the component rendering
     * @param validations
     * @param _component - component data of datafield
     * @param _parentTaskId - stringId of parent task, only defined if field is loaded using {@link TaskRefField}
     * @param _parentCaseId - stringId of parent case, only defined if field is loaded using {@link TaskRefField}
     */
    protected constructor(_stringId: string, _title: string, initialValue: T, _behavior: Behavior, _placeholder?: string, _description?: string, _layout?: Layout, validations?: Array<Validation>, _component?: Component, _parentTaskId?: string, _parentCaseId?: string);
    get stringId(): string;
    set title(title: string);
    get title(): string;
    set placeholder(placeholder: string);
    get placeholder(): string | undefined;
    set description(desc: string);
    get description(): string;
    set behavior(behavior: Behavior);
    get behavior(): Behavior;
    get value(): T;
    set value(value: T);
    get parentTaskId(): string;
    get parentCaseId(): string;
    get previousValue(): T;
    set previousValue(value: T);
    valueWithoutChange(value: T): void;
    set layout(layout: Layout);
    get layout(): Layout;
    get localLayout(): Layout;
    get disabled(): boolean;
    get initialized(): boolean;
    get initialized$(): Observable<boolean>;
    set valid(set: boolean);
    get valid(): boolean;
    set changed(set: boolean);
    get changed(): boolean;
    set block(set: boolean);
    set touch(set: boolean);
    get touch$(): Observable<boolean>;
    get component(): Component;
    set component(component: Component);
    componentChange$(): Observable<Component>;
    revertToPreviousValue(): void;
    set validRequired(set: boolean);
    get validRequired(): boolean;
    get sendInvalidValues(): boolean;
    set sendInvalidValues(value: boolean | null);
    get waitingForResponse(): boolean;
    set waitingForResponse(value: boolean);
    update(): void;
    valueChanges(): Observable<T>;
    set reverting(set: boolean);
    get reverting(): boolean;
    focus(): void;
    get input(): ElementRef;
    set input(value: ElementRef);
    get formControlRef(): FormControl;
    set formControlRef(formControl: FormControl);
    getUpdateOnStrategy(): UpdateOnStrategy;
    /**
     * This function resolve type of component for HTML
     * @returns type of component in string
     */
    getComponentType(): string;
    abstract getTypedComponentType(): string;
    destroy(): void;
    registerFormControl(formControl: FormControl): void;
    disconnectFormControl(): void;
    protected updateFormControlState(formControl: FormControl): void;
    protected subscribeToInnerSubjects(formControl: FormControl): void;
    /**
     * Computes whether the FormControl si valid.
     * @param formControl check form control
     */
    protected _determineFormControlValidity(formControl: FormControl): boolean;
    /**
     * Creates Validator objects based on field `behavior`. Only the `required` behavior is resolved by default.
     * Required is resolved as `Validators.required`.
     * If you need to resolve additional Validators or need a different resolution for the `required` Validator override this method.
     *
     * See {@link Behavior} for information about data field behavior.
     *
     * See {@link ValidatorFn} and {@link Validators} for information about Validators.
     *
     * Alternatively see [Form Validation guide]{@link https://angular.io/guide/form-validation#reactive-form-validation} from Angular.
     */
    protected resolveFormControlValidators(): Array<ValidatorFn>;
    replaceValidations(validations: Array<Validation>): void;
    clearValidators(): void;
    protected resolveValidations(): Array<ValidatorFn>;
    /**
     * Determines if two values of the data field are equal.
     *
     * `a === b` equality is used by default. If you want different behavior override this method.
     * @param a - first compared value
     * @param b - second compared value
     */
    protected valueEquality(a: T, b: T): boolean;
    /**
     * Updates the state of this data field model object.
     * @param change - object describing the changes - returned from backend
     *
     * Also see {@link ChangedFields}.
     */
    applyChange(change: Change): void;
    resolveAppearance(config: ConfigurationService): void;
    resolvePrevValue(value: T): void;
    protected calculateValidity(forValidRequired: boolean, formControl: FormControl): boolean;
    isInvalid(formControl: FormControl): boolean;
    /**
     * Copies the layout settings into the local layout.
     */
    resetLocalLayout(): void;
}
