"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const strings = require("../../../base/common/strings.js");
const lineTokens = require("../../common/tokens/lineTokens.js");
const languages = require("../../common/languages.js");
const viewLineRenderer = require("../../common/viewLayout/viewLineRenderer.js");
const viewModel = require("../../common/viewModel.js");
const monarchLexer = require("../common/monarch/monarchLexer.js");
var __awaiter = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function(resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function(resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
var _a;
const ttPolicy = (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy("standaloneColorizer", { createHTML: (value) => value });
class Colorizer {
  static colorizeElement(themeService, languageService, domNode, options) {
    options = options || {};
    const theme = options.theme || "vs";
    const mimeType = options.mimeType || domNode.getAttribute("lang") || domNode.getAttribute("data-lang");
    if (!mimeType) {
      console.error("Mode not detected");
      return Promise.resolve();
    }
    const languageId = languageService.getLanguageIdByMimeType(mimeType) || mimeType;
    themeService.setTheme(theme);
    const text = domNode.firstChild ? domNode.firstChild.nodeValue : "";
    domNode.className += " " + theme;
    const render = (str) => {
      var _a2;
      const trustedhtml = (_a2 = ttPolicy === null || ttPolicy === void 0 ? void 0 : ttPolicy.createHTML(str)) !== null && _a2 !== void 0 ? _a2 : str;
      domNode.innerHTML = trustedhtml;
    };
    return this.colorize(languageService, text || "", languageId, options).then(render, (err) => console.error(err));
  }
  static colorize(languageService, text, languageId, options) {
    return __awaiter(this, void 0, void 0, function* () {
      const languageIdCodec = languageService.languageIdCodec;
      let tabSize = 4;
      if (options && typeof options.tabSize === "number") {
        tabSize = options.tabSize;
      }
      if (strings.startsWithUTF8BOM(text)) {
        text = text.substr(1);
      }
      const lines = strings.splitLines(text);
      if (!languageService.isRegisteredLanguageId(languageId)) {
        return _fakeColorize(lines, tabSize, languageIdCodec);
      }
      const tokenizationSupport = yield languages.TokenizationRegistry.getOrCreate(languageId);
      if (tokenizationSupport) {
        return _colorize(lines, tabSize, tokenizationSupport, languageIdCodec);
      }
      return _fakeColorize(lines, tabSize, languageIdCodec);
    });
  }
  static colorizeLine(line, mightContainNonBasicASCII, mightContainRTL, tokens, tabSize = 4) {
    const isBasicASCII = viewModel.ViewLineRenderingData.isBasicASCII(line, mightContainNonBasicASCII);
    const containsRTL = viewModel.ViewLineRenderingData.containsRTL(line, isBasicASCII, mightContainRTL);
    const renderResult = viewLineRenderer.renderViewLine2(new viewLineRenderer.RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, tokens, [], tabSize, 0, 0, 0, 0, -1, "none", false, false, null));
    return renderResult.html;
  }
  static colorizeModelLine(model, lineNumber, tabSize = 4) {
    const content = model.getLineContent(lineNumber);
    model.forceTokenization(lineNumber);
    const tokens = model.getLineTokens(lineNumber);
    const inflatedTokens = tokens.inflate();
    return this.colorizeLine(content, model.mightContainNonBasicASCII(), model.mightContainRTL(), inflatedTokens, tabSize);
  }
}
function _colorize(lines, tabSize, tokenizationSupport, languageIdCodec) {
  return new Promise((c, e) => {
    const execute = () => {
      const result = _actualColorize(lines, tabSize, tokenizationSupport, languageIdCodec);
      if (tokenizationSupport instanceof monarchLexer.MonarchTokenizer) {
        const status = tokenizationSupport.getLoadStatus();
        if (status.loaded === false) {
          status.promise.then(execute, e);
          return;
        }
      }
      c(result);
    };
    execute();
  });
}
function _fakeColorize(lines, tabSize, languageIdCodec) {
  let html = [];
  const defaultMetadata = (0 << 10 | 1 << 14 | 2 << 23) >>> 0;
  const tokens = new Uint32Array(2);
  tokens[0] = 0;
  tokens[1] = defaultMetadata;
  for (let i = 0, length = lines.length; i < length; i++) {
    const line = lines[i];
    tokens[0] = line.length;
    const lineTokens$1 = new lineTokens.LineTokens(tokens, line, languageIdCodec);
    const isBasicASCII = viewModel.ViewLineRenderingData.isBasicASCII(
      line,
      /* check for basic ASCII */
      true
    );
    const containsRTL = viewModel.ViewLineRenderingData.containsRTL(
      line,
      isBasicASCII,
      /* check for RTL */
      true
    );
    const renderResult = viewLineRenderer.renderViewLine2(new viewLineRenderer.RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, lineTokens$1, [], tabSize, 0, 0, 0, 0, -1, "none", false, false, null));
    html = html.concat(renderResult.html);
    html.push("<br/>");
  }
  return html.join("");
}
function _actualColorize(lines, tabSize, tokenizationSupport, languageIdCodec) {
  let html = [];
  let state = tokenizationSupport.getInitialState();
  for (let i = 0, length = lines.length; i < length; i++) {
    const line = lines[i];
    const tokenizeResult = tokenizationSupport.tokenizeEncoded(line, true, state);
    lineTokens.LineTokens.convertToEndOffset(tokenizeResult.tokens, line.length);
    const lineTokens$1 = new lineTokens.LineTokens(tokenizeResult.tokens, line, languageIdCodec);
    const isBasicASCII = viewModel.ViewLineRenderingData.isBasicASCII(
      line,
      /* check for basic ASCII */
      true
    );
    const containsRTL = viewModel.ViewLineRenderingData.containsRTL(
      line,
      isBasicASCII,
      /* check for RTL */
      true
    );
    const renderResult = viewLineRenderer.renderViewLine2(new viewLineRenderer.RenderLineInput(false, true, line, false, isBasicASCII, containsRTL, 0, lineTokens$1.inflate(), [], tabSize, 0, 0, 0, 0, -1, "none", false, false, null));
    html = html.concat(renderResult.html);
    html.push("<br/>");
    state = tokenizeResult.endState;
  }
  return html.join("");
}
exports.Colorizer = Colorizer;
