var __decorate = (this && this.__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 = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import { h } from '../../../../base/browser/dom.js';
import { Button } from '../../../../base/browser/ui/button/button.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
import { autorun, derived, observableFromEvent } from '../../../../base/common/observable.js';
import { globalTransaction, observableValue } from '../../../../base/common/observableInternal/base.js';
import { DiffEditorWidget } from '../diffEditor/diffEditorWidget.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
export class TemplateData {
    constructor(viewModel, entry) {
        this.viewModel = viewModel;
        this.entry = entry;
    }
    getId() {
        return this.entry;
    }
}
let DiffEditorItemTemplate = class DiffEditorItemTemplate extends Disposable {
    constructor(_container, _overflowWidgetsDomNode, _workbenchUIElementFactory, _instantiationService) {
        super();
        this._container = _container;
        this._overflowWidgetsDomNode = _overflowWidgetsDomNode;
        this._workbenchUIElementFactory = _workbenchUIElementFactory;
        this._instantiationService = _instantiationService;
        this._contentHeight = observableValue(this, 500);
        this.height = derived(this, reader => {
            const h = this._collapsed.read(reader) ? 0 : this._contentHeight.read(reader);
            return h + this._outerEditorHeight;
        });
        this._modifiedContentWidth = observableValue(this, 0);
        this._modifiedWidth = observableValue(this, 0);
        this._originalContentWidth = observableValue(this, 0);
        this._originalWidth = observableValue(this, 0);
        this.maxScroll = derived(this, reader => {
            const scroll1 = this._modifiedContentWidth.read(reader) - this._modifiedWidth.read(reader);
            const scroll2 = this._originalContentWidth.read(reader) - this._originalWidth.read(reader);
            if (scroll1 > scroll2) {
                return { maxScroll: scroll1, width: this._modifiedWidth.read(reader) };
            }
            else {
                return { maxScroll: scroll2, width: this._originalWidth.read(reader) };
            }
        });
        this._collapsed = observableValue(this, false);
        this._elements = h('div', {
            style: {
                display: 'flex',
                flexDirection: 'column',
            }
        }, [
            h('div', {
                style: {
                    display: 'flex',
                    flexDirection: 'column',
                    flex: '1',
                    overflow: 'hidden',
                }
            }, [
                h('div@header', { style: { display: 'flex', alignItems: 'center', padding: '8px 5px', color: 'var(--vscode-foreground)', background: 'var(--vscode-editor-background)', zIndex: '10000' } }, [
                    h('div.expand-button@collapseButton', { style: { margin: '0 5px' } }),
                    h('div.show-file-icons@title', { style: { fontSize: '14px', lineHeight: '22px' } }, []),
                ]),
                h('div', {
                    style: {
                        flex: '1',
                        display: 'flex',
                        flexDirection: 'column',
                    }
                }, [
                    h('div@editor', { style: { flex: '1' } }),
                ])
            ])
        ]);
        this.editor = this._register(this._instantiationService.createInstance(DiffEditorWidget, this._elements.editor, {
            overflowWidgetsDomNode: this._overflowWidgetsDomNode,
        }, {}));
        this.isModifedFocused = isFocused(this.editor.getModifiedEditor());
        this.isOriginalFocused = isFocused(this.editor.getOriginalEditor());
        this.isFocused = derived(this, reader => this.isModifedFocused.read(reader) || this.isOriginalFocused.read(reader));
        this._resourceLabel = this._workbenchUIElementFactory.createResourceLabel
            ? this._register(this._workbenchUIElementFactory.createResourceLabel(this._elements.title))
            : undefined;
        this._dataStore = new DisposableStore();
        const btn = new Button(this._elements.collapseButton, {});
        this._register(autorun(reader => {
            btn.element.className = '';
            btn.icon = this._collapsed.read(reader) ? Codicon.chevronRight : Codicon.chevronDown;
        }));
        this._register(btn.onDidClick(() => {
            this._collapsed.set(!this._collapsed.get(), undefined);
            this._elements.editor.style.display = this._collapsed.get() ? 'none' : 'block';
        }));
        this.editor.getModifiedEditor().onDidLayoutChange(e => {
            const width = this.editor.getModifiedEditor().getLayoutInfo().contentWidth;
            this._modifiedWidth.set(width, undefined);
        });
        this.editor.getOriginalEditor().onDidLayoutChange(e => {
            const width = this.editor.getOriginalEditor().getLayoutInfo().contentWidth;
            this._originalWidth.set(width, undefined);
        });
        this._register(this.editor.onDidContentSizeChange(e => {
            globalTransaction(tx => {
                this._contentHeight.set(e.contentHeight, tx);
                this._modifiedContentWidth.set(this.editor.getModifiedEditor().getContentWidth(), tx);
                this._originalContentWidth.set(this.editor.getOriginalEditor().getContentWidth(), tx);
            });
        }));
        this._container.appendChild(this._elements.root);
        this._outerEditorHeight = 38;
    }
    setScrollLeft(left) {
        if (this._modifiedContentWidth.get() - this._modifiedWidth.get() > this._originalContentWidth.get() - this._originalWidth.get()) {
            this.editor.getModifiedEditor().setScrollLeft(left);
        }
        else {
            this.editor.getOriginalEditor().setScrollLeft(left);
        }
    }
    setData(data) {
        var _a;
        (_a = this._resourceLabel) === null || _a === void 0 ? void 0 : _a.setUri(data.viewModel.model.modified.uri);
        this._dataStore.clear();
        function updateOptions(options) {
            return Object.assign(Object.assign({}, options), { scrollBeyondLastLine: false, hideUnchangedRegions: {
                    enabled: true,
                }, scrollbar: {
                    vertical: 'hidden',
                    horizontal: 'hidden',
                    handleMouseWheel: false,
                }, renderOverviewRuler: false, fixedOverflowWidgets: true });
        }
        if (data.entry.onOptionsDidChange) {
            this._dataStore.add(data.entry.onOptionsDidChange(() => {
                var _a;
                this.editor.updateOptions(updateOptions((_a = data.entry.options) !== null && _a !== void 0 ? _a : {}));
            }));
        }
        globalTransaction(tx => {
            var _a;
            this.editor.setModel(data.viewModel, tx);
            this.editor.updateOptions(updateOptions((_a = data.entry.options) !== null && _a !== void 0 ? _a : {}));
        });
    }
    render(verticalRange, width, editorScroll, viewPort) {
        this._elements.root.style.visibility = 'visible';
        this._elements.root.style.top = `${verticalRange.start}px`;
        this._elements.root.style.height = `${verticalRange.length}px`;
        this._elements.root.style.width = `${width}px`;
        this._elements.root.style.position = 'absolute';
        // For sticky scroll
        this._elements.header.style.transform = `translateY(${Math.max(0, Math.min(verticalRange.length - this._elements.header.clientHeight, viewPort.start - verticalRange.start))}px)`;
        globalTransaction(tx => {
            this.editor.layout({
                width: width,
                height: verticalRange.length - this._outerEditorHeight,
            });
        });
        this.editor.getOriginalEditor().setScrollTop(editorScroll);
    }
    hide() {
        this._elements.root.style.top = `-100000px`;
        this._elements.root.style.visibility = 'hidden'; // Some editor parts are still visible
    }
};
DiffEditorItemTemplate = __decorate([
    __param(3, IInstantiationService)
], DiffEditorItemTemplate);
export { DiffEditorItemTemplate };
function isFocused(editor) {
    return observableFromEvent(h => {
        const store = new DisposableStore();
        store.add(editor.onDidFocusEditorWidget(() => h(true)));
        store.add(editor.onDidBlurEditorWidget(() => h(false)));
        return store;
    }, () => editor.hasWidgetFocus());
}
