import * as _angular_core from '@angular/core';
import { OnInit, OnDestroy, PipeTransform } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Node, Edge, NgxGraphZoomOptions } from '@swimlane/ngx-graph';
import { DialogService } from '@myrmidon/ngx-mat-tools';
import { LinkedNodeFilter, LinkedLiteralFilter, TripleFilter, NodeSourceType, GraphService, UriNode } from '@myrmidon/cadmus-api';
import { FormControl, FormGroup, FormBuilder } from '@angular/forms';
import { PageEvent } from '@angular/material/paginator';
import { GraphNodeLookupService } from '@myrmidon/cadmus-graph-ui';

interface PagedTripleFilter extends TripleFilter {
    pageNumber: number;
    pageSize: number;
}
interface PagedLinkedLiteralFilter extends LinkedLiteralFilter {
    pageNumber: number;
    pageSize: number;
}
interface PagedLinkedNodeFilter extends LinkedNodeFilter {
    pageNumber: number;
    pageSize: number;
}
/**
 * Essential graph walker data.
 */
interface WalkerData {
    originId: string;
    customColor?: string;
    hidden?: boolean;
}
/**
 * Graph walker widget data, i.e. a node or a property group.
 */
interface WalkerWidgetData extends WalkerData {
    selected?: boolean;
    expanded?: boolean;
    error?: string;
}
/**
 * Graph walker node data.
 * ID: "N" + nodeid (e.g. "N3").
 */
interface WalkerNodeData extends WalkerWidgetData {
    uri: string;
    sourceType: NodeSourceType;
    isClass?: boolean;
    sid?: string;
    tag?: string;
    outFilter: PagedTripleFilter;
    inFilter: PagedTripleFilter;
    outTotal?: number;
    inTotal?: number;
}
/**
 * Graph walker property group data.
 * ID: "P" + propertyid + "N" + source nodeid ("P2N3").
 */
interface WalkerPropData extends WalkerWidgetData {
    uri: string;
    outFilter: PagedLinkedNodeFilter;
    inFilter: PagedLinkedNodeFilter;
    litFilter: PagedLinkedLiteralFilter;
    outTotal?: number;
    inTotal?: number;
    litTotal?: number;
}
/**
 * Graph walker literal node data.
 * ID: "L" + tripleid (e.g. "L5").
 */
interface WalkerLitData extends WalkerWidgetData {
    value: string;
    type?: string;
    language?: string;
    number?: number;
}
/**
 * The total counts of items fetched by each children graph nodes filter.
 */
interface NodeChildTotals {
    pOut: number;
    pIn: number;
    pLit: number;
    nOut: number;
    nIn: number;
}
/**
 * Graph walker.
 * This class encapsulates data used for interactively exploring a graph
 * starting from a designated origin node.
 */
