/*
* 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.
*/

/**
 * @file This file used to draw tree view.
 * @author Deqing Li(annong035@gmail.com)
 */
import * as zrUtil from 'zrender/src/core/util';
import * as graphic from '../../util/graphic';
import SymbolClz from '../helper/Symbol';
import { radialCoordinate } from './layoutHelper';
import * as echarts from '../../echarts';
import * as bbox from 'zrender/src/core/bbox';
import View from '../../coord/View';
import * as roamHelper from '../../component/helper/roamHelper';
import RoamController from '../../component/helper/RoamController';
import { onIrrelevantElement } from '../../component/helper/cursorHelper';
export default echarts.extendChartView({
  type: 'tree',

  /**
   * Init the chart
   * @override
   * @param  {module:echarts/model/Global} ecModel
   * @param  {module:echarts/ExtensionAPI} api
   */
  init: function (ecModel, api) {
    /**
     * @private
     * @type {module:echarts/data/Tree}
     */
    this._oldTree;
    /**
     * @private
     * @type {module:zrender/container/Group}
     */

    this._mainGroup = new graphic.Group();
    /**
     * @private
     * @type {module:echarts/componet/helper/RoamController}
     */

    this._controller = new RoamController(api.getZr());
    this._controllerHost = {
      target: this.group
    };
    this.group.add(this._mainGroup);
  },
  render: function (seriesModel, ecModel, api, payload) {
    var data = seriesModel.getData();
    var layoutInfo = seriesModel.layoutInfo;
    var group = this._mainGroup;
    var layout = seriesModel.get('layout');

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

    this._updateViewCoordSys(seriesModel);

    this._updateController(seriesModel, ecModel, api);

    var oldData = this._data;
    var seriesScope = {
      expandAndCollapse: seriesModel.get('expandAndCollapse'),
      layout: layout,
      orient: seriesModel.getOrient(),
      curvature: seriesModel.get('lineStyle.curveness'),
      symbolRotate: seriesModel.get('symbolRotate'),
      symbolOffset: seriesModel.get('symbolOffset'),
      hoverAnimation: seriesModel.get('hoverAnimation'),
      useNameLabel: true,
      fadeIn: true
    };
    data.diff(oldData).add(function (newIdx) {
      if (symbolNeedsDraw(data, newIdx)) {
        // Create node and edge
        updateNode(data, newIdx, null, group, seriesModel, seriesScope);
      }
    }).update(function (newIdx, oldIdx) {
      var symbolEl = oldData.getItemGraphicEl(oldIdx);

      if (!symbolNeedsDraw(data, newIdx)) {
        symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel, seriesScope);
        return;
      } // Update node and edge


      updateNode(data, newIdx, symbolEl, group, seriesModel, seriesScope);
    }).remove(function (oldIdx) {
      var symbolEl = oldData.getItemGraphicEl(oldIdx); // 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, seriesScope);
      }
    }).execute();
    this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');

    this._updateNodeAndLinkScale(seriesModel);

    if (seriesScope.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: function (seriesModel) {
    var data = seriesModel.getData();
    var points = [];
    data.each(function (idx) {
      var layout = data.getItemLayout(idx);

      if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
        points.push([+layout.x, +layout.y]);
      }
    });
    var min = [];
    var max = [];
    bbox.fromPoints(points, min, max); // If width or height is 0

    if (max[0] - min[0] === 0) {
      max[0] += 1;
      min[0] -= 1;
    }

    if (max[1] - min[1] === 0) {
      max[1] += 1;
      min[1] -= 1;
    }

    var 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'));
    viewCoordSys.setZoom(seriesModel.get('zoom')); // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group

    this.group.attr({
      position: viewCoordSys.position,
      scale: viewCoordSys.scale
    });
    this._viewCoordSys = viewCoordSys;
  },
  _updateController: function (seriesModel, ecModel, api) {
    var controller = this._controller;
    var controllerHost = this._controllerHost;
    var group = this.group;
    controller.setPointerChecker(function (e, x, y) {
      var 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', function (e) {
      roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
      api.dispatchAction({
        seriesId: seriesModel.id,
        type: 'treeRoam',
        dx: e.dx,
        dy: e.dy
      });
    }, this).on('zoom', function (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);
    }, this);
  },
  _updateNodeAndLinkScale: function (seriesModel) {
    var data = seriesModel.getData();

    var nodeScale = this._getNodeGlobalScale(seriesModel);

    var invScale = [nodeScale, nodeScale];
    data.eachItemGraphicEl(function (el, idx) {
      el.attr('scale', invScale);
    });
  },
  _getNodeGlobalScale: function (seriesModel) {
    var coordSys = seriesModel.coordinateSystem;

    if (coordSys.type !== 'view') {
      return 1;
    }

    var nodeScaleRatio = this._nodeScaleRatio;
    var groupScale = coordSys.scale;
    var groupZoom = groupScale && groupScale[0] || 1; // Scale node when zoom changes

    var roamZoom = coordSys.getZoom();
    var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;
    return nodeScale / groupZoom;
  },
  dispose: function () {
    this._controller && this._controller.dispose();
    this._controllerHost = {};
  },
  remove: function () {
    this._mainGroup.removeAll();

    this._data = null;
  }
});

function symbolNeedsDraw(data, dataIndex) {
  var layout = data.getItemLayout(dataIndex);
  return layout && !isNaN(layout.x) && !isNaN(layout.y) && data.getItemVisual(dataIndex, 'symbol') !== 'none';
}

