import { SvgPanZoomInstance } from '../modules/svg-pan-zoom-ex';
import { LayoutHandler } from '../layouts/handler';
import { RecursivePartial } from './common';
import { Edge, Edges, LayerName, Node, Path, Position } from './types';
type CallableValue<V, T> = V | ((target: T) => V);
type CallableValues<V, T> = {
    [K in keyof V]: CallableValue<V[K], T>;
};
export declare class Config {
    static value<V, T>(value: CallableValue<V, T>, target: T): V;
    static values<V, T>(value: CallableValues<V, T>, target: T): V;
}
export interface GridLine {
    color: string;
    width: number;
    dasharray?: string | number;
}
export interface GridConfig {
    visible: boolean;
    interval: number;
    thickIncrements: number | false;
    line: GridLine;
    thick: GridLine;
}
export interface BasicShapeStyle {
    strokeWidth: number;
    strokeColor?: string;
    strokeDasharray?: string | number;
    color: string;
}
type Percent = `${number}%`;
type Pixel = `${number}px`;
type NumericString = `${number}`;
export type MarginValue = Percent | Pixel | NumericString | number;
export type FitContentMargin = MarginValue | {
    top?: MarginValue;
    left?: MarginValue;
    right?: MarginValue;
    bottom?: MarginValue;
};
export interface ViewConfig {
    scalingObjects: boolean;
    panEnabled: boolean;
    zoomEnabled: boolean;
    minZoomLevel: number;
    maxZoomLevel: number;
    doubleClickZoomEnabled: boolean;
    mouseWheelZoomEnabled: boolean;
    boxSelectionEnabled: boolean;
    fit?: boolean;
    autoPanAndZoomOnLoad: false | "center-zero" | "center-content" | "fit-content";
    fitContentMargin: FitContentMargin;
    autoPanOnResize: boolean;
    layoutHandler: LayoutHandler;
    onSvgPanZoomInitialized?: (instance: SvgPanZoomInstance) => void;
    grid: GridConfig;
    selection: {
        box: BasicShapeStyle;
        detector: (event: KeyboardEvent) => boolean;
    };
    builtInLayerOrder: Readonly<LayerName[]>;
    onBeforeInitialDisplay?: (() => Promise<any>) | (() => any);
}
export type ShapeStyleBase = BasicShapeStyle;
export type ShapeType = "circle" | "rect";
interface CircleShape extends ShapeStyleBase {
    radius: number;
}
interface RectangleShape extends ShapeStyleBase {
    width: number;
    height: number;
    borderRadius: number;
}
type ShapeBase<T extends ShapeType = ShapeType> = {
    type: T;
};
export type ShapeStyle = ShapeBase & CircleShape & RectangleShape;
export type CircleShapeStyle = ShapeBase<"circle"> & CircleShape;
export type RectangleShapeStyle = ShapeBase<"rect"> & RectangleShape;
export type AnyShapeStyle = CircleShapeStyle | RectangleShapeStyle;
interface Padding {
    vertical: number;
    horizontal: number;
}
export interface LabelBackgroundStyle {
    visible: boolean;
    color?: string;
    padding?: number | Padding;
    borderRadius?: number;
}
export interface LabelStyle {
    fontFamily?: string;
    fontSize: number;
    color: string;
    background?: LabelBackgroundStyle;
    lineHeight: number;
}
export interface ZOrderConfig<T> {
    enabled: boolean;
    zIndex: CallableValue<number, T>;
    bringToFrontOnHover: boolean;
    bringToFrontOnSelected: boolean;
}
export interface ObjectConfigs<O> {
    selectable: CallableValue<boolean, O> | number;
    zOrder: ZOrderConfig<O>;
}
export declare enum NodeLabelDirection {
    CENTER = "center",
    NORTH = "north",
    NORTH_EAST = "north-east",
    EAST = "east",
    SOUTH_EAST = "south-east",
    SOUTH = "south",
    SOUTH_WEST = "south-west",
    WEST = "west",
    NORTH_WEST = "north-west"
}
export type NodeLabelDirectionType = "center" | "north" | "north-east" | "east" | "south-east" | "south" | "south-west" | "west" | "north-west";
export interface OppositeNode {
    nodeId: string;
    pos: Position;
}
export type OppositeNodes = Record<string, OppositeNode>;
export interface NodeLabelDirectionHandlerParams {
    nodeId: string;
    pos: Position;
    oppositeNodes: OppositeNodes;
}
export type NodeLabelDirectionAutoAdjustmentHandler = (params: NodeLabelDirectionHandlerParams) => NodeLabelDirectionType | null;
export interface NodeLabelStyle extends LabelStyle {
    visible: boolean;
    margin: number;
    direction: NodeLabelDirectionType;
    directionAutoAdjustment: boolean | NodeLabelDirectionAutoAdjustmentHandler;
    text: string;
    handleNodeEvents: boolean;
}
export interface NodeFocusRingStyle {
    visible: boolean;
    width: number;
    padding: number;
    color: string;
    dasharray?: string | number;
}
export interface NodeConfig<N extends Node = Node> {
    normal: CallableValues<ShapeStyle, N>;
    hover?: CallableValues<ShapeStyle, N>;
    selected?: CallableValues<ShapeStyle, N>;
    draggable: CallableValue<boolean, N>;
    selectable: CallableValue<boolean, N> | number;
    label: CallableValues<NodeLabelStyle, N>;
    focusring: NodeFocusRingStyle;
    zOrder: ZOrderConfig<N>;
    transition?: string;
}
export interface StrokeStyle {
    width: number;
    color: string;
    dasharray?: string | number;
    linecap?: "butt" | "round" | "square";
    animate: boolean;
    animationSpeed: number;
}
export interface EdgeLabelStyle extends LabelStyle {
    margin: number;
    padding: number;
}
export type EdgeHeadType = "none" | "arrow" | "angle" | "circle" | "custom";
export type MarkerUnits = "strokeWidth" | "userSpaceOnUse";
export interface MarkerStyle {
    type: EdgeHeadType;
    width: number;
    height: number;
    margin: number;
    offset: number;
    units: MarkerUnits;
    color: string | null;
    customId?: string;
}
export type EdgeType = "straight" | "curve";
export type EdgeKeepOrderType = "clock" | "vertical" | "horizontal";
export interface SelfLoopEdgeStyle {
    radius: number;
    offset: number;
    angle: number;
    isClockwise: boolean;
}
export interface EdgeConfig<E extends Edge = Edge> {
    normal: CallableValues<StrokeStyle, E>;
    hover?: CallableValues<StrokeStyle, E>;
    selected: CallableValues<StrokeStyle, E>;
    selectable: CallableValue<boolean, E> | number;
    gap: number | ((edges: Edges, configs: Configs) => number);
    type: EdgeType;
    marker: {
        source: CallableValues<MarkerStyle, [E, StrokeStyle]>;
        target: CallableValues<MarkerStyle, [E, StrokeStyle]>;
    };
    margin: number | null;
    summarize: boolean | ((edges: Edges, configs: Configs) => boolean | null);
    summarized: {
        label: CallableValues<LabelStyle, Record<string, E>>;
        shape: CallableValues<ShapeStyle, Record<string, E>>;
        stroke: CallableValues<StrokeStyle, Record<string, E>>;
    };
    selfLoop: CallableValues<SelfLoopEdgeStyle, E>;
    keepOrder: EdgeKeepOrderType;
    label: CallableValues<EdgeLabelStyle, E>;
    zOrder: ZOrderConfig<E>;
}
export interface PathStrokeStyle extends StrokeStyle {
    linejoin: "miter" | "round" | "bevel";
}
export type PathEndType = "centerOfNode" | "edgeOfNode";
export interface PathConfig<P extends Path = Path> {
    visible: boolean;
    clickable: CallableValue<boolean, P>;
    hoverable: CallableValue<boolean, P>;
    curveInNode: boolean;
    end: PathEndType;
    margin: CallableValue<number, P>;
    path: CallableValues<PathStrokeStyle, P>;
    normal: CallableValues<PathStrokeStyle, P>;
    hover?: CallableValues<PathStrokeStyle, P>;
    selected: CallableValues<PathStrokeStyle, P>;
    selectable: CallableValue<boolean, P> | number;
    zOrder: ZOrderConfig<P>;
    transition?: string;
}
export interface Configs<N extends Node = Node, E extends Edge = Edge, P extends Path = Path> {
    view: ViewConfig;
    node: NodeConfig<N>;
    edge: EdgeConfig<E>;
    path: PathConfig<P>;
}
/** For specification by the user */
export type UserConfigs<N extends Node = Node, E extends Edge = Edge, P extends Path = Path> = RecursivePartial<Configs<N, E, P>>;
/** Make a config with self object */
export declare function withSelf<T extends {
    [name: string]: any;
}>(callback: (self: T) => T): T;
/** @deprecated */
export declare function configsWithType<N extends Node = Node, E extends Edge = Edge, P extends Path = Path, U extends UserConfigs<N, E, P> = UserConfigs<N, E, P>>(configs: U): U & UserConfigs<N, E, P>;
/** Define configurations */
export declare function defineConfigs<N extends Node = Node, E extends Edge = Edge, P extends Path = Path, U extends UserConfigs<N, E, P> = UserConfigs<N, E, P>>(configs: U): U & UserConfigs<N, E, P>;
export {};
