import { range } from "../../../common/arrays.mjs";
import { CancellationTokenSource } from "../../../common/cancellation.mjs";
import { Event } from "../../../common/event.mjs";
import { Disposable } from "../../../common/lifecycle.mjs";
import "./list.css.mjs";
import { List } from "./listWidget.mjs";
class PagedRenderer {
  constructor(renderer, modelProvider) {
    this.renderer = renderer;
    this.modelProvider = modelProvider;
  }
  get templateId() {
    return this.renderer.templateId;
  }
  renderTemplate(container) {
    const data = this.renderer.renderTemplate(container);
    return { data, disposable: Disposable.None };
  }
  renderElement(index, _, data, height) {
    if (data.disposable) {
      data.disposable.dispose();
    }
    if (!data.data) {
      return;
    }
    const model = this.modelProvider();
    if (model.isResolved(index)) {
      return this.renderer.renderElement(model.get(index), index, data.data, height);
    }
    const cts = new CancellationTokenSource();
    const promise = model.resolve(index, cts.token);
    data.disposable = { dispose: () => cts.cancel() };
    this.renderer.renderPlaceholder(index, data.data);
    promise.then((entry) => this.renderer.renderElement(entry, index, data.data, height));
  }
  disposeTemplate(data) {
    if (data.disposable) {
      data.disposable.dispose();
      data.disposable = void 0;
    }
    if (data.data) {
      this.renderer.disposeTemplate(data.data);
      data.data = void 0;
    }
  }
}
class PagedAccessibilityProvider {
  constructor(modelProvider, accessibilityProvider) {
    this.modelProvider = modelProvider;
    this.accessibilityProvider = accessibilityProvider;
  }
  getWidgetAriaLabel() {
    return this.accessibilityProvider.getWidgetAriaLabel();
  }
  getAriaLabel(index) {
    const model = this.modelProvider();
    if (!model.isResolved(index)) {
      return null;
    }
    return this.accessibilityProvider.getAriaLabel(model.get(index));
  }
}
function fromPagedListOptions(modelProvider, options) {
  return Object.assign(Object.assign({}, options), { accessibilityProvider: options.accessibilityProvider && new PagedAccessibilityProvider(modelProvider, options.accessibilityProvider) });
}
class PagedList {
  constructor(user, container, virtualDelegate, renderers, options = {}) {
    const modelProvider = () => this.model;
    const pagedRenderers = renderers.map((r) => new PagedRenderer(r, modelProvider));
    this.list = new List(user, container, virtualDelegate, pagedRenderers, fromPagedListOptions(modelProvider, options));
  }
  updateOptions(options) {
    this.list.updateOptions(options);
  }
  getHTMLElement() {
    return this.list.getHTMLElement();
  }
  get onDidFocus() {
    return this.list.onDidFocus;
  }
  get onDidDispose() {
    return this.list.onDidDispose;
  }
  get onMouseDblClick() {
    return Event.map(this.list.onMouseDblClick, ({ element, index, browserEvent }) => ({ element: element === void 0 ? void 0 : this._model.get(element), index, browserEvent }));
  }
  get onPointer() {
    return Event.map(this.list.onPointer, ({ element, index, browserEvent }) => ({ element: element === void 0 ? void 0 : this._model.get(element), index, browserEvent }));
  }
  get onDidChangeSelection() {
    return Event.map(this.list.onDidChangeSelection, ({ elements, indexes, browserEvent }) => ({ elements: elements.map((e) => this._model.get(e)), indexes, browserEvent }));
  }
  get model() {
    return this._model;
  }
  set model(model) {
    this._model = model;
    this.list.splice(0, this.list.length, range(model.length));
  }
  getFocus() {
    return this.list.getFocus();
  }
  getSelection() {
    return this.list.getSelection();
  }
  getSelectedElements() {
    return this.getSelection().map((i) => this.model.get(i));
  }
  style(styles) {
    this.list.style(styles);
  }
  dispose() {
    this.list.dispose();
  }
}
export {
  PagedList
};
