/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic';
import {getECData} from '../../util/innerStore';
import SymbolClz from '../helper/Symbol';
import {radialCoordinate} from './layoutHelper';
import * as bbox from 'zrender/src/core/bbox';
import View from '../../coord/View';
import * as roamHelper from '../../component/helper/roamHelper';
import RoamController, { RoamControllerHost } from '../../component/helper/RoamController';
import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import {parsePercent} from '../../util/number';
import ChartView from '../../view/Chart';
import TreeSeriesModel, { TreeSeriesOption, TreeSeriesNodeItemOption } from './TreeSeries';
import Path, { PathProps, PathStyleProps } from 'zrender/src/graphic/Path';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { TreeNode } from '../../data/Tree';
import SeriesData from '../../data/SeriesData';
import { setStatesStylesFromModel, setStatesFlag, setDefaultStateProxy, HOVER_STATE_BLUR } from '../../util/states';
import { AnimationOption, ECElement } from '../../util/types';

type TreeSymbol = SymbolClz & {
    __edge: graphic.BezierCurve | TreePath

    __radialOldRawX: number
    __radialOldRawY: number
    __radialRawX: number
    __radialRawY: number

    __oldX: number
    __oldY: number
};

class TreeEdgeShape {
    parentPoint: number[] = [];
    childPoints: number[][] = [];
    orient: TreeSeriesOption['orient'];
    forkPosition: TreeSeriesOption['edgeForkPosition'];
}

interface TreeEdgePathProps extends PathProps {
    shape?: Partial<TreeEdgeShape>
}

interface TreeNodeLayout {
    x: number
    y: number
    rawX: number
    rawY: number
}

class TreePath extends Path<TreeEdgePathProps> {
    shape: TreeEdgeShape;
    constructor(opts?: TreeEdgePathProps) {
        super(opts);
    }

    getDefaultStyle() {
        return {
            stroke: '#000',
            fill: null as string
        };
    }

    getDefaultShape() {
        return new TreeEdgeShape();
    }

    buildPath(ctx: CanvasRenderingContext2D, shape: TreeEdgeShape) {
        const childPoints = shape.childPoints;
        const childLen = childPoints.length;
        const parentPoint = shape.parentPoint;
        const firstChildPos = childPoints[0];
        const lastChildPos = childPoints[childLen - 1];

        if (childLen === 1) {
            ctx.moveTo(parentPoint[0], parentPoint[1]);
            ctx.lineTo(firstChildPos[0], firstChildPos[1]);
            return;
        }

        const orient = shape.orient;
        const forkDim = (orient === 'TB' || orient === 'BT') ? 0 : 1;
        const otherDim = 1 - forkDim;
        const forkPosition = parsePercent(shape.forkPosition, 1);
        const tmpPoint = [];
        tmpPoint[forkDim] = parentPoint[forkDim];
        tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition;

        ctx.moveTo(parentPoint[0], parentPoint[1]);
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.moveTo(firstChildPos[0], firstChildPos[1]);
        tmpPoint[forkDim] = firstChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        tmpPoint[forkDim] = lastChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.lineTo(lastChildPos[0], lastChildPos[1]);

        for (let i = 1; i < childLen - 1; i++) {
            const point = childPoints[i];
            ctx.moveTo(point[0], point[1]);
            tmpPoint[forkDim] = point[forkDim];
            ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        }
    }
}

class TreeView extends ChartView {

    static readonly type = 'tree';
    readonly type = TreeView.type;

    private _mainGroup = new graphic.Group();

    private _controller: RoamController;
    private _controllerHost: RoamControllerHost;

    private _data: SeriesData<TreeSeriesModel>;

    private _nodeScaleRatio: number;
    private _min: number[];
    private _max: number[];

    init(ecModel: GlobalModel, api: ExtensionAPI) {
        this._controller = new RoamController(api.getZr());

        this._controllerHost = {
            target: this.group
        } as RoamControllerHost;

        this.group.add(this._mainGroup);
    }

