"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getContentUrl = getContentUrl;
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _dom = require("../../ui/src/dom");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
let canvasEl = null;
let fontEl = null;
const fontCacheMaps = {};
function getMarkCanvas() {
  if (!canvasEl) {
    canvasEl = document.createElement('canvas');
    canvasEl.style.position = 'absolute';
    canvasEl.style.top = '0';
    canvasEl.style.left = '0';
  }
  return canvasEl;
}
function removeMarkElement(elem) {
  if (elem) {
    const parentEl = elem.parentNode;
    if (parentEl) {
      parentEl.removeChild(elem);
    }
  }
}
function calcFontWH(text, fontSize) {
  const fKey = `${fontSize}_${text}`;
  if (!fontCacheMaps[fKey]) {
    if (!fontEl) {
      fontEl = document.createElement('span');
    }
    if (!fontEl.parentNode) {
      document.body.append(fontEl);
    }
    fontEl.textContent = text;
    fontEl.style.fontSize = (0, _dom.toCssUnit)(fontSize);
    const width = fontEl.offsetWidth;
    const height = fontEl.offsetHeight;
    fontCacheMaps[fKey] = {
      width,
      height
    };
  }
  return fontCacheMaps[fKey];
}
function calcContentWH(contList) {
  let contentWidth = 0;
  let contentHeight = 0;
  contList.forEach(item => {
    contentWidth = Math.max(item.width, contentWidth);
    contentHeight = Math.max(item.height, contentHeight);
  });
  return {
    contentWidth,
    contentHeight
  };
}
function getFontConf(item, key, opts) {
  return (item.font ? item.font[key] : '') || (opts.font ? opts.font[key] : '');
}
function createMarkFont(contConf, defaultFontSize, opts) {
  const {
    offset
  } = opts;
  const text = _xeUtils.default.toValueString(contConf.textContent);
  const fontSize = _xeUtils.default.toNumber(getFontConf(contConf, 'fontSize', opts) || defaultFontSize) || 14;
  const [offsetX = 0, offsetY = 0] = offset ? _xeUtils.default.isArray(offset) ? offset : [offset, offset] : [];
  const {
    width,
    height
  } = calcFontWH(text, fontSize);
  return {
    text,
    fontSize,
    font: contConf.font,
    width: width + _xeUtils.default.toNumber(offsetX),
    height: height + _xeUtils.default.toNumber(offsetY)
  };
}
function drayFont(ctx, item, opts) {
  const fontWeight = getFontConf(item, 'fontWeight', opts);
  ctx.fillStyle = `${getFontConf(item, 'color', opts) || 'rgba(0, 0, 0, 0.15)'}`;
  ctx.font = [getFontConf(item, 'fontStyle', opts) || 'normal', fontWeight === 'bold' || fontWeight === 'bolder' ? 'bold' : '', (0, _dom.toCssUnit)(item.fontSize), getFontConf(item, 'fontFamily', opts) || 'sans-serif'].join(' ');
}
function getContentUrl(content, defaultFontSize, options) {
  const opts = Object.assign({}, options);
  const {
    rotate
  } = opts;
  const deg = _xeUtils.default.toNumber(rotate);
  const contList = (_xeUtils.default.isArray(content) ? content : [content]).map(item => {
    if (item) {
      if (item.textContent) {
        return createMarkFont(item, defaultFontSize, opts);
      }
      return createMarkFont({
        textContent: `${item}`
      }, defaultFontSize, opts);
    }
    return createMarkFont({
      textContent: ''
    }, defaultFontSize, opts);
  });
  removeMarkElement(fontEl);
  return new Promise(resolve => {
    const canvasEl = getMarkCanvas();
    if (!canvasEl.parentNode) {
      document.body.append(canvasEl);
    }
    const ctx = canvasEl.getContext('2d');
    if (ctx && contList.length) {
      const {
        gap
      } = opts;
      const gapList = gap ? _xeUtils.default.isArray(gap) ? gap : [gap, gap] : [];
      const gapX = _xeUtils.default.toNumber(gapList[0]);
      const gapY = _xeUtils.default.toNumber(gapList[1]);
      const {
        contentWidth
      } = calcContentWH(contList);
      const canvasWidth = contentWidth * 2 + gapX * 2 + gapX / 2;
      const canvasHeight = contentWidth * 2 + gapY;
      canvasEl.width = canvasWidth;
      canvasEl.height = canvasHeight;
      const drayX = gapX / 2;
      const drayY = contentWidth + gapY / 2;
      ctx.save();
      ctx.translate(drayX, drayY);
      ctx.rotate(deg * Math.PI / 180);
      ctx.translate(-drayX, -drayY);
      let txtOffsetY = 0;
      contList.forEach(item => {
        drayFont(ctx, item, opts);
        const txtX = drayX;
        const txtY = drayY + txtOffsetY;
        ctx.fillText(item.text, txtX, txtY, contentWidth);
        txtOffsetY += item.height;
      });
      const offsetX = gapX;
      const offsetY = gapY + contentWidth;
      txtOffsetY = 0;
      contList.forEach(item => {
        drayFont(ctx, item, opts);
        const txtX = drayX + offsetX;
        const txtY = drayY + txtOffsetY + offsetY;
        ctx.fillText(item.text, txtX, txtY, contentWidth);
        txtOffsetY += item.height;
      });
      ctx.restore();
      resolve(canvasEl.toDataURL());
      removeMarkElement(canvasEl);
    } else {
      resolve('');
      removeMarkElement(canvasEl);
    }
  });
}