/*
* 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 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
  };
}