    render(
        seriesModel: TreeSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI
    ) {
        const data = seriesModel.getData();

        const layoutInfo = seriesModel.layoutInfo;

        const group = this._mainGroup;

        const layout = seriesModel.get('layout');

        if (layout === 'radial') {
            group.x = layoutInfo.x + layoutInfo.width / 2;
            group.y = layoutInfo.y + layoutInfo.height / 2;
        }
        else {
            group.x = layoutInfo.x;
            group.y = layoutInfo.y;
        }

        this._updateViewCoordSys(seriesModel, api);
        this._updateController(seriesModel, ecModel, api);

        const oldData = this._data;

        data.diff(oldData)
            .add(function (newIdx) {
                if (symbolNeedsDraw(data, newIdx)) {
                    // Create node and edge
                    updateNode(data, newIdx, null, group, seriesModel);
                }
            })
            .update(function (newIdx, oldIdx) {
                const symbolEl = oldData.getItemGraphicEl(oldIdx) as TreeSymbol;
                if (!symbolNeedsDraw(data, newIdx)) {
                    symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
                    return;
                }
                // Update node and edge
                updateNode(data, newIdx, symbolEl, group, seriesModel);
            })
            .remove(function (oldIdx) {
                const symbolEl = oldData.getItemGraphicEl(oldIdx) as TreeSymbol;
                // When remove a collapsed node of subtree, since the collapsed
                // node haven't been initialized with a symbol element,
                // you can't found it's symbol element through index.
                // so if we want to remove the symbol element we should insure
                // that the symbol element is not null.
                if (symbolEl) {
                    removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
                }
            })
            .execute();

        this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');

        this._updateNodeAndLinkScale(seriesModel);

        if (seriesModel.get('expandAndCollapse') === true) {
            data.eachItemGraphicEl(function (el, dataIndex) {
                el.off('click').on('click', function () {
                    api.dispatchAction({
                        type: 'treeExpandAndCollapse',
                        seriesId: seriesModel.id,
                        dataIndex: dataIndex
                    });
                });
            });
        }
        this._data = data;
    }

    _updateViewCoordSys(seriesModel: TreeSeriesModel, api: ExtensionAPI) {
        const data = seriesModel.getData();
        const points: number[][] = [];
        data.each(function (idx) {
            const layout = data.getItemLayout(idx);
            if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
                points.push([+layout.x, +layout.y]);
            }
        });
        const min: number[] = [];
        const max: number[] = [];
        bbox.fromPoints(points, min, max);

        // If don't Store min max when collapse the root node after roam,
        // the root node will disappear.
        const oldMin = this._min;
        const oldMax = this._max;

        // If width or height is 0
        if (max[0] - min[0] === 0) {
            min[0] = oldMin ? oldMin[0] : min[0] - 1;
            max[0] = oldMax ? oldMax[0] : max[0] + 1;
        }
        if (max[1] - min[1] === 0) {
            min[1] = oldMin ? oldMin[1] : min[1] - 1;
            max[1] = oldMax ? oldMax[1] : max[1] + 1;
        }

        const viewCoordSys = seriesModel.coordinateSystem = new View();
        viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');

        viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);

        viewCoordSys.setCenter(seriesModel.get('center'), api);
        viewCoordSys.setZoom(seriesModel.get('zoom'));

        // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group
        this.group.attr({
            x: viewCoordSys.x,
            y: viewCoordSys.y,
            scaleX: viewCoordSys.scaleX,
            scaleY: viewCoordSys.scaleY
        });

        this._min = min;
        this._max = max;
    }

    _updateController(
        seriesModel: TreeSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI
    ) {
        const controller = this._controller;
        const controllerHost = this._controllerHost;
        const group = this.group;
        controller.setPointerChecker(function (e, x, y) {
            const rect = group.getBoundingRect();
            rect.applyTransform(group.transform);
            return rect.contain(x, y)
                && !onIrrelevantElement(e, api, seriesModel);
        });

        controller.enable(seriesModel.get('roam'));
        controllerHost.zoomLimit = seriesModel.get('scaleLimit');
        controllerHost.zoom = seriesModel.coordinateSystem.getZoom();

        controller
            .off('pan')
            .off('zoom')
            .on('pan', (e) => {
                roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
                api.dispatchAction({
                    seriesId: seriesModel.id,
                    type: 'treeRoam',
                    dx: e.dx,
                    dy: e.dy
                });
            })
            .on('zoom', (e) => {
                roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
                api.dispatchAction({
                    seriesId: seriesModel.id,
                    type: 'treeRoam',
                    zoom: e.scale,
                    originX: e.originX,
                    originY: e.originY
                });
                this._updateNodeAndLinkScale(seriesModel);
                // Only update label layout on zoom
                api.updateLabelLayout();
            });
    }

    _updateNodeAndLinkScale(seriesModel: TreeSeriesModel) {
        const data = seriesModel.getData();

        const nodeScale = this._getNodeGlobalScale(seriesModel);

        data.eachItemGraphicEl(function (el: SymbolClz, idx) {
            el.setSymbolScale(nodeScale);
        });
    }

    _getNodeGlobalScale(seriesModel: TreeSeriesModel) {
        const coordSys = seriesModel.coordinateSystem;
        if (coordSys.type !== 'view') {
            return 1;
        }

        const nodeScaleRatio = this._nodeScaleRatio;

        const groupZoom = coordSys.scaleX || 1;
        // Scale node when zoom changes
        const roamZoom = coordSys.getZoom();
        const nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;

        return nodeScale / groupZoom;
    }

    dispose() {
        this._controller && this._controller.dispose();
        this._controllerHost = null;
    }

    remove() {
        this._mainGroup.removeAll();
        this._data = null;
    }

}

function symbolNeedsDraw(data: SeriesData, dataIndex: number) {
    const layout = data.getItemLayout(dataIndex);

    return layout
        && !isNaN(layout.x) && !isNaN(layout.y);
}


