import { ExtensionType } from '../../../extensions/Extensions.mjs';
import { isSafari } from '../../../utils/isSafari.mjs';
import { warn } from '../../../utils/logging/warn.mjs';
import { BigPool } from '../../../utils/pool/PoolGroup.mjs';
import { TexturePool } from '../../renderers/shared/texture/TexturePool.mjs';
import { RendererType } from '../../renderers/types.mjs';
import { extractFontFamilies } from './utils/extractFontFamilies.mjs';
import { getFontCss } from './utils/getFontCss.mjs';
import { getPo2TextureFromSource } from './utils/getPo2TextureFromSource.mjs';
import { getSVGUrl } from './utils/getSVGUrl.mjs';
import { getTemporaryCanvasFromImage } from './utils/getTemporaryCanvasFromImage.mjs';
import { loadSVGImage } from './utils/loadSVGImage.mjs';
import { measureHtmlText } from './utils/measureHtmlText..mjs';

const nssvg = "http://www.w3.org/2000/svg";
const nsxhtml = "http://www.w3.org/1999/xhtml";
const FontStylePromiseCache = /* @__PURE__ */ new Map();
class HTMLTextRenderData {
  constructor() {
    this.svgRoot = document.createElementNS(nssvg, "svg");
    this.foreignObject = document.createElementNS(nssvg, "foreignObject");
    this.domElement = document.createElementNS(nsxhtml, "div");
    this.styleElement = document.createElementNS(nsxhtml, "style");
    this.image = new Image();
    const { foreignObject, svgRoot, styleElement, domElement } = this;
    foreignObject.setAttribute("width", "10000");
    foreignObject.setAttribute("height", "10000");
    foreignObject.style.overflow = "hidden";
    svgRoot.appendChild(foreignObject);
    foreignObject.appendChild(styleElement);
    foreignObject.appendChild(domElement);
  }
}
class HTMLTextSystem {
  constructor(renderer) {
    this._activeTextures = {};
    this._createCanvas = renderer.type === RendererType.WEBGPU;
  }
  getTexture(options) {
    return this._buildTexturePromise(options.text, options.resolution, options.style);
  }
  getManagedTexture(text, resolution, style, textKey) {
    if (this._activeTextures[textKey]) {
      this._increaseReferenceCount(textKey);
      return this._activeTextures[textKey].promise;
    }
    const promise = this._buildTexturePromise(text, resolution, style).then((texture) => {
      this._activeTextures[textKey].texture = texture;
      return texture;
    });
    this._activeTextures[textKey] = {
      texture: null,
      promise,
      usageCount: 1
    };
    return promise;
  }
  async _buildTexturePromise(text, resolution, style) {
    const htmlTextData = BigPool.get(HTMLTextRenderData);
    const fontFamilies = extractFontFamilies(text, style.fontFamily);
    const fontCSS = await getFontCss(fontFamilies, style);
    const measured = measureHtmlText(text, style, fontCSS, htmlTextData);
    const width = Math.ceil(Math.ceil(Math.max(1, measured.width) + style.padding * 2) * resolution);
    const height = Math.ceil(Math.ceil(Math.max(1, measured.height) + style.padding * 2) * resolution);
    const image = htmlTextData.image;
    image.width = width | 0;
    image.height = height | 0;
    const svgURL = getSVGUrl(text, style, resolution, fontCSS, htmlTextData);
    await loadSVGImage(image, svgURL, isSafari() && fontFamilies.length > 0);
    let resource = image;
    if (this._createCanvas) {
      resource = getTemporaryCanvasFromImage(image, resolution);
    }
    BigPool.return(htmlTextData);
    return getPo2TextureFromSource(resource, resolution);
  }
  _increaseReferenceCount(textKey) {
    this._activeTextures[textKey].usageCount++;
  }
  decreaseReferenceCount(textKey) {
    const activeTexture = this._activeTextures[textKey];
    if (!activeTexture)
      return;
    activeTexture.usageCount--;
    if (activeTexture.usageCount === 0) {
      if (activeTexture.texture) {
        this._cleanUp(activeTexture);
      } else {
        activeTexture.promise.then((texture) => {
          activeTexture.texture = texture;
          this._cleanUp(activeTexture);
        }).catch(() => {
          warn("HTMLTextSystem: Failed to clean texture");
        });
      }
      this._activeTextures[textKey] = null;
    }
  }
  _cleanUp(activeTexture) {
    TexturePool.returnTexture(activeTexture.texture);
    activeTexture.texture.source.resource = null;
    activeTexture.texture.source.uploadMethodId = "unknown";
  }
  getReferenceCount(textKey) {
    return this._activeTextures[textKey].usageCount;
  }
  destroy() {
    this._activeTextures = null;
  }
}
/** @ignore */
HTMLTextSystem.extension = {
  type: [
    ExtensionType.WebGLSystem,
    ExtensionType.WebGPUSystem,
    ExtensionType.CanvasSystem
  ],
  name: "htmlText"
};
HTMLTextSystem.defaultFontOptions = {
  fontFamily: "Arial",
  fontStyle: "normal",
  fontWeight: "normal"
};

export { FontStylePromiseCache, HTMLTextRenderData, HTMLTextSystem };
//# sourceMappingURL=HTMLTextSystem.mjs.map
