"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const layout = require("../../util/layout.js");
const number = require("../../util/number.js");
const util = require("../../../../../../zrender@5.4.4/node_modules/zrender/lib/core/util.js");
function getViewRect(seriesModel, api) {
  return layout.getLayoutRect(seriesModel.getBoxLayoutParams(), {
    width: api.getWidth(),
    height: api.getHeight()
  });
}
function getSortedIndices(data, sort) {
  var valueDim = data.mapDimension("value");
  var valueArr = data.mapArray(valueDim, function(val) {
    return val;
  });
  var indices = [];
  var isAscending = sort === "ascending";
  for (var i = 0, len = data.count(); i < len; i++) {
    indices[i] = i;
  }
  if (util.isFunction(sort)) {
    indices.sort(sort);
  } else if (sort !== "none") {
    indices.sort(function(a, b) {
      return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];
    });
  }
  return indices;
}
function labelLayout(data) {
  var seriesModel = data.hostModel;
  var orient = seriesModel.get("orient");
  data.each(function(idx) {
    var itemModel = data.getItemModel(idx);
    var labelModel = itemModel.getModel("label");
    var labelPosition = labelModel.get("position");
    var labelLineModel = itemModel.getModel("labelLine");
    var layout2 = data.getItemLayout(idx);
    var points = layout2.points;
    var isLabelInside = labelPosition === "inner" || labelPosition === "inside" || labelPosition === "center" || labelPosition === "insideLeft" || labelPosition === "insideRight";
    var textAlign;
    var textX;
    var textY;
    var linePoints;
    if (isLabelInside) {
      if (labelPosition === "insideLeft") {
        textX = (points[0][0] + points[3][0]) / 2 + 5;
        textY = (points[0][1] + points[3][1]) / 2;
        textAlign = "left";
      } else if (labelPosition === "insideRight") {
        textX = (points[1][0] + points[2][0]) / 2 - 5;
        textY = (points[1][1] + points[2][1]) / 2;
        textAlign = "right";
      } else {
        textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4;
        textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4;
        textAlign = "center";
      }
      linePoints = [[textX, textY], [textX, textY]];
    } else {
      var x1 = void 0;
      var y1 = void 0;
      var x2 = void 0;
      var y2 = void 0;
      var labelLineLen = labelLineModel.get("length");
      if (process.env.NODE_ENV !== "production") {
        if (orient === "vertical" && ["top", "bottom"].indexOf(labelPosition) > -1) {
          labelPosition = "left";
          console.warn("Position error: Funnel chart on vertical orient dose not support top and bottom.");
        }
        if (orient === "horizontal" && ["left", "right"].indexOf(labelPosition) > -1) {
          labelPosition = "bottom";
          console.warn("Position error: Funnel chart on horizontal orient dose not support left and right.");
        }
      }
      if (labelPosition === "left") {
        x1 = (points[3][0] + points[0][0]) / 2;
        y1 = (points[3][1] + points[0][1]) / 2;
        x2 = x1 - labelLineLen;
        textX = x2 - 5;
        textAlign = "right";
      } else if (labelPosition === "right") {
        x1 = (points[1][0] + points[2][0]) / 2;
        y1 = (points[1][1] + points[2][1]) / 2;
        x2 = x1 + labelLineLen;
        textX = x2 + 5;
        textAlign = "left";
      } else if (labelPosition === "top") {
        x1 = (points[3][0] + points[0][0]) / 2;
        y1 = (points[3][1] + points[0][1]) / 2;
        y2 = y1 - labelLineLen;
        textY = y2 - 5;
        textAlign = "center";
      } else if (labelPosition === "bottom") {
        x1 = (points[1][0] + points[2][0]) / 2;
        y1 = (points[1][1] + points[2][1]) / 2;
        y2 = y1 + labelLineLen;
        textY = y2 + 5;
        textAlign = "center";
      } else if (labelPosition === "rightTop") {
        x1 = orient === "horizontal" ? points[3][0] : points[1][0];
        y1 = orient === "horizontal" ? points[3][1] : points[1][1];
        if (orient === "horizontal") {
          y2 = y1 - labelLineLen;
          textY = y2 - 5;
          textAlign = "center";
        } else {
          x2 = x1 + labelLineLen;
          textX = x2 + 5;
          textAlign = "top";
        }
      } else if (labelPosition === "rightBottom") {
        x1 = points[2][0];
        y1 = points[2][1];
        if (orient === "horizontal") {
          y2 = y1 + labelLineLen;
          textY = y2 + 5;
          textAlign = "center";
        } else {
          x2 = x1 + labelLineLen;
          textX = x2 + 5;
          textAlign = "bottom";
        }
      } else if (labelPosition === "leftTop") {
        x1 = points[0][0];
        y1 = orient === "horizontal" ? points[0][1] : points[1][1];
        if (orient === "horizontal") {
          y2 = y1 - labelLineLen;
          textY = y2 - 5;
          textAlign = "center";
        } else {
          x2 = x1 - labelLineLen;
          textX = x2 - 5;
          textAlign = "right";
        }
      } else if (labelPosition === "leftBottom") {
        x1 = orient === "horizontal" ? points[1][0] : points[3][0];
        y1 = orient === "horizontal" ? points[1][1] : points[2][1];
        if (orient === "horizontal") {
          y2 = y1 + labelLineLen;
          textY = y2 + 5;
          textAlign = "center";
        } else {
          x2 = x1 - labelLineLen;
          textX = x2 - 5;
          textAlign = "right";
        }
      } else {
        x1 = (points[1][0] + points[2][0]) / 2;
        y1 = (points[1][1] + points[2][1]) / 2;
        if (orient === "horizontal") {
          y2 = y1 + labelLineLen;
          textY = y2 + 5;
          textAlign = "center";
        } else {
          x2 = x1 + labelLineLen;
          textX = x2 + 5;
          textAlign = "left";
        }
      }
      if (orient === "horizontal") {
        x2 = x1;
        textX = x2;
      } else {
        y2 = y1;
        textY = y2;
      }
      linePoints = [[x1, y1], [x2, y2]];
    }
    layout2.label = {
      linePoints,
      x: textX,
      y: textY,
      verticalAlign: "middle",
      textAlign,
      inside: isLabelInside
    };
  });
}
function funnelLayout(ecModel, api) {
  ecModel.eachSeriesByType("funnel", function(seriesModel) {
    var data = seriesModel.getData();
    var valueDim = data.mapDimension("value");
    var sort = seriesModel.get("sort");
    var viewRect = getViewRect(seriesModel, api);
    var orient = seriesModel.get("orient");
    var viewWidth = viewRect.width;
    var viewHeight = viewRect.height;
    var indices = getSortedIndices(data, sort);
    var x = viewRect.x;
    var y = viewRect.y;
    var sizeExtent = orient === "horizontal" ? [number.parsePercent(seriesModel.get("minSize"), viewHeight), number.parsePercent(seriesModel.get("maxSize"), viewHeight)] : [number.parsePercent(seriesModel.get("minSize"), viewWidth), number.parsePercent(seriesModel.get("maxSize"), viewWidth)];
    var dataExtent = data.getDataExtent(valueDim);
    var min = seriesModel.get("min");
    var max = seriesModel.get("max");
    if (min == null) {
      min = Math.min(dataExtent[0], 0);
    }
    if (max == null) {
      max = dataExtent[1];
    }
    var funnelAlign = seriesModel.get("funnelAlign");
    var gap = seriesModel.get("gap");
    var viewSize = orient === "horizontal" ? viewWidth : viewHeight;
    var itemSize = (viewSize - gap * (data.count() - 1)) / data.count();
    var getLinePoints = function(idx2, offset) {
      if (orient === "horizontal") {
        var val_1 = data.get(valueDim, idx2) || 0;
        var itemHeight = number.linearMap(val_1, [min, max], sizeExtent, true);
        var y0 = void 0;
        switch (funnelAlign) {
          case "top":
            y0 = y;
            break;
          case "center":
            y0 = y + (viewHeight - itemHeight) / 2;
            break;
          case "bottom":
            y0 = y + (viewHeight - itemHeight);
            break;
        }
        return [[offset, y0], [offset, y0 + itemHeight]];
      }
      var val = data.get(valueDim, idx2) || 0;
      var itemWidth = number.linearMap(val, [min, max], sizeExtent, true);
      var x0;
      switch (funnelAlign) {
        case "left":
          x0 = x;
          break;
        case "center":
          x0 = x + (viewWidth - itemWidth) / 2;
          break;
        case "right":
          x0 = x + viewWidth - itemWidth;
          break;
      }
      return [[x0, offset], [x0 + itemWidth, offset]];
    };
    if (sort === "ascending") {
      itemSize = -itemSize;
      gap = -gap;
      if (orient === "horizontal") {
        x += viewWidth;
      } else {
        y += viewHeight;
      }
      indices = indices.reverse();
    }
    for (var i = 0; i < indices.length; i++) {
      var idx = indices[i];
      var nextIdx = indices[i + 1];
      var itemModel = data.getItemModel(idx);
      if (orient === "horizontal") {
        var width = itemModel.get(["itemStyle", "width"]);
        if (width == null) {
          width = itemSize;
        } else {
          width = number.parsePercent(width, viewWidth);
          if (sort === "ascending") {
            width = -width;
          }
        }
        var start = getLinePoints(idx, x);
        var end = getLinePoints(nextIdx, x + width);
        x += width + gap;
        data.setItemLayout(idx, {
          points: start.concat(end.slice().reverse())
        });
      } else {
        var height = itemModel.get(["itemStyle", "height"]);
        if (height == null) {
          height = itemSize;
        } else {
          height = number.parsePercent(height, viewHeight);
          if (sort === "ascending") {
            height = -height;
          }
        }
        var start = getLinePoints(idx, y);
        var end = getLinePoints(nextIdx, y + height);
        y += height + gap;
        data.setItemLayout(idx, {
          points: start.concat(end.slice().reverse())
        });
      }
    }
    labelLayout(data);
  });
}
exports.default = funnelLayout;