function updateNode(
    data: SeriesData,
    dataIndex: number,
    symbolEl: TreeSymbol,
    group: graphic.Group,
    seriesModel: TreeSeriesModel
) {
    const isInit = !symbolEl;
    const node = data.tree.getNodeByDataIndex(dataIndex);
    const itemModel = node.getModel<TreeSeriesNodeItemOption>();
    const visualColor = (node.getVisual('style') as PathStyleProps).fill;
    const symbolInnerColor = node.isExpand === false && node.children.length !== 0
            ? visualColor : '#fff';

    const virtualRoot = data.tree.root;

    const source = node.parentNode === virtualRoot ? node : node.parentNode || node;
    const sourceSymbolEl = data.getItemGraphicEl(source.dataIndex) as TreeSymbol;
    const sourceLayout = source.getLayout() as TreeNodeLayout;
    const sourceOldLayout = sourceSymbolEl
        ? {
            x: sourceSymbolEl.__oldX,
            y: sourceSymbolEl.__oldY,
            rawX: sourceSymbolEl.__radialOldRawX,
            rawY: sourceSymbolEl.__radialOldRawY
        }
        : sourceLayout;
    const targetLayout = node.getLayout();

    if (isInit) {
        symbolEl = new SymbolClz(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        }) as TreeSymbol;
        symbolEl.x = sourceOldLayout.x;
        symbolEl.y = sourceOldLayout.y;
    }
    else {
        symbolEl.updateData(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        });
    }

    symbolEl.__radialOldRawX = symbolEl.__radialRawX;
    symbolEl.__radialOldRawY = symbolEl.__radialRawY;
    symbolEl.__radialRawX = targetLayout.rawX;
    symbolEl.__radialRawY = targetLayout.rawY;

    group.add(symbolEl);
    data.setItemGraphicEl(dataIndex, symbolEl);

    symbolEl.__oldX = symbolEl.x;
    symbolEl.__oldY = symbolEl.y;

    graphic.updateProps(symbolEl, {
        x: targetLayout.x,
        y: targetLayout.y
    }, seriesModel);

    const symbolPath = symbolEl.getSymbolPath();

    if (seriesModel.get('layout') === 'radial') {
        const realRoot = virtualRoot.children[0];
        const rootLayout = realRoot.getLayout();
        const length = realRoot.children.length;
        let rad;
        let isLeft;

        if (targetLayout.x === rootLayout.x && node.isExpand === true && realRoot.children.length) {
            const center = {
                x: (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2,
                y: (realRoot.children[0].getLayout().y + realRoot.children[length - 1].getLayout().y) / 2
            };
            rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            isLeft = center.x < rootLayout.x;
            if (isLeft) {
                rad = rad - Math.PI;
            }
        }
        else {
            rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            if (node.children.length === 0 || (node.children.length !== 0 && node.isExpand === false)) {
                isLeft = targetLayout.x < rootLayout.x;
                if (isLeft) {
                    rad = rad - Math.PI;
                }
            }
            else {
                isLeft = targetLayout.x > rootLayout.x;
                if (!isLeft) {
                    rad = rad - Math.PI;
                }
            }
        }

        const textPosition = isLeft ? 'left' as const : 'right' as const;
        const normalLabelModel = itemModel.getModel('label');
        const rotate = normalLabelModel.get('rotate');
        const labelRotateRadian = rotate * (Math.PI / 180);

        const textContent = symbolPath.getTextContent();
        if (textContent) {
            symbolPath.setTextConfig({
                position: normalLabelModel.get('position') || textPosition,
                rotation: rotate == null ? -rad : labelRotateRadian,
                origin: 'center'
            });
            textContent.setStyle('verticalAlign', 'middle');
        }

    }

    // Handle status
    const focus = itemModel.get(['emphasis', 'focus']);
    const focusDataIndices: number[] = focus === 'relative'
        ? zrUtil.concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) as number[]
        : focus === 'ancestor'
            ? node.getAncestorsIndices()
            : focus === 'descendant' ? node.getDescendantIndices() : null;

    if (focusDataIndices) {
        // Modify the focus to data indices.
        getECData(symbolEl).focus = focusDataIndices;
    }

    drawEdge(
        seriesModel, node, virtualRoot, symbolEl, sourceOldLayout,
        sourceLayout, targetLayout, group
    );

    if (symbolEl.__edge) {
        (symbolEl as ECElement).onHoverStateChange = function (toState) {
            if (toState !== 'blur') {
                // NOTE: Ensure the parent elements will been blurred firstly.
                // According to the return of getAncestorsIndices and getDescendantIndices
                // TODO: A bit tricky.
                const parentEl = node.parentNode
                    && data.getItemGraphicEl(node.parentNode.dataIndex);
                if (!(parentEl && (parentEl as ECElement).hoverState === HOVER_STATE_BLUR)) {
                    setStatesFlag(symbolEl.__edge, toState);
                }
            }
        };
    }
}