function getTreeNodeStyle(node, itemModel, seriesScope) {
  seriesScope.itemModel = itemModel;
  seriesScope.itemStyle = itemModel.getModel('itemStyle').getItemStyle();
  seriesScope.hoverItemStyle = itemModel.getModel('emphasis.itemStyle').getItemStyle();
  seriesScope.lineStyle = itemModel.getModel('lineStyle').getLineStyle();
  seriesScope.labelModel = itemModel.getModel('label');
  seriesScope.hoverLabelModel = itemModel.getModel('emphasis.label');

  if (node.isExpand === false && node.children.length !== 0) {
    seriesScope.symbolInnerColor = seriesScope.itemStyle.fill;
  } else {
    seriesScope.symbolInnerColor = '#fff';
  }

  return seriesScope;
}

function updateNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) {
  var isInit = !symbolEl;
  var node = data.tree.getNodeByDataIndex(dataIndex);
  var itemModel = node.getModel();
  var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope);
  var virtualRoot = data.tree.root;
  var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
  var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex);
  var sourceLayout = source.getLayout();
  var sourceOldLayout = sourceSymbolEl ? {
    x: sourceSymbolEl.position[0],
    y: sourceSymbolEl.position[1],
    rawX: sourceSymbolEl.__radialOldRawX,
    rawY: sourceSymbolEl.__radialOldRawY
  } : sourceLayout;
  var targetLayout = node.getLayout();

  if (isInit) {
    symbolEl = new SymbolClz(data, dataIndex, seriesScope);
    symbolEl.attr('position', [sourceOldLayout.x, sourceOldLayout.y]);
  } else {
    symbolEl.updateData(data, dataIndex, seriesScope);
  }

  symbolEl.__radialOldRawX = symbolEl.__radialRawX;
  symbolEl.__radialOldRawY = symbolEl.__radialRawY;
  symbolEl.__radialRawX = targetLayout.rawX;
  symbolEl.__radialRawY = targetLayout.rawY;
  group.add(symbolEl);
  data.setItemGraphicEl(dataIndex, symbolEl);
  graphic.updateProps(symbolEl, {
    position: [targetLayout.x, targetLayout.y]
  }, seriesModel);
  var symbolPath = symbolEl.getSymbolPath();

  if (seriesScope.layout === 'radial') {
    var realRoot = virtualRoot.children[0];
    var rootLayout = realRoot.getLayout();
    var length = realRoot.children.length;
    var rad;
    var isLeft;

    if (targetLayout.x === rootLayout.x && node.isExpand === true) {
      var center = {};
      center.x = (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2;
      center.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;
        }
      }
    }

    var textPosition = isLeft ? 'left' : 'right';
    symbolPath.setStyle({
      textPosition: textPosition,
      textRotation: -rad,
      textOrigin: 'center',
      verticalAlign: 'middle'
    });
  }

  if (node.parentNode && node.parentNode !== virtualRoot) {
    var edge = symbolEl.__edge;

    if (!edge) {
      edge = symbolEl.__edge = new graphic.BezierCurve({
        shape: getEdgeShape(seriesScope, sourceOldLayout, sourceOldLayout),
        style: zrUtil.defaults({
          opacity: 0,
          strokeNoScale: true
        }, seriesScope.lineStyle)
      });
    }

    graphic.updateProps(edge, {
      shape: getEdgeShape(seriesScope, sourceLayout, targetLayout),
      style: {
        opacity: 1
      }
    }, seriesModel);
    group.add(edge);
  }
}

function removeNode(data, dataIndex, symbolEl, group, seriesModel, seriesScope) {
  var node = data.tree.getNodeByDataIndex(dataIndex);
  var virtualRoot = data.tree.root;
  var itemModel = node.getModel();
  var seriesScope = getTreeNodeStyle(node, itemModel, seriesScope);
  var source = node.parentNode === virtualRoot ? node : node.parentNode || node;
  var sourceLayout;

  while (sourceLayout = source.getLayout(), sourceLayout == null) {
    source = source.parentNode === virtualRoot ? source : source.parentNode || source;
  }

  graphic.updateProps(symbolEl, {
    position: [sourceLayout.x + 1, sourceLayout.y + 1]
  }, seriesModel, function () {
    group.remove(symbolEl);
    data.setItemGraphicEl(dataIndex, null);
  });
  symbolEl.fadeOut(null, {
    keepLabel: true
  });
  var edge = symbolEl.__edge;

  if (edge) {
    graphic.updateProps(edge, {
      shape: getEdgeShape(seriesScope, sourceLayout, sourceLayout),
      style: {
        opacity: 0
      }
    }, seriesModel, function () {
      group.remove(edge);
    });
  }
}

function getEdgeShape(seriesScope, sourceLayout, targetLayout) {
  var cpx1;
  var cpy1;
  var cpx2;
  var cpy2;
  var orient = seriesScope.orient;
  var x1;
  var x2;
  var y1;
  var y2;

  if (seriesScope.layout === 'radial') {
    x1 = sourceLayout.rawX;
    y1 = sourceLayout.rawY;
    x2 = targetLayout.rawX;
    y2 = targetLayout.rawY;
    var radialCoor1 = radialCoordinate(x1, y1);
    var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * seriesScope.curvature);
    var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * seriesScope.curvature);
    var radialCoor4 = radialCoordinate(x2, y2);
    return {
      x1: radialCoor1.x,
      y1: radialCoor1.y,
      x2: radialCoor4.x,
      y2: radialCoor4.y,
      cpx1: radialCoor2.x,
      cpy1: radialCoor2.y,
      cpx2: radialCoor3.x,
      cpy2: radialCoor3.y
    };
  } else {
    x1 = sourceLayout.x;
    y1 = sourceLayout.y;
    x2 = targetLayout.x;
    y2 = targetLayout.y;

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

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

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