import { OnDestroy } from '@angular/core';
import { Filter } from '../../../filter/models/filter';
import { CaseResourceService } from '../../../resources/engine-endpoint/case-resource.service';
import { CaseTreeNode } from './model/case-tree-node';
import { TreeCaseViewService } from '../tree-case-view.service';
import { TaskResourceService } from '../../../resources/engine-endpoint/task-resource.service';
import { LoggerService } from '../../../logger/services/logger.service';
import { ImmediateData } from '../../../resources/interface/immediate-data';
import { Case } from '../../../resources/interface/case';
import { ProcessService } from '../../../process/process.service';
import { SideMenuService } from '../../../side-menu/services/side-menu.service';
import { Observable, Subject } from 'rxjs';
import { Page } from '../../../resources/interface/page';
import { TranslateService } from '@ngx-translate/core';
import { NestedTreeControl } from '@angular/cdk/tree';
import { MatTreeNestedDataSource } from '@angular/material/tree';
import { CaseGetRequestBody } from '../../../resources/interface/case-get-request-body';
import { CaseTreePath } from './model/case-tree-path';
import { ExpansionTree } from './model/expansion-tree';
import { ResultWithAfterActions } from '../../../utility/result-with-after-actions';
import { TreeCaseViewConfiguration } from './model/tree-case-view-configuration';
import * as i0 from "@angular/core";
export declare class CaseTreeService implements OnDestroy {
    protected _caseResourceService: CaseResourceService;
    protected _treeCaseViewService: TreeCaseViewService;
    protected _taskResourceService: TaskResourceService;
    protected _logger: LoggerService;
    protected _processService: ProcessService;
    protected _sideMenuService: SideMenuService;
    protected _translateService: TranslateService;
    protected _optionSelectorComponent: any;
    protected _treeConfiguration: TreeCaseViewConfiguration;
    static readonly DEFAULT_PAGE_SIZE = 50;
    protected _currentNode: CaseTreeNode;
    private _rootNodesFilter;
    private readonly _treeDataSource;
    private readonly _treeControl;
    private _treeRootLoaded$;
    private _rootNode;
    private _showRoot;
    /**
     * Weather the tree is eager loaded or not.
     *
     * Defaults to `false`.
     *
     * It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
     */
    private _isEagerLoaded;
    /**
     * string id of the case, that is currently being reloaded, `undefined` if no case is currently being reloaded
     */
    private _reloadedCaseId;
    constructor(_caseResourceService: CaseResourceService, _treeCaseViewService: TreeCaseViewService, _taskResourceService: TaskResourceService, _logger: LoggerService, _processService: ProcessService, _sideMenuService: SideMenuService, _translateService: TranslateService, _optionSelectorComponent: any, _treeConfiguration: TreeCaseViewConfiguration);
    ngOnDestroy(): void;
    set rootFilter(filter: Filter);
    get dataSource(): MatTreeNestedDataSource<CaseTreeNode>;
    get treeControl(): NestedTreeControl<CaseTreeNode>;
    get currentNode(): CaseTreeNode;
    /**
     * Emits a value whenever a new root node Filter is set.
     *
     * `true` is emitted if the root node was successfully loaded. `false` otherwise.
     *
     * On subscription emits the last emitted value (if any) to the subscriber.
     */
    get treeRootLoaded$(): Observable<boolean>;
    protected get _currentCase(): Case | undefined;
    /**
     * @returns an `Observable` of the {@link LoadingEmitter} representing the loading state of the root node.
     * Returns `undefined` if the tree has not yet been initialized.
     *
     * Wait for an emission on the [treeRootLoaded$]{@link CaseTreeService#treeRootLoaded$} stream before getting this Observable.
     *
     * The first value emitted by the Observable is `false`, when the tree finishes initializing.
     */
    get rootNodeLoading$(): Observable<boolean> | undefined;
    /**
     * @returns an `Observable` of the {@link LoadingEmitter} representing whether the root node is currently
     * in the process of adding a new child node or not.
     * Returns `undefined` if the tree has not yet been initialized.
     *
     * Wait for an emission on the [treeRootLoaded$]{@link CaseTreeService#treeRootLoaded$} stream before getting this Observable.
     *
     * The first value emitted by the Observable is `false`, when the tree finishes initializing.
     */
    get rootNodeAddingChild$(): Observable<boolean> | undefined;
    /**
     * Weather the tree is eager loaded or not.
     *
     * Defaults to `false`.
     *
     * It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
     */
    get isEagerLoaded(): boolean;
    /**
     * Weather the tree is eager loaded or not.
     *
     * Defaults to `false`.
     *
     * It is not recommended to eager load large trees as each node sends a separate backend request to load its data.
     *
     * @param eager the new setting for eager loading
     */
    set isEagerLoaded(eager: boolean);
    /**
     * Loads and populates the topmost level of the tree.
     *
     * The displayed cases are determined by this object's [rootFilter]{@link CaseTreeService#rootFilter}.
     *
     * Cases are loaded one page at a time and the tree is refreshed after each page.
     * [finishedLoadingFirstLevel$]{@link CaseTreeService#treeRootLoaded$}
     * will emit `true` once the last page loads successfully.
     * `false` will be emitted if any of the requests fail.
     */
    protected loadTreeRoot(): void;
    /**
     * Adds the loaded tree root to the display based on the setting.
     * @param showRoot whether the root of the tree should be displayed in the tree or not.
     * If the root is not displayed it's children will be displayed on the first level.
     * @returns an Observable that emits when the tree finishes initialization.
     */
    initializeTree(showRoot: boolean): Observable<void>;
    /**
     * Notifies the parent TreeCaseView that a case was clicked in the tree and it's Task should be displayed
     */
    changeActiveNode(node: CaseTreeNode | undefined): void;
    /**
     * Toggles the expansion state of a node
     * @param node the {@link CaseTreeNode} who's content should be toggled
     */
    toggleNode(node: CaseTreeNode): void;
    /**
     * Expands the target node in the tree and reloads it's children if they are marked as dirty
     * @param node the {@link CaseTreeNode} that should be expanded
     * @returns emits `true` if the node is expanded and `false` if not. If the expansion causes more node expansions
     * (e.g. eager loaded tree) then, the Observable emits after all the subtree expansions complete.
     */
    protected expandNode(node: CaseTreeNode): Observable<boolean>;
    /**
     * Checks whether dirty children need to be reloaded and reloads them if needed.
     * @param node the {@link CaseTreeNode} who's children are updated
     * @returns emits when loading finishes
     */
    protected updateNodeChildren(node: CaseTreeNode): Observable<void>;
    /**
     * Loads every page of children from the given number and updates the existing children.
     *
     * Missing nodes are removed. Existing nodes are marked as dirty. New nodes are added.
     *
     * Nodes are returned in their insertion order.
     * @param node the {@link CaseTreeNode} who's children are updated
     * @param pageNumber the number of the first page that should be loaded. All following pages are loaded as well
     * @returns next is emitted when loading of all pages completes (regardless of the outcome)
     */
    protected updatePageOfChildren(node: CaseTreeNode, pageNumber: number): Observable<void>;
    /**
     * Updates the children of the given {@link CaseTreeNode} with [Cases]{@link Case} from the provided {@link Page}.
     * @param node the {@link CaseTreeNode} who's children are updated
     * @param page the {@link Page} that contains the updated children
     */
    protected updateCurrentChildrenWithNewPage(node: CaseTreeNode, page: Page<Case>): void;
    /**
     * @param node the {@link CaseTreeNode} who's children the {@link Filter} should return
     * @returns a request body that finds all child cases of the given `node`.
     * Returns `undefined` if the provided `node` doesn't contain enough information to create the request body.
     */
    protected createChildRequestBody(node: CaseTreeNode): CaseGetRequestBody;
    /**
     * Adds a child to the root node.
     *
     * Useful if you are using the layout where the root node is hidden.
     * @returns emits `true` if the child was successfully added, `false` if not
     */
    addRootChildNode(): Observable<boolean>;
    /**
     * Adds a new child node to the given node based on the properties of the node's case
     * @returns emits `true` if the child was successfully added, `false` if not
     */
    addChildNode(clickedNode: CaseTreeNode): Observable<boolean>;
    /**
     * Creates a new case and adds it to the children of the specified node
     * @param processIdentifier identifier of the process that should be created
     * @param clickedNode the node that is the parent of the new case
     * @param operationResult the result of the operation will be emitted into this stream when the operation completes
     */
    protected createAndAddChildCase(processIdentifier: string, clickedNode: CaseTreeNode, operationResult: Subject<boolean>): void;
    /**
     * Updates the tree after adding a new child
     * @param clickedNode the parent node
     * @param newCaseRefValue the new value of the parent node's case ref
     * @param operationResult the result of the operation will be emitted into this stream when the operation completes
     */
    protected updateTreeAfterChildAdd(clickedNode: CaseTreeNode, newCaseRefValue: Array<string>, operationResult: Subject<boolean>): void;
    /**
     * removes the provided non-root node if the underlying case allows it.
     *
     * The underlying case is removed from the case ref of it's parent element with the help from the `remove`
     * operation provided by case ref itself.
     * @param node the node that should be removed from the tree
     */
    removeNode(node: CaseTreeNode): void;
    /**
     * Expands all nodes in the tree dictated by the argument.
     *
     * @param path nodes that should be expanded along with their path from the root node
     */
    expandPath(path: CaseTreePath): void;
    /**
     * Transforms a {@Link CaseTreePath} object into an {@link ExpansionTree} object.
     * The result has all the common paths merged into single branches of the resulting tree structure.
     *
     * @param paths nodes that should be expanded along with their path from the root node
     * @returns an {@link ExpansionTree} equivalent to the provided {@link CaseTreePath}
     */
    protected convertPathToExpansionTree(paths: CaseTreePath): ExpansionTree;
    /**
     * Recursively expands all nodes from the provided array of nodes, that appear in the top level of the {@link ExpansionTree} object.
     *
     * @param levelNodes nodes from which the expansion should start
     * @param targets a tree structure representing the nodes that are to be expanded recursively.
     * The top level nodes are expanded first, from the provided `levelNodes`.
     */
    protected expandLevel(levelNodes: Array<CaseTreeNode>, targets: ExpansionTree): void;
    /**
     * Deletes the subtrees rooted at the nodes that are present in the parent node's child case ref values,
     * but are no longer present in the new value
     * @param parentNode an inner node of the tree that had some of it's children removed
     * @param newCaseRefValue the new value of the parent node's case ref
     */
    protected deleteRemovedNodes(parentNode: CaseTreeNode, newCaseRefValue: Array<string>): void;
    /**
     * Deselects the currently selected node if it is a descendant of the provided node
     * @param node the node who's descendants should be deselected
     */
    protected deselectNodeIfDescendantOf(node: CaseTreeNode): void;
    /**
     * Performs a backend call on the given case, and sets the value of the case ref field in the transition defined by
     * [CASE_REF_TRANSITION]{@link TreePetriflowIdentifiers#CASE_REF_TRANSITION}.
     * @param caseId string ID of the case that should have it's tree case ref set
     * @param newCaseRefValue the new value of the case ref field
     */
    private performCaseRefCall;
    /**
     * Performs an update after adding or removing a node from the tree.
     *
     * If only one node was added adds it into the tree
     *
     * If only one node was removed removes it from the tree
     *
     * Otherwise collapses the affected node and marks it's children as dirty
     *
     * @param affectedNode node that had it's children changed
     * @param newCaseRefValue new value of the caseRef field returned by backend
     * @returns an `Observable` that emits an object with the [result]{@link ResultWithAfterActions#result} attribute set to `true` if
     * the update completes successfully and `false` otherwise.
     */
    private updateNodeChildrenFromChangedFields;
    /**
     * Adds a new child node to the `affectedNode` by adding the last Case from the `newCaseRefValue`
     * @param affectedNode the node in the tree that had a child added - the parent node
     * @param caseRefField the case ref field of the affected node
     * @param newCaseRefValue the new value of the case ref field in the node
     * @returns an `Observable` that emits `true` if a node was successfully added, `false` otherwise.
     */
    protected processChildNodeAdd(affectedNode: CaseTreeNode, caseRefField: ImmediateData, newCaseRefValue: Array<string>): Observable<ResultWithAfterActions<boolean>>;
    /**
     * Adds a new child node to the target parent node.
     * @param parentNode the nodes whose child should be added
     * @param childCase the child case
     * @returns the newly added node
     */
    protected pushChildToTree(parentNode: CaseTreeNode, childCase: Case): CaseTreeNode;
    /**
     * Removes the deleted node from the children of the `affectedNode`
     * @param affectedNode the node in the tree that had it's child removed
     * @param caseRefField the case ref field of the affected node
     * @param newCaseRefValues the new value of the case ref field in the node
     * @returns an `Observable` that emits `true` when the remove operation completes.
     */
    protected processChildNodeRemove(affectedNode: CaseTreeNode, caseRefField: ImmediateData, newCaseRefValues: Set<string>): Observable<ResultWithAfterActions<boolean>>;
    /**
     * @ignore
     * Forces a rerender of the tree content
     */
    private refreshTree;
    /**
     * Reloads the currently selected case node. The {@link Case} object held in the {@link CaseTreeNode} instance is not replaced,
     * but the new Case is `Object.assign`-ed into it. This means that the reference to the Case instance is unchanged but references
     * to all it's non-primitive attributes are changed.
     *
     * If a reload of the current node is initiated before the previous one completed, the new one is ignored.
     *
     * If the currently selected case changed before a response from backend was received the response is ignored.
     *
     * Note that the parent node, nor the child nodes are reloaded.
     */
    protected reloadCurrentCase(): void;
    /**
     * Determines if anny of the case attributes that are visible on the tree changed.
     * @param oldCase the previous version of the Case object, that is currently displayed on the tree
     * @param newCase the new version of the Case object, that should replace the old one
     */
    private determineCaseUpdate;
    static ɵfac: i0.ɵɵFactoryDeclaration<CaseTreeService, [null, null, null, null, null, null, null, { optional: true; }, { optional: true; }]>;
    static ɵprov: i0.ɵɵInjectableDeclaration<CaseTreeService>;
}
