"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const async = require("../../../../base/common/async.js");
const cancellation = require("../../../../base/common/cancellation.js");
const color = require("../../../../base/common/color.js");
const lifecycle = require("../../../../base/common/lifecycle.js");
const range = require("../../../common/core/range.js");
const color$1 = require("./color.js");
const colorDetector = require("./colorDetector.js");
const colorPickerModel = require("./colorPickerModel.js");
const colorPickerWidget = require("./colorPickerWidget.js");
const themeService = require("../../../../platform/theme/common/themeService.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
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());
  });
};
class ColorHover {
  constructor(owner, range2, model, provider) {
    this.owner = owner;
    this.range = range2;
    this.model = model;
    this.provider = provider;
    this.forceShowAtRange = true;
  }
  isValidForHoverAnchor(anchor) {
    return anchor.type === 1 && this.range.startColumn <= anchor.range.startColumn && this.range.endColumn >= anchor.range.endColumn;
  }
}
exports.ColorHoverParticipant = class ColorHoverParticipant {
  constructor(_editor, _themeService) {
    this._editor = _editor;
    this._themeService = _themeService;
    this.hoverOrdinal = 1;
  }
  computeSync(anchor, lineDecorations) {
    return [];
  }
  computeAsync(anchor, lineDecorations, token) {
    return async.AsyncIterableObject.fromPromise(this._computeAsync(anchor, lineDecorations, token));
  }
  _computeAsync(anchor, lineDecorations, token) {
    return __awaiter(this, void 0, void 0, function* () {
      if (!this._editor.hasModel()) {
        return [];
      }
      const colorDetector$1 = colorDetector.ColorDetector.get(this._editor);
      if (!colorDetector$1) {
        return [];
      }
      for (const d of lineDecorations) {
        if (!colorDetector$1.isColorDecorationId(d.id)) {
          continue;
        }
        const colorData = colorDetector$1.getColorData(d.range.getStartPosition());
        if (colorData) {
          const colorHover = yield this._createColorHover(this._editor.getModel(), colorData.colorInfo, colorData.provider);
          return [colorHover];
        }
      }
      return [];
    });
  }
  _createColorHover(editorModel, colorInfo, provider) {
    return __awaiter(this, void 0, void 0, function* () {
      const originalText = editorModel.getValueInRange(colorInfo.range);
      const { red, green, blue, alpha } = colorInfo.color;
      const rgba = new color.RGBA(Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255), alpha);
      const color$2 = new color.Color(rgba);
      const colorPresentations = yield color$1.getColorPresentations(editorModel, colorInfo, provider, cancellation.CancellationToken.None);
      const model = new colorPickerModel.ColorPickerModel(color$2, [], 0);
      model.colorPresentations = colorPresentations || [];
      model.guessColorPresentation(color$2, originalText);
      return new ColorHover(this, range.Range.lift(colorInfo.range), model, provider);
    });
  }
  renderHoverParts(context, hoverParts) {
    if (hoverParts.length === 0 || !this._editor.hasModel()) {
      return lifecycle.Disposable.None;
    }
    const disposables = new lifecycle.DisposableStore();
    const colorHover = hoverParts[0];
    const editorModel = this._editor.getModel();
    const model = colorHover.model;
    const widget = disposables.add(new colorPickerWidget.ColorPickerWidget(context.fragment, model, this._editor.getOption(
      129
      /* pixelRatio */
    ), this._themeService));
    context.setColorPicker(widget);
    let range$1 = new range.Range(colorHover.range.startLineNumber, colorHover.range.startColumn, colorHover.range.endLineNumber, colorHover.range.endColumn);
    const updateEditorModel = () => {
      let textEdits;
      let newRange;
      if (model.presentation.textEdit) {
        textEdits = [model.presentation.textEdit];
        newRange = new range.Range(model.presentation.textEdit.range.startLineNumber, model.presentation.textEdit.range.startColumn, model.presentation.textEdit.range.endLineNumber, model.presentation.textEdit.range.endColumn);
        const trackedRange = this._editor.getModel()._setTrackedRange(
          null,
          newRange,
          3
          /* GrowsOnlyWhenTypingAfter */
        );
        this._editor.pushUndoStop();
        this._editor.executeEdits("colorpicker", textEdits);
        newRange = this._editor.getModel()._getTrackedRange(trackedRange) || newRange;
      } else {
        textEdits = [{ range: range$1, text: model.presentation.label, forceMoveMarkers: false }];
        newRange = range$1.setEndPosition(range$1.endLineNumber, range$1.startColumn + model.presentation.label.length);
        this._editor.pushUndoStop();
        this._editor.executeEdits("colorpicker", textEdits);
      }
      if (model.presentation.additionalTextEdits) {
        textEdits = [...model.presentation.additionalTextEdits];
        this._editor.executeEdits("colorpicker", textEdits);
        context.hide();
      }
      this._editor.pushUndoStop();
      range$1 = newRange;
    };
    const updateColorPresentations = (color2) => {
      return color$1.getColorPresentations(editorModel, {
        range: range$1,
        color: {
          red: color2.rgba.r / 255,
          green: color2.rgba.g / 255,
          blue: color2.rgba.b / 255,
          alpha: color2.rgba.a
        }
      }, colorHover.provider, cancellation.CancellationToken.None).then((colorPresentations) => {
        model.colorPresentations = colorPresentations || [];
      });
    };
    disposables.add(model.onColorFlushed((color2) => {
      updateColorPresentations(color2).then(updateEditorModel);
    }));
    disposables.add(model.onDidChangeColor(updateColorPresentations));
    return disposables;
  }
};
exports.ColorHoverParticipant = __decorate([
  __param(1, themeService.IThemeService)
], exports.ColorHoverParticipant);
exports.ColorHover = ColorHover;
