"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const dom = require("../../dom.js");
const highlightedLabel = require("../highlightedlabel/highlightedLabel.js");
const iconLabelHover = require("./iconLabelHover.js");
const lifecycle = require("../../../common/lifecycle.js");
const objects = require("../../../common/objects.js");
const range = require("../../../common/range.js");
require("./iconlabel.css.js");
class FastLabelNode {
  constructor(_element) {
    this._element = _element;
  }
  get element() {
    return this._element;
  }
  set textContent(content) {
    if (this.disposed || content === this._textContent) {
      return;
    }
    this._textContent = content;
    this._element.textContent = content;
  }
  set className(className) {
    if (this.disposed || className === this._className) {
      return;
    }
    this._className = className;
    this._element.className = className;
  }
  set empty(empty) {
    if (this.disposed || empty === this._empty) {
      return;
    }
    this._empty = empty;
    this._element.style.marginLeft = empty ? "0" : "";
  }
  dispose() {
    this.disposed = true;
  }
}
class IconLabel extends lifecycle.Disposable {
  constructor(container, options) {
    super();
    this.customHovers = /* @__PURE__ */ new Map();
    this.domNode = this._register(new FastLabelNode(dom.append(container, dom.$(".monaco-icon-label"))));
    this.labelContainer = dom.append(this.domNode.element, dom.$(".monaco-icon-label-container"));
    const nameContainer = dom.append(this.labelContainer, dom.$("span.monaco-icon-name-container"));
    this.descriptionContainer = this._register(new FastLabelNode(dom.append(this.labelContainer, dom.$("span.monaco-icon-description-container"))));
    if ((options === null || options === void 0 ? void 0 : options.supportHighlights) || (options === null || options === void 0 ? void 0 : options.supportIcons)) {
      this.nameNode = new LabelWithHighlights(nameContainer, !!options.supportIcons);
    } else {
      this.nameNode = new Label(nameContainer);
    }
    if (options === null || options === void 0 ? void 0 : options.supportDescriptionHighlights) {
      this.descriptionNodeFactory = () => new highlightedLabel.HighlightedLabel(dom.append(this.descriptionContainer.element, dom.$("span.label-description")), { supportIcons: !!options.supportIcons });
    } else {
      this.descriptionNodeFactory = () => this._register(new FastLabelNode(dom.append(this.descriptionContainer.element, dom.$("span.label-description"))));
    }
    this.hoverDelegate = options === null || options === void 0 ? void 0 : options.hoverDelegate;
  }
  get element() {
    return this.domNode.element;
  }
  setLabel(label, description, options) {
    const classes = ["monaco-icon-label"];
    if (options) {
      if (options.extraClasses) {
        classes.push(...options.extraClasses);
      }
      if (options.italic) {
        classes.push("italic");
      }
      if (options.strikethrough) {
        classes.push("strikethrough");
      }
    }
    this.domNode.className = classes.join(" ");
    this.setupHover((options === null || options === void 0 ? void 0 : options.descriptionTitle) ? this.labelContainer : this.element, options === null || options === void 0 ? void 0 : options.title);
    this.nameNode.setLabel(label, options);
    if (description || this.descriptionNode) {
      if (!this.descriptionNode) {
        this.descriptionNode = this.descriptionNodeFactory();
      }
      if (this.descriptionNode instanceof highlightedLabel.HighlightedLabel) {
        this.descriptionNode.set(description || "", options ? options.descriptionMatches : void 0);
        this.setupHover(this.descriptionNode.element, options === null || options === void 0 ? void 0 : options.descriptionTitle);
      } else {
        this.descriptionNode.textContent = description || "";
        this.setupHover(this.descriptionNode.element, (options === null || options === void 0 ? void 0 : options.descriptionTitle) || "");
        this.descriptionNode.empty = !description;
      }
    }
  }
  setupHover(htmlElement, tooltip) {
    const previousCustomHover = this.customHovers.get(htmlElement);
    if (previousCustomHover) {
      previousCustomHover.dispose();
      this.customHovers.delete(htmlElement);
    }
    if (!tooltip) {
      htmlElement.removeAttribute("title");
      return;
    }
    if (!this.hoverDelegate) {
      iconLabelHover.setupNativeHover(htmlElement, tooltip);
    } else {
      const hoverDisposable = iconLabelHover.setupCustomHover(this.hoverDelegate, htmlElement, tooltip);
      if (hoverDisposable) {
        this.customHovers.set(htmlElement, hoverDisposable);
      }
    }
  }
  dispose() {
    super.dispose();
    for (const disposable of this.customHovers.values()) {
      disposable.dispose();
    }
    this.customHovers.clear();
  }
}
class Label {
  constructor(container) {
    this.container = container;
    this.label = void 0;
    this.singleLabel = void 0;
  }
  setLabel(label, options) {
    if (this.label === label && objects.equals(this.options, options)) {
      return;
    }
    this.label = label;
    this.options = options;
    if (typeof label === "string") {
      if (!this.singleLabel) {
        this.container.innerText = "";
        this.container.classList.remove("multiple");
        this.singleLabel = dom.append(this.container, dom.$("a.label-name", { id: options === null || options === void 0 ? void 0 : options.domId }));
      }
      this.singleLabel.textContent = label;
    } else {
      this.container.innerText = "";
      this.container.classList.add("multiple");
      this.singleLabel = void 0;
      for (let i = 0; i < label.length; i++) {
        const l = label[i];
        const id = (options === null || options === void 0 ? void 0 : options.domId) && `${options === null || options === void 0 ? void 0 : options.domId}_${i}`;
        dom.append(this.container, dom.$("a.label-name", { id, "data-icon-label-count": label.length, "data-icon-label-index": i, "role": "treeitem" }, l));
        if (i < label.length - 1) {
          dom.append(this.container, dom.$("span.label-separator", void 0, (options === null || options === void 0 ? void 0 : options.separator) || "/"));
        }
      }
    }
  }
}
function splitMatches(labels, separator, matches) {
  if (!matches) {
    return void 0;
  }
  let labelStart = 0;
  return labels.map((label) => {
    const labelRange = { start: labelStart, end: labelStart + label.length };
    const result = matches.map((match) => range.Range.intersect(labelRange, match)).filter((range$1) => !range.Range.isEmpty(range$1)).map(({ start, end }) => ({ start: start - labelStart, end: end - labelStart }));
    labelStart = labelRange.end + separator.length;
    return result;
  });
}
class LabelWithHighlights {
  constructor(container, supportIcons) {
    this.container = container;
    this.supportIcons = supportIcons;
    this.label = void 0;
    this.singleLabel = void 0;
  }
  setLabel(label, options) {
    if (this.label === label && objects.equals(this.options, options)) {
      return;
    }
    this.label = label;
    this.options = options;
    if (typeof label === "string") {
      if (!this.singleLabel) {
        this.container.innerText = "";
        this.container.classList.remove("multiple");
        this.singleLabel = new highlightedLabel.HighlightedLabel(dom.append(this.container, dom.$("a.label-name", { id: options === null || options === void 0 ? void 0 : options.domId })), { supportIcons: this.supportIcons });
      }
      this.singleLabel.set(label, options === null || options === void 0 ? void 0 : options.matches, void 0, options === null || options === void 0 ? void 0 : options.labelEscapeNewLines);
    } else {
      this.container.innerText = "";
      this.container.classList.add("multiple");
      this.singleLabel = void 0;
      const separator = (options === null || options === void 0 ? void 0 : options.separator) || "/";
      const matches = splitMatches(label, separator, options === null || options === void 0 ? void 0 : options.matches);
      for (let i = 0; i < label.length; i++) {
        const l = label[i];
        const m = matches ? matches[i] : void 0;
        const id = (options === null || options === void 0 ? void 0 : options.domId) && `${options === null || options === void 0 ? void 0 : options.domId}_${i}`;
        const name = dom.$("a.label-name", { id, "data-icon-label-count": label.length, "data-icon-label-index": i, "role": "treeitem" });
        const highlightedLabel$1 = new highlightedLabel.HighlightedLabel(dom.append(this.container, name), { supportIcons: this.supportIcons });
        highlightedLabel$1.set(l, m, void 0, options === null || options === void 0 ? void 0 : options.labelEscapeNewLines);
        if (i < label.length - 1) {
          dom.append(name, dom.$("span.label-separator", void 0, separator));
        }
      }
    }
  }
}
exports.IconLabel = IconLabel;
