import { DatumNodeSpec, ErrNodeSpec, MergeNodeSpec, PinNodeSpec, PlugNodeSpec, UnitNodeSpec } from '../Class/Graph/buildMoveMap';
import { DataRef } from '../DataRef';
import { Position } from '../client/util/geometry/types';
import { BaseSpec } from './BaseSpec';
import { Dict } from './Dict';
import { GraphMergeSpec } from './GraphMergeSpec';
import { GraphPinSpec } from './GraphPinSpec';
import { GraphSpec } from './GraphSpec';
import { IO } from './IO';
import { IOOf } from './IOOf';
import { NodeMetadataSpec } from './NodeMetadataSpec';
import { None } from './None';
import { UnitClass } from './UnitClass';
export type Type = string;
export type Types = Dict<Type>;
export type PinSpecBase = {
    name?: string;
    optional?: boolean;
    functional?: boolean;
    defaultIgnored?: boolean;
    ref?: boolean;
    data?: any;
    type?: string;
    init?: string;
    icon?: string;
    component?: boolean;
    metadata?: PinBaseMetadataSpec;
};
export type PinBaseMetadataSpec = NodeMetadataSpec & {
    examples?: any[];
    r?: number;
};
export type PinSpec = PinSpecBase | GraphPinSpec;
export type PinsSpecBase = Dict<PinSpecBase>;
export type GraphExposedMergeSpec = PinSpecBase & {
    mergeId: string;
    unitId?: undefined;
    pinId?: undefined;
    kind?: undefined;
};
export type GraphExposedLinkPinSpec = PinSpecBase & {
    unitId: string;
    kind?: IO | undefined;
    pinId: string;
    mergeId?: undefined;
};
export type GraphExposedEmptyPinSpec = PinSpecBase & {
    unitId?: undefined;
    pinId?: undefined;
    mergeId?: undefined;
    kind?: undefined;
};
export type GraphSubPinSpec = GraphExposedMergeSpec | GraphExposedLinkPinSpec | GraphExposedEmptyPinSpec;
export type NodeSpec = PinNodeSpec | MergeNodeSpec | PlugNodeSpec | UnitNodeSpec | DatumNodeSpec | ErrNodeSpec;
export type GraphPinNodeSpec = {
    type: 'pin';
    spec: PinNodeSpec;
};
export type GraphMergeNodeSpec = {
    type: 'merge';
    spec: MergeNodeSpec;
};
export type GraphUnitNodeSpec = {
    type: 'unit';
    spec: UnitNodeSpec;
};
export type GraphPlugNodeSpec = {
    type: 'plug';
    spec: PlugNodeSpec;
};
export type GraphDatumNodeSpec = {
    type: 'datum';
    spec: DatumNodeSpec;
};
export type GraphErrNodeSpec = {
    type: 'err';
    spec: ErrNodeSpec;
};
export type GraphNodeSpec = GraphPinNodeSpec | GraphMergeNodeSpec | GraphUnitNodeSpec | GraphPlugNodeSpec | GraphDatumNodeSpec | GraphErrNodeSpec;
export type GraphPinsSpec = Dict<GraphPinSpec>;
export type PinsSpec = Dict<PinSpec>;
export type Classes = Dict<UnitClass<any>>;
export type DatumSpec = {
    value: string | DataRef<any>;
    metadata?: DatumMetadataSpec;
};
export type DatumMetadataSpec = {
    position?: Position;
};
export type GraphDataSpec = Dict<DatumSpec>;
export type Spec = BaseSpec | GraphSpec;
export type Specs = Dict<Spec>;
export type GraphMetadataSpec = NodeMetadataSpec & {
    position?: Dict<Dict<Position> | None>;
};
export type BaseComponentSpec = {
    defaultWidth?: number;
    defaultHeight?: number;
};
export type BaseComponentSpecs = Dict<BaseComponentSpec>;
export type GraphSubComponentSpec = {
    width?: number;
    height?: number;
    children?: string[];
    childSlot?: Dict<string>;
    attr?: Dict<string>;
};
export type GraphSubComponentSpecs = Dict<GraphSubComponentSpec>;
export type GraphComponentSpec = BaseComponentSpec & {
    slots?: string[][];
    subComponents?: GraphSubComponentSpecs;
    children?: string[];
};
export type ComponentSpec = GraphComponentSpec | BaseComponentSpec;
export type Email = string;
export type Comment = {
    author: Email;
    comment: string;
};
export type Comments = {
    [id: string]: Comment;
};
export type GraphUnitMetadataSpec = {
    component?: {
        width?: number;
        height?: number;
    };
    rename?: string | None;
    comment?: string | None;
    position?: Position;
};
export type GraphUnitPinOuterSpec = {
    unitId: string;
    type: IO;
    pinId: string;
};
export type GraphPlugOuterSpec = {
    type: IO;
    pinId: string;
    subPinId: string;
    pinSpec: GraphPinSpec;
    subPinSpec: GraphSubPinSpec;
};
export type GraphOuterMergeSpec = {
    mergeId: string;
    mergeSpec: GraphMergeSpec;
};
export type GraphUnitOuterSpec = {
    merges: IOOf<Dict<{
        mergeId: string;
        otherPin: GraphUnitPinOuterSpec | null;
        exposedPin: GraphPlugOuterSpec | null;
    }>>;
    exposed: IOOf<Dict<GraphPlugOuterSpec>>;
};
