// 工具
declare namespace Util {
  /**
   * @function arcPath
   * @description 计算弧线
   * @param {Object} link link对象
   * @param {string} direction 方向
   */
  interface arcPath {
    (link: any, direction: 'upper' | 'lower'): void;
  }

  /**
   * @function bezierCurveCoord
   * @description 计算贝塞尔坐标
   * @param {Object} d link对象
   * @return {Object} controlPoint1 控制点1
   * @return {Object} controlPoint2 控制点2
   * @return {Object} pointStart 源节点
   * @return {Object} pointEnd 目标节点
   * @return {Object} sPoint 附加测试节点
   */
  interface bezierCurveCoord {
    (d: any): {
      controlPoint1: any;
      controlPoint2: any;
      pointStart: any;
      pointEnd: any;
      sPoint: any;
    };
  }

  /**
   * @function getProportion
   * @description 计算控制点的位置比例
   * @param {Object} d link对象
   * @param {Object} {x, y} 控制点坐标
   * @return {Object} {x, y} 控制点位置比例
   */
  interface getProportion {
    (d: any): {
      y: number;
      x: number;
    };
  }

  /**
   * @function bezierPath
   * @description 计算path的贝塞尔值
   * @param {Object} link link对象
   * @param {Object} bezierOption 贝塞尔控制
   * @return {string} svg中path的值
   */
  interface bezierPath {
    (d: any, bezierOption?: any): string;
  }

  /**
   * @function couldBeClass
   * @description 判断是否是class
   * @param {Object} obj 被判断的对象
   * @return {boolean} 是否是对象
   * https://github.com/hyurl/could-be-class
   */
  interface couldBeClass {
    (obj: any): boolean;
  }

  // 节点创建工具
  class GraphCreator {
    constructor(data: any, option: any);
    option: any;
    data: any;
    nodes: any[];
    links: any[];
    key: string;
    keyCnt: number;
    keyCntObj: any;
    keyPrefix: string;

    getData(): any;
    createKey(channel: string): any;
    checkUniq(node: any): any;
    addNode(node: any): any;
    addNodeAttr(): void;
    addNodes(cnt: number, prefix: string, callback: any): any;
    addLinks(source: any, target: any, linkOption: any): any;
    findNode(key: string, value: any): any;
  }

  /**
   * @function layoutLayerData
   * @description 图数据数据类dag化
   * @param {Object} graphData {nodes: [], links: []}
   * @param {string} options.expandFirst 'next' | 'prev'
   * @param {boolean} options.nextFarFirst 定制功能
   * @param {string | [string]} options.root 根节点
   * @return {Object[]} rootNodes 根节点
   * @return {Object[]} nextNodesLevel 根节点下游(包含根节点)
   * @return {Object[]} nextNodesLevelOnly 根节点下游
   * @return {Object[]} prevNodesLevel 根节点上游(包含根节点)
   * @return {Object[]} prevNodesLevelOnly 根节点上游
   * @return {Object[]} remainNodes 剩余的节点
   */
  interface layoutLayerData {
    (
      graphData: { nodes: any[]; links: any[] },
      options: {
        expandFirst: string;
        nextFarFirst: boolean;
        root: string | string[];
      }
    ): {
      rootNodes: any[];
      nextNodesLevel: any[];
      nextNodesLevelOnly: any[];
      prevNodesLevel: any[];
      prevNodesLevelOnly: any[];
      remainNodes: any[];
    };
  }

  /**
   * @function layoutLayerCoord
   * @description dag模式坐标计算
   * @param {Object} param1.reactObj {width, height}
   * @param {Object} param1.layerNodes 层次化的数据
   * @param {Object} param1.remainNodes 剩余的节点
   * @param {Object} options.padding {top, bottom, left, right}
   */
  interface layoutLayerCoord {
    (
      params1: { reactObj: { width: number; height: number }; layerNodes: any[]; remainNodes: any[] },
      options: {
        padding?: {
          top: number;
          bottom: number;
          left: number;
          right: number;
        };
      }
    ): void;
  }

  /**
   * @function layoutRingCoord
   * @description 环形模式坐标计算
   * @param {Object} param1.reactObj {width, height}
   * @param {Object} param1.layerNodes 层次化的数据
   * @param {Object} param1.remainNodes 剩余的节点
   * @param {Object} options.padding {top, bottom, left, right}
   */
  interface layoutRingCoord {
    (
      params1: { reactObj: { width: number; height: number }; layerNodes: any[]; remainNodes: any[] },
      options: {
        padding?: {
          top: number;
          bottom: number;
          left: number;
          right: number;
        };
      }
    ): void;
  }

  /**
   * @function linkCoord
   * @description 边的坐标计算
   * @param {Object} link link对象
   * @param {Object} option 功能配置
   * @return {Object} link 计算过后的坐标
   */
  interface linkCoord {
    (link: { source: { x: number; y: number }; target: { x: number; y: number } }, options: any): {
      source: { x: number; y: number };
      target: { x: number; y: number };
    };
  }

  // 遮挡检测算法
  class OcclusionDetection {
    constructor(options: { rootElement: any; detectionElement: string; xGridCnt: number; yGridCnt: number });
    detectionElement: any;
    rootElement: any;
    rootRect: any;
    xGridCnt: any;
    yGridCnt: any;
    xGridWidth: any;
    yGridHeight: any;
    gridSizeMap: any;
    gridPointsMap: any;
    detectionElements: any[];
    detectionRectList: any[];
    _tick: any;

    detect(): void;
    makeDetectionRect(): void;
    fillGrid(rect: any): void;
    findDetection(): void;
    divideGrid(): void;
    tick(cb: any): void;
    getRect(dom: any): any;
    getRect(dom: any): any;
  }

  /**
   * @function straightPath
   * @description 直线path值计算
   * @param {Object} d link对象
   * @return {string} path值
   */
  interface straightPath {
    (d: { source: { x: number; y: number }; target: { x: number; y: number } }): string;
  }
}

export default Util;
