var _a;
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
import * as dom from '../../../../base/browser/dom.js';
import { createStringBuilder } from '../../../common/core/stringBuilder.js';
import { RenderLineInput, renderViewLine } from '../../../common/viewLayout/viewLineRenderer.js';
import { LineDecoration } from '../../../common/viewLayout/lineDecorations.js';
import { Position } from '../../../common/core/position.js';
import './stickyScroll.css';
export class StickyScrollWidgetState {
    constructor(lineNumbers, lastLineRelativePosition) {
        this.lineNumbers = lineNumbers;
        this.lastLineRelativePosition = lastLineRelativePosition;
    }
}
const _ttPolicy = (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy('stickyScrollViewLayer', { createHTML: value => value });
export class StickyScrollWidget extends Disposable {
    constructor(_editor) {
        super();
        this._editor = _editor;
        this.rootDomNode = document.createElement('div');
        this.disposableStore = this._register(new DisposableStore());
        this.layoutInfo = this._editor.getLayoutInfo();
        this.rootDomNode = document.createElement('div');
        this.rootDomNode.className = 'sticky-widget';
        this.rootDomNode.style.width = `${this.layoutInfo.width - this.layoutInfo.minimap.minimapCanvasOuterWidth - this.layoutInfo.verticalScrollbarWidth}px`;
        this.lineNumbers = [];
        this.lastLineRelativePosition = 0;
        this.lineHeight = this._editor.getOption(61 /* EditorOption.lineHeight */);
        this._register(this._editor.onDidChangeConfiguration(e => {
            if (e.hasChanged(61 /* EditorOption.lineHeight */)) {
                this.lineHeight = this._editor.getOption(61 /* EditorOption.lineHeight */);
            }
        }));
    }
    getCurrentLines() {
        return this.lineNumbers;
    }
    setState(state) {
        this.disposableStore.clear();
        this.lineNumbers.length = 0;
        dom.clearNode(this.rootDomNode);
        this.lastLineRelativePosition = state.lastLineRelativePosition;
        this.lineNumbers = state.lineNumbers;
        this.renderRootNode();
    }
    getChildNode(index, line) {
        const child = document.createElement('div');
        const viewModel = this._editor._getViewModel();
        const viewLineNumber = viewModel.coordinatesConverter.convertModelPositionToViewPosition(new Position(line, 1)).lineNumber;
        const lineRenderingData = viewModel.getViewLineRenderingData(viewLineNumber);
        const layoutInfo = this._editor.getLayoutInfo();
        const width = layoutInfo.width - layoutInfo.minimap.minimapCanvasOuterWidth - layoutInfo.verticalScrollbarWidth;
        const minimapSide = this._editor.getOption(67 /* EditorOption.minimap */).side;
        const lineHeight = this._editor.getOption(61 /* EditorOption.lineHeight */);
        const lineNumberOption = this._editor.getOption(62 /* EditorOption.lineNumbers */);
        let actualInlineDecorations;
        try {
            actualInlineDecorations = LineDecoration.filter(lineRenderingData.inlineDecorations, viewLineNumber, lineRenderingData.minColumn, lineRenderingData.maxColumn);
        }
        catch (err) {
            actualInlineDecorations = [];
        }
        const renderLineInput = new RenderLineInput(true, true, lineRenderingData.content, lineRenderingData.continuesWithWrappedLine, lineRenderingData.isBasicASCII, lineRenderingData.containsRTL, 0, lineRenderingData.tokens, actualInlineDecorations, lineRenderingData.tabSize, lineRenderingData.startVisibleColumn, 1, 1, 1, 500, 'none', true, true, null);
        const sb = createStringBuilder(2000);
        renderViewLine(renderLineInput, sb);
        let newLine;
        if (_ttPolicy) {
            newLine = _ttPolicy.createHTML(sb.build());
        }
        else {
            newLine = sb.build();
        }
        const lineHTMLNode = document.createElement('span');
        lineHTMLNode.className = 'sticky-line';
        lineHTMLNode.style.lineHeight = `${lineHeight}px`;
        lineHTMLNode.innerHTML = newLine;
        const lineNumberHTMLNode = document.createElement('span');
        lineNumberHTMLNode.className = 'sticky-line';
        lineNumberHTMLNode.style.lineHeight = `${lineHeight}px`;
        if (minimapSide === 'left') {
            lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft - layoutInfo.minimap.minimapCanvasOuterWidth}px`;
        }
        else if (minimapSide === 'right') {
            lineNumberHTMLNode.style.width = `${layoutInfo.contentLeft}px`;
        }
        const innerLineNumberHTML = document.createElement('span');
        if (lineNumberOption.renderType === 1 /* RenderLineNumbersType.On */ || lineNumberOption.renderType === 3 /* RenderLineNumbersType.Interval */ && line % 10 === 0) {
            innerLineNumberHTML.innerText = line.toString();
        }
        else if (lineNumberOption.renderType === 2 /* RenderLineNumbersType.Relative */) {
            innerLineNumberHTML.innerText = Math.abs(line - this._editor.getPosition().lineNumber).toString();
        }
        innerLineNumberHTML.className = 'sticky-line-number';
        innerLineNumberHTML.style.lineHeight = `${lineHeight}px`;
        innerLineNumberHTML.style.width = `${layoutInfo.lineNumbersWidth}px`;
        if (minimapSide === 'left') {
            innerLineNumberHTML.style.paddingLeft = `${layoutInfo.lineNumbersLeft - layoutInfo.minimap.minimapCanvasOuterWidth}px`;
        }
        else if (minimapSide === 'right') {
            innerLineNumberHTML.style.paddingLeft = `${layoutInfo.lineNumbersLeft}px`;
        }
        lineNumberHTMLNode.appendChild(innerLineNumberHTML);
        this._editor.applyFontInfo(lineHTMLNode);
        this._editor.applyFontInfo(innerLineNumberHTML);
        child.appendChild(lineNumberHTMLNode);
        child.appendChild(lineHTMLNode);
        child.className = 'sticky-line-root';
        child.style.lineHeight = `${lineHeight}px`;
        child.style.width = `${width}px`;
        child.style.height = `${lineHeight}px`;
        child.style.zIndex = '0';
        // Special case for the last line of sticky scroll
        if (index === this.lineNumbers.length - 1) {
            child.style.position = 'relative';
            child.style.zIndex = '-1';
            child.style.top = this.lastLineRelativePosition + 'px';
        }
        this.disposableStore.add(dom.addDisposableListener(child, 'click', e => {
            e.stopPropagation();
            e.preventDefault();
            this._editor.revealPosition({ lineNumber: line - index, column: 1 });
        }));
        return child;
    }
    renderRootNode() {
        if (!this._editor._getViewModel()) {
            return;
        }
        for (const [index, line] of this.lineNumbers.entries()) {
            this.rootDomNode.appendChild(this.getChildNode(index, line));
        }
        const widgetHeight = this.lineNumbers.length * this.lineHeight + this.lastLineRelativePosition;
        this.rootDomNode.style.height = widgetHeight.toString() + 'px';
        const minimapSide = this._editor.getOption(67 /* EditorOption.minimap */).side;
        if (minimapSide === 'left') {
            this.rootDomNode.style.marginLeft = this._editor.getLayoutInfo().minimap.minimapCanvasOuterWidth + 'px';
        }
        else if (minimapSide === 'right') {
            this.rootDomNode.style.marginLeft = '0px';
        }
    }
    getId() {
        return 'editor.contrib.stickyScrollWidget';
    }
    getDomNode() {
        return this.rootDomNode;
    }
    getPosition() {
        return {
            preference: null
        };
    }
    dispose() {
        super.dispose();
        this.disposableStore.dispose();
    }
}
