"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const number = require("../../util/number.js");
require("../../util/graphic.js");
const util = require("../../../../../../zrender@5.4.4/node_modules/zrender/lib/core/util.js");
const labelGuideHelper = require("../../label/labelGuideHelper.js");
const labelLayoutHelper = require("../../label/labelLayoutHelper.js");
const Point = require("../../../../../../zrender@5.4.4/node_modules/zrender/lib/core/Point.js");
var RADIAN = Math.PI / 180;
function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
  if (list.length < 2) {
    return;
  }
  function recalculateXOnSemiToAlignOnEllipseCurve(semi) {
    var rB = semi.rB;
    var rB2 = rB * rB;
    for (var i2 = 0; i2 < semi.list.length; i2++) {
      var item = semi.list[i2];
      var dy = Math.abs(item.label.y - cy);
      var rA = r + item.len;
      var rA2 = rA * rA;
      var dx2 = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2);
      var newX = cx + (dx2 + item.len2) * dir;
      var deltaX = newX - item.label.x;
      var newTargetWidth = item.targetTextWidth - deltaX * dir;
      constrainTextWidth(item, newTargetWidth, true);
      item.label.x = newX;
    }
  }
  function recalculateX(items) {
    var topSemi = {
      list: [],
      maxY: 0
    };
    var bottomSemi = {
      list: [],
      maxY: 0
    };
    for (var i2 = 0; i2 < items.length; i2++) {
      if (items[i2].labelAlignTo !== "none") {
        continue;
      }
      var item = items[i2];
      var semi = item.label.y > cy ? bottomSemi : topSemi;
      var dy = Math.abs(item.label.y - cy);
      if (dy >= semi.maxY) {
        var dx2 = item.label.x - cx - item.len2 * dir;
        var rA = r + item.len;
        var rB = Math.abs(dx2) < rA ? Math.sqrt(dy * dy / (1 - dx2 * dx2 / rA / rA)) : rA;
        semi.rB = rB;
        semi.maxY = dy;
      }
      semi.list.push(item);
    }
    recalculateXOnSemiToAlignOnEllipseCurve(topSemi);
    recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi);
  }
  var len = list.length;
  for (var i = 0; i < len; i++) {
    if (list[i].position === "outer" && list[i].labelAlignTo === "labelLine") {
      var dx = list[i].label.x - farthestX;
      list[i].linePoints[1][0] += dx;
      list[i].label.x = farthestX;
    }
  }
  if (labelLayoutHelper.shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) {
    recalculateX(list);
  }
}
function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
  var leftList = [];
  var rightList = [];
  var leftmostX = Number.MAX_VALUE;
  var rightmostX = -Number.MAX_VALUE;
  for (var i = 0; i < labelLayoutList.length; i++) {
    var label = labelLayoutList[i].label;
    if (isPositionCenter(labelLayoutList[i])) {
      continue;
    }
    if (label.x < cx) {
      leftmostX = Math.min(leftmostX, label.x);
      leftList.push(labelLayoutList[i]);
    } else {
      rightmostX = Math.max(rightmostX, label.x);
      rightList.push(labelLayoutList[i]);
    }
  }
  for (var i = 0; i < labelLayoutList.length; i++) {
    var layout = labelLayoutList[i];
    if (!isPositionCenter(layout) && layout.linePoints) {
      if (layout.labelStyleWidth != null) {
        continue;
      }
      var label = layout.label;
      var linePoints = layout.linePoints;
      var targetTextWidth = void 0;
      if (layout.labelAlignTo === "edge") {
        if (label.x < cx) {
          targetTextWidth = linePoints[2][0] - layout.labelDistance - viewLeft - layout.edgeDistance;
        } else {
          targetTextWidth = viewLeft + viewWidth - layout.edgeDistance - linePoints[2][0] - layout.labelDistance;
        }
      } else if (layout.labelAlignTo === "labelLine") {
        if (label.x < cx) {
          targetTextWidth = leftmostX - viewLeft - layout.bleedMargin;
        } else {
          targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin;
        }
      } else {
        if (label.x < cx) {
          targetTextWidth = label.x - viewLeft - layout.bleedMargin;
        } else {
          targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
        }
      }
      layout.targetTextWidth = targetTextWidth;
      constrainTextWidth(layout, targetTextWidth);
    }
  }
  adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
  adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);
  for (var i = 0; i < labelLayoutList.length; i++) {
    var layout = labelLayoutList[i];
    if (!isPositionCenter(layout) && layout.linePoints) {
      var label = layout.label;
      var linePoints = layout.linePoints;
      var isAlignToEdge = layout.labelAlignTo === "edge";
      var padding = label.style.padding;
      var paddingH = padding ? padding[1] + padding[3] : 0;
      var extraPaddingH = label.style.backgroundColor ? 0 : paddingH;
      var realTextWidth = layout.rect.width + extraPaddingH;
      var dist = linePoints[1][0] - linePoints[2][0];
      if (isAlignToEdge) {
        if (label.x < cx) {
          linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance;
        } else {
          linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance - realTextWidth - layout.labelDistance;
        }
      } else {
        if (label.x < cx) {
          linePoints[2][0] = label.x + layout.labelDistance;
        } else {
          linePoints[2][0] = label.x - layout.labelDistance;
        }
        linePoints[1][0] = linePoints[2][0] + dist;
      }
      linePoints[1][1] = linePoints[2][1] = label.y;
    }
  }
}
function constrainTextWidth(layout, availableWidth, forceRecalculate) {
  if (forceRecalculate === void 0) {
    forceRecalculate = false;
  }
  if (layout.labelStyleWidth != null) {
    return;
  }
  var label = layout.label;
  var style = label.style;
  var textRect = layout.rect;
  var bgColor = style.backgroundColor;
  var padding = style.padding;
  var paddingH = padding ? padding[1] + padding[3] : 0;
  var overflow = style.overflow;
  var oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH);
  if (availableWidth < oldOuterWidth || forceRecalculate) {
    var oldHeight = textRect.height;
    if (overflow && overflow.match("break")) {
      label.setStyle("backgroundColor", null);
      label.setStyle("width", availableWidth - paddingH);
      var innerRect = label.getBoundingRect();
      label.setStyle("width", Math.ceil(innerRect.width));
      label.setStyle("backgroundColor", bgColor);
    } else {
      var availableInnerWidth = availableWidth - paddingH;
      var newWidth = availableWidth < oldOuterWidth ? availableInnerWidth : (
        // Current available width is enough, but the text may have
        // already been wrapped with a smaller available width.
        forceRecalculate ? availableInnerWidth > layout.unconstrainedWidth ? null : availableInnerWidth : (
          // Current available width is enough, so no need to
          // constrain.
          null
        )
      );
      label.setStyle("width", newWidth);
    }
    var newRect = label.getBoundingRect();
    textRect.width = newRect.width;
    var margin = (label.style.margin || 0) + 2.1;
    textRect.height = newRect.height + margin;
    textRect.y -= (textRect.height - oldHeight) / 2;
  }
}
function isPositionCenter(sectorShape) {
  return sectorShape.position === "center";
}
function pieLabelLayout(seriesModel) {
  var data = seriesModel.getData();
  var labelLayoutList = [];
  var cx;
  var cy;
  var hasLabelRotate = false;
  var minShowLabelRadian = (seriesModel.get("minShowLabelAngle") || 0) * RADIAN;
  var viewRect = data.getLayout("viewRect");
  var r = data.getLayout("r");
  var viewWidth = viewRect.width;
  var viewLeft = viewRect.x;
  var viewTop = viewRect.y;
  var viewHeight = viewRect.height;
  function setNotShow(el) {
    el.ignore = true;
  }
  function isLabelShown(label2) {
    if (!label2.ignore) {
      return true;
    }
    for (var key in label2.states) {
      if (label2.states[key].ignore === false) {
        return true;
      }
    }
    return false;
  }
  data.each(function(idx) {
    var sector = data.getItemGraphicEl(idx);
    var sectorShape = sector.shape;
    var label2 = sector.getTextContent();
    var labelLine2 = sector.getTextGuideLine();
    var itemModel = data.getItemModel(idx);
    var labelModel = itemModel.getModel("label");
    var labelPosition = labelModel.get("position") || itemModel.get(["emphasis", "label", "position"]);
    var labelDistance = labelModel.get("distanceToLabelLine");
    var labelAlignTo = labelModel.get("alignTo");
    var edgeDistance = number.parsePercent(labelModel.get("edgeDistance"), viewWidth);
    var bleedMargin = labelModel.get("bleedMargin");
    var labelLineModel = itemModel.getModel("labelLine");
    var labelLineLen = labelLineModel.get("length");
    labelLineLen = number.parsePercent(labelLineLen, viewWidth);
    var labelLineLen2 = labelLineModel.get("length2");
    labelLineLen2 = number.parsePercent(labelLineLen2, viewWidth);
    if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
      util.each(label2.states, setNotShow);
      label2.ignore = true;
      if (labelLine2) {
        util.each(labelLine2.states, setNotShow);
        labelLine2.ignore = true;
      }
      return;
    }
    if (!isLabelShown(label2)) {
      return;
    }
    var midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
    var nx = Math.cos(midAngle);
    var ny = Math.sin(midAngle);
    var textX;
    var textY;
    var linePoints2;
    var textAlign;
    cx = sectorShape.cx;
    cy = sectorShape.cy;
    var isLabelInside = labelPosition === "inside" || labelPosition === "inner";
    if (labelPosition === "center") {
      textX = sectorShape.cx;
      textY = sectorShape.cy;
      textAlign = "center";
    } else {
      var x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx;
      var y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy;
      textX = x1 + nx * 3;
      textY = y1 + ny * 3;
      if (!isLabelInside) {
        var x2 = x1 + nx * (labelLineLen + r - sectorShape.r);
        var y2 = y1 + ny * (labelLineLen + r - sectorShape.r);
        var x3 = x2 + (nx < 0 ? -1 : 1) * labelLineLen2;
        var y3 = y2;
        if (labelAlignTo === "edge") {
          textX = nx < 0 ? viewLeft + edgeDistance : viewLeft + viewWidth - edgeDistance;
        } else {
          textX = x3 + (nx < 0 ? -labelDistance : labelDistance);
        }
        textY = y3;
        linePoints2 = [[x1, y1], [x2, y2], [x3, y3]];
      }
      textAlign = isLabelInside ? "center" : labelAlignTo === "edge" ? nx > 0 ? "right" : "left" : nx > 0 ? "left" : "right";
    }
    var PI = Math.PI;
    var labelRotate = 0;
    var rotate = labelModel.get("rotate");
    if (util.isNumber(rotate)) {
      labelRotate = rotate * (PI / 180);
    } else if (labelPosition === "center") {
      labelRotate = 0;
    } else if (rotate === "radial" || rotate === true) {
      var radialAngle = nx < 0 ? -midAngle + PI : -midAngle;
      labelRotate = radialAngle;
    } else if (rotate === "tangential" && labelPosition !== "outside" && labelPosition !== "outer") {
      var rad = Math.atan2(nx, ny);
      if (rad < 0) {
        rad = PI * 2 + rad;
      }
      var isDown = ny > 0;
      if (isDown) {
        rad = PI + rad;
      }
      labelRotate = rad - PI;
    }
    hasLabelRotate = !!labelRotate;
    label2.x = textX;
    label2.y = textY;
    label2.rotation = labelRotate;
    label2.setStyle({
      verticalAlign: "middle"
    });
    if (!isLabelInside) {
      var textRect = label2.getBoundingRect().clone();
      textRect.applyTransform(label2.getComputedTransform());
      var margin = (label2.style.margin || 0) + 2.1;
      textRect.y -= margin / 2;
      textRect.height += margin;
      labelLayoutList.push({
        label: label2,
        labelLine: labelLine2,
        position: labelPosition,
        len: labelLineLen,
        len2: labelLineLen2,
        minTurnAngle: labelLineModel.get("minTurnAngle"),
        maxSurfaceAngle: labelLineModel.get("maxSurfaceAngle"),
        surfaceNormal: new Point.default(nx, ny),
        linePoints: linePoints2,
        textAlign,
        labelDistance,
        labelAlignTo,
        edgeDistance,
        bleedMargin,
        rect: textRect,
        unconstrainedWidth: textRect.width,
        labelStyleWidth: label2.style.width
      });
    } else {
      label2.setStyle({
        align: textAlign
      });
      var selectState2 = label2.states.select;
      if (selectState2) {
        selectState2.x += label2.x;
        selectState2.y += label2.y;
      }
    }
    sector.setTextConfig({
      inside: isLabelInside
    });
  });
  if (!hasLabelRotate && seriesModel.get("avoidLabelOverlap")) {
    avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
  }
  for (var i = 0; i < labelLayoutList.length; i++) {
    var layout = labelLayoutList[i];
    var label = layout.label;
    var labelLine = layout.labelLine;
    var notShowLabel = isNaN(label.x) || isNaN(label.y);
    if (label) {
      label.setStyle({
        align: layout.textAlign
      });
      if (notShowLabel) {
        util.each(label.states, setNotShow);
        label.ignore = true;
      }
      var selectState = label.states.select;
      if (selectState) {
        selectState.x += label.x;
        selectState.y += label.y;
      }
    }
    if (labelLine) {
      var linePoints = layout.linePoints;
      if (notShowLabel || !linePoints) {
        util.each(labelLine.states, setNotShow);
        labelLine.ignore = true;
      } else {
        labelGuideHelper.limitTurnAngle(linePoints, layout.minTurnAngle);
        labelGuideHelper.limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);
        labelLine.setShape({
          points: linePoints
        });
        label.__hostTarget.textGuideLineConfig = {
          anchor: new Point.default(linePoints[0][0], linePoints[0][1])
        };
      }
    }
  }
}
exports.default = pieLabelLayout;
