import BoundingRect from "../core/BoundingRect.mjs";
import LRU from "../core/LRU.mjs";
import { platformApi, DEFAULT_FONT } from "../core/platform.mjs";
var textWidthCache = {};
function getWidth(text, font) {
  font = font || DEFAULT_FONT;
  var cacheOfFont = textWidthCache[font];
  if (!cacheOfFont) {
    cacheOfFont = textWidthCache[font] = new LRU(500);
  }
  var width = cacheOfFont.get(text);
  if (width == null) {
    width = platformApi.measureText(text, font).width;
    cacheOfFont.put(text, width);
  }
  return width;
}
function innerGetBoundingRect(text, font, textAlign, textBaseline) {
  var width = getWidth(text, font);
  var height = getLineHeight(font);
  var x = adjustTextX(0, width, textAlign);
  var y = adjustTextY(0, height, textBaseline);
  var rect = new BoundingRect(x, y, width, height);
  return rect;
}
function getBoundingRect(text, font, textAlign, textBaseline) {
  var textLines = ((text || "") + "").split("\n");
  var len = textLines.length;
  if (len === 1) {
    return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline);
  } else {
    var uniondRect = new BoundingRect(0, 0, 0, 0);
    for (var i = 0; i < textLines.length; i++) {
      var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline);
      i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect);
    }
    return uniondRect;
  }
}
function adjustTextX(x, width, textAlign) {
  if (textAlign === "right") {
    x -= width;
  } else if (textAlign === "center") {
    x -= width / 2;
  }
  return x;
}
function adjustTextY(y, height, verticalAlign) {
  if (verticalAlign === "middle") {
    y -= height / 2;
  } else if (verticalAlign === "bottom") {
    y -= height;
  }
  return y;
}
function getLineHeight(font) {
  return getWidth("国", font);
}
function parsePercent(value, maxValue) {
  if (typeof value === "string") {
    if (value.lastIndexOf("%") >= 0) {
      return parseFloat(value) / 100 * maxValue;
    }
    return parseFloat(value);
  }
  return value;
}
function calculateTextPosition(out, opts, rect) {
  var textPosition = opts.position || "inside";
  var distance = opts.distance != null ? opts.distance : 5;
  var height = rect.height;
  var width = rect.width;
  var halfHeight = height / 2;
  var x = rect.x;
  var y = rect.y;
  var textAlign = "left";
  var textVerticalAlign = "top";
  if (textPosition instanceof Array) {
    x += parsePercent(textPosition[0], rect.width);
    y += parsePercent(textPosition[1], rect.height);
    textAlign = null;
    textVerticalAlign = null;
  } else {
    switch (textPosition) {
      case "left":
        x -= distance;
        y += halfHeight;
        textAlign = "right";
        textVerticalAlign = "middle";
        break;
      case "right":
        x += distance + width;
        y += halfHeight;
        textVerticalAlign = "middle";
        break;
      case "top":
        x += width / 2;
        y -= distance;
        textAlign = "center";
        textVerticalAlign = "bottom";
        break;
      case "bottom":
        x += width / 2;
        y += height + distance;
        textAlign = "center";
        break;
      case "inside":
        x += width / 2;
        y += halfHeight;
        textAlign = "center";
        textVerticalAlign = "middle";
        break;
      case "insideLeft":
        x += distance;
        y += halfHeight;
        textVerticalAlign = "middle";
        break;
      case "insideRight":
        x += width - distance;
        y += halfHeight;
        textAlign = "right";
        textVerticalAlign = "middle";
        break;
      case "insideTop":
        x += width / 2;
        y += distance;
        textAlign = "center";
        break;
      case "insideBottom":
        x += width / 2;
        y += height - distance;
        textAlign = "center";
        textVerticalAlign = "bottom";
        break;
      case "insideTopLeft":
        x += distance;
        y += distance;
        break;
      case "insideTopRight":
        x += width - distance;
        y += distance;
        textAlign = "right";
        break;
      case "insideBottomLeft":
        x += distance;
        y += height - distance;
        textVerticalAlign = "bottom";
        break;
      case "insideBottomRight":
        x += width - distance;
        y += height - distance;
        textAlign = "right";
        textVerticalAlign = "bottom";
        break;
    }
  }
  out = out || {};
  out.x = x;
  out.y = y;
  out.align = textAlign;
  out.verticalAlign = textVerticalAlign;
  return out;
}
export {
  adjustTextX,
  adjustTextY,
  calculateTextPosition,
  getBoundingRect,
  getLineHeight,
  getWidth,
  innerGetBoundingRect,
  parsePercent
};