declare class GraphWalker {
    private _graphService;
    private readonly _nodes$;
    private readonly _edges$;
    private readonly _loading$;
    private readonly _error$;
    private _rootNode?;
    private readonly _selectedNode$;
    private readonly _pOutFilter$;
    private readonly _pInFilter$;
    private readonly _pLitFilter$;
    private readonly _nOutFilter$;
    private readonly _nInFilter$;
    private readonly _childTotals$;
    /**
     * The page size. Default is 10.
     */
    pageSize: number;
    /**
     * Max length of literal value to show. Default is 30.
     */
    maxLiteralLen: number;
    /**
     * The nodes of the walker graph, which can represent nodes, literals,
     * or property groups. You can easily determine the type of each node
     * by looking at the first character of its id (N=node, L=literal,
     * P=property).
     */
    get nodes$(): Observable<Node[]>;
    /**
     * The edges connecting nodes.
     */
    get edges$(): Observable<Edge[]>;
    /**
     * True if the walker is loading data.
     */
    get loading$(): Observable<boolean>;
    /**
     * The last error occurred in communicating with the server, if any.
     */
    get error$(): Observable<string | null>;
    /**
     * The selected node. Only one node at a time can be selected.
     */
    get selectedNode$(): Observable<Node | null>;
    /**
     * The outbound linked nodes filter for the selected P node.
     */
    get pOutFilter$(): Observable<PagedLinkedNodeFilter | null>;
    /**
     * The inbound linked nodes filter for the selected P node.
     */
    get pInFilter$(): Observable<PagedLinkedNodeFilter | null>;
    /**
     * The literal linked nodes filter for the selected P node.
     */
    get pLitFilter$(): Observable<PagedLinkedLiteralFilter | null>;
    /**
     * The outbound triples filter for the selected N node.
     */
    get nOutFilter$(): Observable<PagedTripleFilter | null>;
    /**
     * The inbound triples filter for the selected N node.
     */
    get nInFilter$(): Observable<PagedTripleFilter | null>;
    /**
     * The total items fetched for each filter of the selected node.
     */
    get childTotals$(): Observable<NodeChildTotals>;
    constructor(_graphService: GraphService);
    getSelectedNode(): Node | null;
    private toggleLoading;
    private setError;
    private buildNodeId;
    /**
     * Get the numeric ID of the data node being the source of the graph node
     * with the specified ID.
     *
     * @param id The graph node ID (...N + its data node numeric ID)
     * @returns The data node numeric ID.
     */
    private getNodeNumericId;
    private getPredicateNumericId;
    private buildEdgeId;
    private buildPropertyId;
    private buildLiteralId;
    private scale;
    private addEdgeIfAbsent;
    private resetFilters;
    /**
     * Select the specified node. This also implies updating all the current
     * filters, which depend on the selected node.
     *
     * @param id The node ID or null to deselect the selected node.
     */
    selectNode(id: string | null): void;
    /**
     * Reset the graph setting its origin to the specified node.
     *
     * @param id The ID of the origin node to start from ("root origin").
     */
    reset(id: number): void;
    /**
     * Get the source and target graph nodes IDs from the specified edge ID.
     *
     * @param edgeId The ID of the edge graph node.
     * @returns IDs of the source and target graph nodes.
     */
    private getEdgeEndIds;
    /**
     * Remove all the nodes with the specified origin node ID.
     *
     * @param originId The ID of the origin graph node.
     * @param nodes The nodes array to remove nodes from.
     * @param removedIds The IDs of all the removed nodes.
     */
    private removeDescendantNodes;
    /**
     * Remove all the children graph nodes of the specified origin graph node.
     *
     * @param originId The ID of the origin graph node.
     * @param nodes The nodes array to remove nodes from.
     * @param edges The edges array to remove edges from.
     */
    private removeChildren;
    /**
     * Build a new graph node representing a property.
     *
     * @param sourceId The source node ID.
     * @param group The triple group emitting this node.
     * @returns A new graph node.
     */
    private buildPropertyNode;
    /**
     * Expand the specified node, by loading its property groups.
     *
     * @param node The node to expand.
     * @param outFilter The properties to update for the output filter.
     * @param inFilter The properties to update for the input filter.
     */
    expandNode(node: Node, outFilter?: Partial<PagedTripleFilter> | null, inFilter?: Partial<PagedTripleFilter> | null): void;
    /**
     * Expand the selected node, by loading its property groups.
     *
     * @param outFilter The properties to update for the output filter.
     * @param inFilter The properties to update for the input filter.
     */
    expandSelectedNode(outFilter?: Partial<PagedTripleFilter> | null, inFilter?: Partial<PagedTripleFilter> | null): void;
    private buildLiteralLabel;
    private buildNonLiteralNode;
    private buildLiteralNode;
    /**
     * Expand the currently selected properties group node, by loading its
     * outbound nodes, inbound nodes, and literal nodes.
     *
     * @param node The property group node to expand.
     * @param outFilter The properties to update for the outbound nodes filter.
     * @param inFilter The properties to update for the inbound nodes filter.
     * @param litFilter The properties to update for the literal nodes filter.
     */
    expandProperty(node: Node, outFilter?: Partial<PagedLinkedNodeFilter> | null, inFilter?: Partial<PagedLinkedNodeFilter> | null, litFilter?: Partial<PagedLinkedLiteralFilter> | null): void;
    /**
     * Expand the currently selected properties group node, by loading its
     * outbound nodes, inbound nodes, and literal nodes. If there is no
     * selection, or the selected node is not a properties group node, nothing
     * is done.
     *
     * @param outFilter The properties to update for the outbound nodes filter.
     * @param inFilter The properties to update for the inbound nodes filter.
     * @param litFilter The properties to update for the literal nodes filter.
     */
    expandSelectedProperty(outFilter?: Partial<PagedLinkedNodeFilter> | null, inFilter?: Partial<PagedLinkedNodeFilter> | null, litFilter?: Partial<PagedLinkedLiteralFilter> | null): void;
    /**
     * Toggle the specified node by expanding or collapsing it.
     *
     * @param node The node to toggle.
     */
    toggleNode(node: Node): void;
}

/**
 * Graph walker component. This starts from a given node, and let users
 * walk along edges to discover new nodes.
 */
