import { append, $, reset } from "../../dom.mjs";
import { renderLabelWithIcons } from "../iconLabel/iconLabels.mjs";
import { equals } from "../../../common/objects.mjs";
class HighlightedLabel {
  /**
   * Create a new {@link HighlightedLabel}.
   *
   * @param container The parent container to append to.
   */
  constructor(container, options) {
    var _a;
    this.text = "";
    this.title = "";
    this.highlights = [];
    this.didEverRender = false;
    this.supportIcons = (_a = options === null || options === void 0 ? void 0 : options.supportIcons) !== null && _a !== void 0 ? _a : false;
    this.domNode = append(container, $("span.monaco-highlighted-label"));
  }
  /**
   * The label's DOM node.
   */
  get element() {
    return this.domNode;
  }
  /**
   * Set the label and highlights.
   *
   * @param text The label to display.
   * @param highlights The ranges to highlight.
   * @param title An optional title for the hover tooltip.
   * @param escapeNewLines Whether to escape new lines.
   * @returns
   */
  set(text, highlights = [], title = "", escapeNewLines) {
    if (!text) {
      text = "";
    }
    if (escapeNewLines) {
      text = HighlightedLabel.escapeNewLines(text, highlights);
    }
    if (this.didEverRender && this.text === text && this.title === title && equals(this.highlights, highlights)) {
      return;
    }
    this.text = text;
    this.title = title;
    this.highlights = highlights;
    this.render();
  }
  render() {
    const children = [];
    let pos = 0;
    for (const highlight of this.highlights) {
      if (highlight.end === highlight.start) {
        continue;
      }
      if (pos < highlight.start) {
        const substring2 = this.text.substring(pos, highlight.start);
        children.push($("span", void 0, ...this.supportIcons ? renderLabelWithIcons(substring2) : [substring2]));
        pos = highlight.end;
      }
      const substring = this.text.substring(highlight.start, highlight.end);
      const element = $("span.highlight", void 0, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]);
      if (highlight.extraClasses) {
        element.classList.add(...highlight.extraClasses);
      }
      children.push(element);
      pos = highlight.end;
    }
    if (pos < this.text.length) {
      const substring = this.text.substring(pos);
      children.push($("span", void 0, ...this.supportIcons ? renderLabelWithIcons(substring) : [substring]));
    }
    reset(this.domNode, ...children);
    if (this.title) {
      this.domNode.title = this.title;
    } else {
      this.domNode.removeAttribute("title");
    }
    this.didEverRender = true;
  }
  static escapeNewLines(text, highlights) {
    let total = 0;
    let extra = 0;
    return text.replace(/\r\n|\r|\n/g, (match, offset) => {
      extra = match === "\r\n" ? -1 : 0;
      offset += total;
      for (const highlight of highlights) {
        if (highlight.end <= offset) {
          continue;
        }
        if (highlight.start >= offset) {
          highlight.start += extra;
        }
        if (highlight.end >= offset) {
          highlight.end += extra;
        }
      }
      total += extra;
      return "⏎";
    });
  }
}
export {
  HighlightedLabel
};
