/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import './list.css';
import { Disposable } from '../../../common/lifecycle';
import { range } from '../../../common/arrays';
import { List } from './listWidget';
import { Event } from '../../../common/event';
import { CancellationTokenSource } from '../../../common/cancellation';
var PagedRenderer = /** @class */ (function () {
    function PagedRenderer(renderer, modelProvider) {
        this.renderer = renderer;
        this.modelProvider = modelProvider;
    }
    Object.defineProperty(PagedRenderer.prototype, "templateId", {
        get: function () { return this.renderer.templateId; },
        enumerable: true,
        configurable: true
    });
    PagedRenderer.prototype.renderTemplate = function (container) {
        var data = this.renderer.renderTemplate(container);
        return { data: data, disposable: Disposable.None };
    };
    PagedRenderer.prototype.renderElement = function (index, _, data, height) {
        var _this = this;
        if (data.disposable) {
            data.disposable.dispose();
        }
        if (!data.data) {
            return;
        }
        var model = this.modelProvider();
        if (model.isResolved(index)) {
            return this.renderer.renderElement(model.get(index), index, data.data, height);
        }
        var cts = new CancellationTokenSource();
        var promise = model.resolve(index, cts.token);
        data.disposable = { dispose: function () { return cts.cancel(); } };
        this.renderer.renderPlaceholder(index, data.data);
        promise.then(function (entry) { return _this.renderer.renderElement(entry, index, data.data, height); });
    };
    PagedRenderer.prototype.disposeTemplate = function (data) {
        if (data.disposable) {
            data.disposable.dispose();
            data.disposable = undefined;
        }
        if (data.data) {
            this.renderer.disposeTemplate(data.data);
            data.data = undefined;
        }
    };
    return PagedRenderer;
}());
var PagedList = /** @class */ (function () {
    function PagedList(user, container, virtualDelegate, renderers, options) {
        var _this = this;
        if (options === void 0) { options = {}; }
        var pagedRenderers = renderers.map(function (r) { return new PagedRenderer(r, function () { return _this.model; }); });
        this.list = new List(user, container, virtualDelegate, pagedRenderers, options);
    }
    PagedList.prototype.getHTMLElement = function () {
        return this.list.getHTMLElement();
    };
    PagedList.prototype.isDOMFocused = function () {
        return this.list.getHTMLElement() === document.activeElement;
    };
    PagedList.prototype.domFocus = function () {
        this.list.domFocus();
    };
    Object.defineProperty(PagedList.prototype, "onDidFocus", {
        get: function () {
            return this.list.onDidFocus;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onDidBlur", {
        get: function () {
            return this.list.onDidBlur;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "widget", {
        get: function () {
            return this.list;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onDidDispose", {
        get: function () {
            return this.list.onDidDispose;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onFocusChange", {
        get: function () {
            var _this = this;
            return Event.map(this.list.onFocusChange, function (_a) {
                var elements = _a.elements, indexes = _a.indexes;
                return ({ elements: elements.map(function (e) { return _this._model.get(e); }), indexes: indexes });
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onOpen", {
        get: function () {
            var _this = this;
            return Event.map(this.list.onDidOpen, function (_a) {
                var elements = _a.elements, indexes = _a.indexes, browserEvent = _a.browserEvent;
                return ({ elements: elements.map(function (e) { return _this._model.get(e); }), indexes: indexes, browserEvent: browserEvent });
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onSelectionChange", {
        get: function () {
            var _this = this;
            return Event.map(this.list.onSelectionChange, function (_a) {
                var elements = _a.elements, indexes = _a.indexes;
                return ({ elements: elements.map(function (e) { return _this._model.get(e); }), indexes: indexes });
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onPin", {
        get: function () {
            var _this = this;
            return Event.map(this.list.onDidPin, function (_a) {
                var elements = _a.elements, indexes = _a.indexes;
                return ({ elements: elements.map(function (e) { return _this._model.get(e); }), indexes: indexes });
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "onContextMenu", {
        get: function () {
            var _this = this;
            return Event.map(this.list.onContextMenu, function (_a) {
                var element = _a.element, index = _a.index, anchor = _a.anchor, browserEvent = _a.browserEvent;
                return (typeof element === 'undefined' ? { element: element, index: index, anchor: anchor, browserEvent: browserEvent } : { element: _this._model.get(element), index: index, anchor: anchor, browserEvent: browserEvent });
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "model", {
        get: function () {
            return this._model;
        },
        set: function (model) {
            this._model = model;
            this.list.splice(0, this.list.length, range(model.length));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "length", {
        get: function () {
            return this.list.length;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "scrollTop", {
        get: function () {
            return this.list.scrollTop;
        },
        set: function (scrollTop) {
            this.list.scrollTop = scrollTop;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PagedList.prototype, "scrollLeft", {
        get: function () {
            return this.list.scrollLeft;
        },
        set: function (scrollLeft) {
            this.list.scrollLeft = scrollLeft;
        },
        enumerable: true,
        configurable: true
    });
    PagedList.prototype.open = function (indexes, browserEvent) {
        this.list.open(indexes, browserEvent);
    };
    PagedList.prototype.setFocus = function (indexes) {
        this.list.setFocus(indexes);
    };
    PagedList.prototype.focusNext = function (n, loop) {
        this.list.focusNext(n, loop);
    };
    PagedList.prototype.focusPrevious = function (n, loop) {
        this.list.focusPrevious(n, loop);
    };
    PagedList.prototype.focusNextPage = function () {
        this.list.focusNextPage();
    };
    PagedList.prototype.focusPreviousPage = function () {
        this.list.focusPreviousPage();
    };
    PagedList.prototype.getFocus = function () {
        return this.list.getFocus();
    };
    PagedList.prototype.setSelection = function (indexes) {
        this.list.setSelection(indexes);
    };
    PagedList.prototype.getSelection = function () {
        return this.list.getSelection();
    };
    PagedList.prototype.layout = function (height, width) {
        this.list.layout(height, width);
    };
    PagedList.prototype.toggleKeyboardNavigation = function () {
        this.list.toggleKeyboardNavigation();
    };
    PagedList.prototype.reveal = function (index, relativeTop) {
        this.list.reveal(index, relativeTop);
    };
    PagedList.prototype.style = function (styles) {
        this.list.style(styles);
    };
    PagedList.prototype.dispose = function () {
        this.list.dispose();
    };
    return PagedList;
}());
export { PagedList };