declare class GraphWalkerComponent implements OnInit, OnDestroy {
    private _dialog;
    private _sub?;
    private readonly _walker;
    /**
     * The root origin node ID.
     */
    readonly nodeId: _angular_core.InputSignal<number>;
    /**
     * True if user can pick a node from the graph.
     */
    readonly canPick: _angular_core.InputSignal<boolean | undefined>;
    /**
     * True if user can move to the source of a picked node when
     * shift-clicking it.
     */
    readonly canMoveToSource: _angular_core.InputSignal<boolean | undefined>;
    /**
     * Emitted when a graph node is picked by user.
     */
    readonly nodePick: _angular_core.OutputEmitterRef<Node>;
    /**
     * Emitted when the user requests to move to the source of a picked node.
     */
    readonly moveToSource: _angular_core.OutputEmitterRef<Node>;
    nodes$: Observable<Node[]>;
    edges$: Observable<Edge[]>;
    loading$: Observable<boolean>;
    error$: Observable<string | null>;
    selectedNode$: Observable<Node | null>;
    pOutFilter$: Observable<PagedLinkedNodeFilter | null>;
    pInFilter$: Observable<PagedLinkedNodeFilter | null>;
    pLitFilter$: Observable<PagedLinkedLiteralFilter | null>;
    nOutFilter$: Observable<PagedTripleFilter | null>;
    nInFilter$: Observable<PagedTripleFilter | null>;
    childTotals$: Observable<NodeChildTotals>;
    update$: Subject<boolean>;
    center$: Subject<boolean>;
    zoomToFit$: Subject<NgxGraphZoomOptions>;
    constructor(graphService: GraphService, _dialog: DialogService);
    ngOnInit(): void;
    ngOnDestroy(): void;
    onNodeSelect(node: Node): void;
    private reset;
    onReset(): void;
    onNodeDblClick(node: Node): void;
    onPOutFilterChange(filter: PagedLinkedNodeFilter): void;
    onPInFilterChange(filter: PagedLinkedNodeFilter): void;
    onPLitFilterChange(filter: PagedLinkedLiteralFilter): void;
    onNOutFilterChange(filter: PagedTripleFilter): void;
    onNInFilterChange(filter: PagedTripleFilter): void;
    pickSelectedNode(event: MouseEvent): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<GraphWalkerComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<GraphWalkerComponent, "cadmus-graph-walker", never, { "nodeId": { "alias": "nodeId"; "required": false; "isSignal": true; }; "canPick": { "alias": "canPick"; "required": false; "isSignal": true; }; "canMoveToSource": { "alias": "canMoveToSource"; "required": false; "isSignal": true; }; }, { "nodePick": "nodePick"; "moveToSource": "moveToSource"; }, never, never, true, never>;
}

/**
 * Linked literal filter.
 */
declare class LinkedLiteralFilterComponent {
    lookupService: GraphNodeLookupService;
    private _graphService;
    /**
     * True if this component is disabled.
     */
    readonly disabled: _angular_core.InputSignal<boolean | undefined>;
    /**
     * True if this component should show a pager.
     */
    readonly hasPager: _angular_core.InputSignal<boolean | undefined>;
    /**
     * The total number of triples returned from the last
     * page fetch operation. Used when hasPager is true.
     */
    readonly total: _angular_core.InputSignal<number>;
    /**
     * The filter.
     */
    readonly filter: _angular_core.ModelSignal<PagedLinkedLiteralFilter>;
    pageNumber: FormControl<number>;
    pageSize: FormControl<number>;
    litPattern: FormControl<string | null>;
    litType: FormControl<string | null>;
    litLanguage: FormControl<string | null>;
    minLitNumber: FormControl<number | null>;
    maxLitNumber: FormControl<number | null>;
    subj: FormControl<UriNode | null>;
    pred: FormControl<UriNode | null>;
    form: FormGroup;
    constructor(formBuilder: FormBuilder, lookupService: GraphNodeLookupService, _graphService: GraphService);
    private updateForm;
    private getFilter;
    onSubjectNodeChange(node: unknown): void;
    onPredicateNodeChange(node: unknown): void;
    onPageChange(page: PageEvent): void;
    reset(): void;
    apply(): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<LinkedLiteralFilterComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<LinkedLiteralFilterComponent, "cadmus-walker-linked-literal-filter", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hasPager": { "alias": "hasPager"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; }, { "filter": "filterChange"; }, never, never, true, never>;
}

/**
 * Linked non-literal node filter.
 */