function drawEdge(
    seriesModel: TreeSeriesModel,
    node: TreeNode,
    virtualRoot: TreeNode,
    symbolEl: TreeSymbol,
    sourceOldLayout: TreeNodeLayout,
    sourceLayout: TreeNodeLayout,
    targetLayout: TreeNodeLayout,
    group: graphic.Group
) {
    const itemModel = node.getModel<TreeSeriesNodeItemOption>();
    const edgeShape = seriesModel.get('edgeShape');
    const layout = seriesModel.get('layout');
    const orient = seriesModel.getOrient();
    const curvature = seriesModel.get(['lineStyle', 'curveness']);
    const edgeForkPosition = seriesModel.get('edgeForkPosition');
    const lineStyle = itemModel.getModel('lineStyle').getLineStyle();
    let edge = symbolEl.__edge;
    // curve edge from node -> parent
    // polyline edge from node -> children
    if (edgeShape === 'curve') {
        if (node.parentNode && node.parentNode !== virtualRoot) {
            if (!edge) {
                edge = symbolEl.__edge = new graphic.BezierCurve({
                    shape: getEdgeShape(layout, orient, curvature, sourceOldLayout, sourceOldLayout)
                });
            }

            graphic.updateProps(edge as Path, {
                shape: getEdgeShape(layout, orient, curvature, sourceLayout, targetLayout)
            }, seriesModel);
        }
    }
    else if (edgeShape === 'polyline') {
        if (layout === 'orthogonal') {
            if (node !== virtualRoot && node.children && (node.children.length !== 0) && (node.isExpand === true)) {
                const children = node.children;
                const childPoints = [];
                for (let i = 0; i < children.length; i++) {
                    const childLayout = children[i].getLayout();
                    childPoints.push([childLayout.x, childLayout.y]);
                }

                if (!edge) {
                    edge = symbolEl.__edge = new TreePath({
                        shape: {
                            parentPoint: [targetLayout.x, targetLayout.y],
                            childPoints: [[targetLayout.x, targetLayout.y]],
                            orient: orient,
                            forkPosition: edgeForkPosition
                        }
                    });
                }
                graphic.updateProps(edge as Path, {
                    shape: {
                        parentPoint: [targetLayout.x, targetLayout.y],
                        childPoints: childPoints
                    }
                }, seriesModel);
            }
        }
        else {
            if (__DEV__) {
                throw new Error('The polyline edgeShape can only be used in orthogonal layout');
            }
        }
    }

    // show all edge when edgeShape is 'curve', filter node `isExpand` is false when edgeShape is 'polyline'
    if (edge && !(edgeShape === 'polyline' && !node.isExpand)) {
        edge.useStyle(zrUtil.defaults({
            strokeNoScale: true, fill: null
        }, lineStyle));

        setStatesStylesFromModel(edge, itemModel, 'lineStyle');
        setDefaultStateProxy(edge);

        group.add(edge);
    }
}

function removeNodeEdge(
    node: TreeNode,
    data: SeriesData,
    group: graphic.Group,
    seriesModel: TreeSeriesModel,
    removeAnimationOpt: AnimationOption
) {
    const virtualRoot = data.tree.root;
    const { source, sourceLayout } = getSourceNode(virtualRoot, node);

    const symbolEl: TreeSymbol = data.getItemGraphicEl(node.dataIndex) as TreeSymbol;

    if (!symbolEl) {
        return;
    }

    const sourceSymbolEl = data.getItemGraphicEl(source.dataIndex) as TreeSymbol;
    const sourceEdge = sourceSymbolEl.__edge;

    // 1. when expand the sub tree, delete the children node should delete the edge of
    // the source at the same time. because the polyline edge shape is only owned by the source.
    // 2.when the node is the only children of the source, delete the node should delete the edge of
    // the source at the same time. the same reason as above.
    const edge = symbolEl.__edge
        || ((source.isExpand === false || source.children.length === 1) ? sourceEdge : undefined);

    const edgeShape = seriesModel.get('edgeShape');
    const layoutOpt = seriesModel.get('layout');
    const orient = seriesModel.get('orient');
    const curvature = seriesModel.get(['lineStyle', 'curveness']);

    if (edge) {
        if (edgeShape === 'curve') {
            graphic.removeElement(edge as Path, {
                shape: getEdgeShape(
                    layoutOpt,
                    orient,
                    curvature,
                    sourceLayout,
                    sourceLayout
                ),
                style: {
                    opacity: 0
                }
            }, seriesModel, {
                cb() {
                    group.remove(edge);
                },
                removeOpt: removeAnimationOpt
            });
        }
        else if (edgeShape === 'polyline' && seriesModel.get('layout') === 'orthogonal') {
            graphic.removeElement(edge as Path, {
                shape: {
                    parentPoint: [sourceLayout.x, sourceLayout.y],
                    childPoints: [[sourceLayout.x, sourceLayout.y]]
                },
                style: {
                    opacity: 0
                }
            }, seriesModel, {
                cb() {
                    group.remove(edge);
                },
                removeOpt: removeAnimationOpt
            });
        }
    }
}

