import EventEmitter from "jenesius-event-emitter";
import FormEvent from "./FormEvent";
import { CompareItem } from "../utils/compare-changes";
import DependencyQueue from "./DependencyQueue";
import { FormAvailability, FormSetValuesOptions, OnFunction } from "../types";
/**
 * Main principe : GMN
 * G - Grand
 * M - Merge
 * N - Notify
 * Важно помнить про данный принцип. Любой последующие этап не может быть вызван без предыдущего. Это значит, что перед
 * Merge(M) всегда должен быть выполнен и Grand(G), для Notify(N) всегда должны быть выполнены M и G соответственно.
 */
/**
 * @description Необходимо пометить один принцип: данные передаваемые в CompareItem нужно только для сохранения изменений.
 * Всё состояние формы лежит сугубо в форме.
 * */
export default class Form extends EventEmitter implements FormDependence {
    #private;
    static PROVIDE_NAME: string;
    static EVENT_VALUE: string;
    static EVENT_AVAILABLE: string;
    /**
     * @description Событие срабатывает, когда форма была изменена или наоборот очищена. В таком случае отдаёт true/false
     * в каком состоянии находится форма.
     * */
    static EVENT_CHANGED: string;
    static getParentForm(): Form | undefined;
    static getEventValueByName(name: string): string;
    static getEventAvailabilityByName(name: string): string;
    static restoreFullName<T extends {
        name?: string;
        parent?: Form;
    }>(elem: T): string;
    static getTargetName<T extends {
        name?: string;
        parent?: any;
        autonomic?: boolean;
    }>(elem: T): string;
    /**
     * @description Name of Entity.
     * */
    name?: string;
    /**
     * @description Класс является автономным, если не указан родитель или если свойство #autonomic установлено в true
     */
    get autonomic(): boolean;
    set autonomic(value: boolean);
    get changes(): any;
    get values(): any;
    /**
     * @description Чистые значения формы. Которые изменяются при помощи setValues без опции change.
     * */
    get pureValues(): any;
    get TEST_PURE_VALUE(): {};
    private set values(value);
    dependencies: DependencyQueue<import("./DependencyQueue").DependencyItem & Record<string, any>>;
    get parent(): Form | undefined;
    set parent(parent: Form | undefined);
    /**
     * !!!!!!!!!!!
     * CONSTRUCTOR
     * !!!!!!!!!!!
     */
    constructor(params?: Partial<FormParams>);
    setValues(values: any, options?: Partial<FormSetValuesOptions>): void;
    /**
     * @description Метод для принятия изменения и переноса их в pureValues
     * */
    acceptChanges(name?: string): void;
    /**
     * @description Метод проецирует цепочку изменений на форму.
     * @param compareResult {CompareItem[]} массив изменений, которые необходимо спроецировать
     * @param isChange {Boolean} флаг, указывающий какого типа будут изменения. В случае, если true, то изменения
     * проецируются только на changes, в противно случае: проецируются на values, но стирают часть changes, которая была
     * затронута.
     * */
    private mergeValues;
    getValueByName(name: string): any;
    /**
     * @description Method using for change form's values. Current function is mnemonic for
     * *form.setValues(value, {change: true})* and just using for shortest form.
     * */
    change(data: any, options?: Partial<Omit<FormSetValuesOptions, "change">>): void;
    /**
     * @description Return true if form includes changes, otherwise false.
     * */
    get changed(): boolean;
    subscribe(element: any): () => void;
    unsubscribe(element: any): void;
    /**
     *
     * @param name - tracked field
     * @param callback
     * @description The method fires every time the given field has been changed.
     */
    oninput(name: string, callback: (newValue: any) => void): () => void;
    onvalue(callback: (data: CompareItem) => void): () => void;
    /**
     * @description Отправляет событие. Данный метод используется только для запуска события для себя и дочерних элементов.
     * Наша система построена так, что бы все значения идут от родителя к дочернему элементу (values, changes, event, other..)
     * */
    dispatchEvent<T extends FormEvent>(event: T): void;
    cleanValues(values?: any): void;
    /**
     * @description Отменяет изменения для переданного поля. Данная функция работает только с объектом changes и не
     * затрагивает объект values. Если в дочернее свойство объекта changes является объектом, но при этом количество
     * дочерних ключей равно 0, данной свойство полностью удаляется из объекта changes.
     * @param {String} fieldName Имя поля, для которого необходимо убрать статус 'changed'. В данном случае, изменение
     * для данного поля будет стёрто из объекта changes.
     * */
    cleanChangesByField(fieldName: string): void;
    /**
     * @description Метод используется для очистки changes. Иными словами происходит просто очистка всех changes.
     * */
    revert(): undefined;
    /**
     * @description Method check field on changed status. Return true if changes include some values for provided fieldName.
     * */
    checkFieldChange(fieldName: string): boolean;
    /**
     * @description Method using for clear field. Dont set NULL. Remove field from values.
     * @example
     * { address: { city: 'Some' }, name: 'jack' } clearField('address')
     * {name: 'jack'}
     * */
    cleanField(fieldName: string): void;
    /**
     * FRONT FORM LEVEL
     * */
    static EVENT_VERSION: string;
    set version(data: any);
    get version(): any;
    onversion(callback: OnFunction<Form['version']>): () => void;
    static EVENT_ID: string;
    set id(data: any);
    get id(): any;
    onid(callback: OnFunction<Form['id']>): () => void;
    static EVENT_WAIT: string;
    set wait(v: boolean);
    get wait(): boolean;
    static EVENT_READ: string;
    /**
     * @description Method takes read functions from all children elements, and
     * run it
     */
    get read(): FunctionHandleData;
    set read(callback: FunctionHandleData);
    static EVENT_SAVE: string;
    /**
     * @description The same with read. After saving run cleanChanges.
     */
    get save(): FunctionHandleData;
    set save(callback: FunctionHandleData);
    set isAvailable(v: boolean);
    get isAvailable(): boolean;
    get disabled(): boolean;
    get enabled(): boolean;
    onavailable(callback: (disabled: boolean) => any): any;
    onavailable(fieldName: string, callback: (disabled: boolean) => any): any;
    disable(names?: string | string[]): void;
    enable(names?: string | string[]): void;
    /**
     * Здесь принцип отличается от setValues. Он не является оптимизированным, однако является 100% рабочим.
     * В будущем будем оптимизировать.
     * Мы сперва строем выходной объект availability, а затем идём по dependencies и уведомляем их, если они были изменены.
     * Далее передаём объект в dispatchEvent.
     * */
    available(type: boolean, names: string[]): void;
    get TEST_PURE_AVAILABILITIES(): FormAvailability;
    /**
     * @description Вернёт true, если переданное поле является disabled.
     * */
    checkFieldDisable(fieldName: string): boolean;
    /**
     * @description Method using for validate form and all child items.
     * */
    validate(): boolean;
}
interface FormParams {
    name: string;
    provide: boolean;
    parent: Form | null | false;
    /**
     * @description The form will be self-contained. They want and will have the opportunity to receive higher education
     * from their parents, however values, changes, enabling and disabling will be stored inside this form.
     */
    autonomic: boolean;
}
interface FormDependence {
    change(data: any): void;
    setValues(data: any): void;
}
export declare type FunctionHandleData = (...params: any) => Promise<any> | any | void;
export {};