declare class LinkedNodeFilterComponent {
    lookupService: GraphNodeLookupService;
    private _graphService;
    /**
     * True if this component is disabled.
     */
    readonly disabled: _angular_core.InputSignal<boolean | undefined>;
    /**
     * True if this component should show a pager.
     */
    readonly hasPager: _angular_core.InputSignal<boolean>;
    /**
     * The total number of nodes returned from the last
     * page fetch operation. Used when hasPager is true.
     */
    readonly total: _angular_core.InputSignal<number>;
    /**
     * The filter.
     */
    readonly filter: _angular_core.ModelSignal<PagedLinkedNodeFilter>;
    otherNodeId: number;
    predicateId: number;
    isObject: boolean;
    pageNumber: FormControl<number>;
    pageSize: FormControl<number>;
    uid: FormControl<string | null>;
    isClass: FormControl<boolean | null>;
    tag: FormControl<string | null>;
    label: FormControl<string | null>;
    sourceType: FormControl<NodeSourceType | null>;
    sid: FormControl<string | null>;
    isSidPrefix: FormControl<boolean>;
    classes: FormControl<UriNode[]>;
    form: FormGroup;
    constructor(formBuilder: FormBuilder, lookupService: GraphNodeLookupService, _graphService: GraphService);
    private updateForm;
    private getFilter;
    onPageChange(page: PageEvent): void;
    onClassAdd(node: unknown): void;
    onClassRemove(node: UriNode): void;
    reset(): void;
    apply(): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<LinkedNodeFilterComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<LinkedNodeFilterComponent, "cadmus-walker-linked-node-filter", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hasPager": { "alias": "hasPager"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; }, { "filter": "filterChange"; }, never, never, true, never>;
}

/**
 * Triples filter.
 */
declare class TripleFilterComponent {
    lookupService: GraphNodeLookupService;
    private _graphService;
    /**
     * True if this component is disabled.
     */
    readonly disabled: _angular_core.InputSignal<boolean>;
    /**
     * True if this component should show a pager.
     */
    readonly hasPager: _angular_core.InputSignal<boolean>;
    /**
     * The total number of triples returned from the last
     * page fetch operation. Used when hasPager is true.
     */
    readonly total: _angular_core.InputSignal<number>;
    /**
     * The filter.
     */
    readonly filter: _angular_core.ModelSignal<PagedTripleFilter>;
    pageNumber: FormControl<number>;
    pageSize: FormControl<number>;
    litPattern: FormControl<string | null>;
    litType: FormControl<string | null>;
    litLanguage: FormControl<string | null>;
    minLitNumber: FormControl<number | null>;
    maxLitNumber: FormControl<number | null>;
    subj: FormControl<UriNode | null>;
    isNotPred: FormControl<boolean>;
    preds: FormControl<UriNode[]>;
    notPreds: FormControl<UriNode[]>;
    hasLiteralObj: FormControl<boolean | null>;
    obj: FormControl<UriNode | null>;
    sid: FormControl<string | null>;
    isSidPrefix: FormControl<boolean>;
    tag: FormControl<string | null>;
    form: FormGroup;
    constructor(formBuilder: FormBuilder, lookupService: GraphNodeLookupService, _graphService: GraphService);
    private updateForm;
    private getFilter;
    onPageChange(page: PageEvent): void;
    onSubjectNodeChange(node: unknown): void;
    onObjectNodeChange(node: unknown): void;
    onPredicateNodeChange(node: unknown): void;
    deleteNotPred(node: UriNode): void;
    deletePred(node: UriNode): void;
    reset(): void;
    apply(): void;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<TripleFilterComponent, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<TripleFilterComponent, "cadmus-walker-triple-filter", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "hasPager": { "alias": "hasPager"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; }, { "filter": "filterChange"; }, never, never, true, never>;
}

/**
 * Get the extended label for the specified graph node. This returns the label
 * for N nodes, and the uri + "=" + the label for P nodes. That's because P
 * nodes label is just the count of the triples group, so the predicate ID is
 * got from the property node's data uri.
 */
declare class GraphNodeLabelPipe implements PipeTransform {
    transform(value: unknown, ...args: unknown[]): unknown;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<GraphNodeLabelPipe, never>;
    static ɵpipe: _angular_core.ɵɵPipeDeclaration<GraphNodeLabelPipe, "graphNodeLabel", true>;
}

export { GraphNodeLabelPipe, GraphWalker, GraphWalkerComponent, LinkedLiteralFilterComponent, LinkedNodeFilterComponent, TripleFilterComponent };
export type { NodeChildTotals, PagedLinkedLiteralFilter, PagedLinkedNodeFilter, PagedTripleFilter, WalkerData, WalkerLitData, WalkerNodeData, WalkerPropData, WalkerWidgetData };