function getSourceNode(virtualRoot: TreeNode, node: TreeNode): { source: TreeNode, sourceLayout: TreeNodeLayout } {
    let source = node.parentNode === virtualRoot ? node : node.parentNode || node;
    let sourceLayout;
    while (sourceLayout = source.getLayout(), sourceLayout == null) {
        source = source.parentNode === virtualRoot ? source : source.parentNode || source;
    }
    return {
        source,
        sourceLayout
    };
}

function removeNode(
    data: SeriesData,
    dataIndex: number,
    symbolEl: TreeSymbol,
    group: graphic.Group,
    seriesModel: TreeSeriesModel
) {
    const node = data.tree.getNodeByDataIndex(dataIndex);
    const virtualRoot = data.tree.root;

    const { sourceLayout } = getSourceNode(virtualRoot, node);

    // Use same duration and easing with update to have more consistent animation.
    const removeAnimationOpt = {
        duration: seriesModel.get('animationDurationUpdate') as number,
        easing: seriesModel.get('animationEasingUpdate')
    };

    graphic.removeElement(symbolEl, {
        x: sourceLayout.x + 1,
        y: sourceLayout.y + 1
    }, seriesModel, {
        cb() {
            group.remove(symbolEl);
            data.setItemGraphicEl(dataIndex, null);
        },
        removeOpt: removeAnimationOpt
    });

    symbolEl.fadeOut(null, data.hostModel as TreeSeriesModel, {
        fadeLabel: true,
        animation: removeAnimationOpt
    });

    // remove edge as parent node
    node.children.forEach(childNode => {
        removeNodeEdge(childNode, data, group, seriesModel, removeAnimationOpt);
    });
    // remove edge as child node
    removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt);
}

function getEdgeShape(
    layoutOpt: TreeSeriesOption['layout'],
    orient: TreeSeriesOption['orient'],
    curvature: number,
    sourceLayout: TreeNodeLayout,
    targetLayout: TreeNodeLayout
) {
    let cpx1: number;
    let cpy1: number;
    let cpx2: number;
    let cpy2: number;
    let x1: number;
    let x2: number;
    let y1: number;
    let y2: number;

    if (layoutOpt === 'radial') {
        x1 = sourceLayout.rawX;
        y1 = sourceLayout.rawY;
        x2 = targetLayout.rawX;
        y2 = targetLayout.rawY;

        const radialCoor1 = radialCoordinate(x1, y1);
        const radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * curvature);
        const radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * curvature);
        const radialCoor4 = radialCoordinate(x2, y2);

        return {
            x1: radialCoor1.x || 0,
            y1: radialCoor1.y || 0,
            x2: radialCoor4.x || 0,
            y2: radialCoor4.y || 0,
            cpx1: radialCoor2.x || 0,
            cpy1: radialCoor2.y || 0,
            cpx2: radialCoor3.x || 0,
            cpy2: radialCoor3.y || 0
        };
    }
    else {
        x1 = sourceLayout.x;
        y1 = sourceLayout.y;
        x2 = targetLayout.x;
        y2 = targetLayout.y;

        if (orient === 'LR' || orient === 'RL') {
            cpx1 = x1 + (x2 - x1) * curvature;
            cpy1 = y1;
            cpx2 = x2 + (x1 - x2) * curvature;
            cpy2 = y2;
        }
        if (orient === 'TB' || orient === 'BT') {
            cpx1 = x1;
            cpy1 = y1 + (y2 - y1) * curvature;
            cpx2 = x2;
            cpy2 = y2 + (y1 - y2) * curvature;
        }
    }

    return {
        x1: x1,
        y1: y1,
        x2: x2,
        y2: y2,
        cpx1: cpx1,
        cpy1: cpy1,
        cpx2: cpx2,
        cpy2: cpy2
    };
}

export default TreeView;