import * as tslib_1 from "tslib";
import { abortAbleAll, isAsyncUpdate } from 'lineupengine';
import { round } from '../internal';
import { multiLevelGridCSSClass, forEachChild } from '../renderer/utils';
import { COLUMN_PADDING, cssClass } from '../styles';
import { createHeader, updateHeader } from './header';
import RenderColumn from './RenderColumn';
/** @internal */
var MultiLevelRenderColumn = /** @class */ (function (_super) {
    tslib_1.__extends(MultiLevelRenderColumn, _super);
    function MultiLevelRenderColumn(c, index, ctx, flags) {
        var _this = _super.call(this, c, index, ctx, flags) || this;
        _this.summaries = [];
        return _this;
    }
    Object.defineProperty(MultiLevelRenderColumn.prototype, "mc", {
        get: function () {
            return this.c;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiLevelRenderColumn.prototype, "width", {
        get: function () {
            return this.c.getWidth() + COLUMN_PADDING * this.mc.length;
        },
        enumerable: true,
        configurable: true
    });
    MultiLevelRenderColumn.prototype.createHeader = function () {
        var r = _super.prototype.createHeader.call(this);
        var wrapper = this.ctx.document.createElement('div');
        wrapper.classList.add(cssClass('nested'));
        wrapper.classList.add(multiLevelGridCSSClass(this.ctx.idPrefix, this.c));
        if (isAsyncUpdate(r)) {
            r.item.appendChild(wrapper);
        }
        else {
            r.appendChild(wrapper);
        }
        return this.updateNested(wrapper, r);
    };
    MultiLevelRenderColumn.prototype.matchChildren = function (wrapper, children) {
        var _this = this;
        if (this.summaries.length > children.length) {
            this.summaries.splice(children.length, this.summaries.length - children.length);
        }
        function matches(col, i) {
            //do both match?
            var n = wrapper.children[i];
            return n != null && n.dataset.colId === col.id;
        }
        if (children.every(matches)) {
            return;
        }
        var existing = new Set(children.map(function (d) { return d.id; }));
        //remove all that are not existing anymore
        forEachChild(wrapper, function (n) {
            var id = n.dataset.colId;
            if (!existing.has(id)) {
                wrapper.removeChild(n);
            }
        });
        children.forEach(function (cc, i) {
            var cnode = wrapper.querySelector("[data-col-id=\"" + cc.id + "\"]");
            if (cnode) { // reuse existing
                wrapper.appendChild(cnode);
                return;
            }
            var n = createHeader(cc, _this.ctx, {
                extraPrefix: 'th',
                mergeDropAble: false,
                dragAble: _this.flags.advancedModelFeatures,
                rearrangeAble: _this.flags.advancedModelFeatures,
                resizeable: _this.flags.advancedModelFeatures
            });
            n.classList.add(cssClass('header'), cssClass('nested-th'));
            n.style.gridColumnStart = (i + 1).toString();
            wrapper.appendChild(n);
            if (!_this.renderers || !_this.renderers.summary) {
                return;
            }
            var summary = _this.ctx.summaryRenderer(cc, false);
            var summaryNode = _this.ctx.asElement(summary.template);
            summaryNode.classList.add(cssClass('summary'), cssClass('th-summary'), cssClass("renderer-" + cc.getSummaryRenderer()));
            summaryNode.dataset.renderer = cc.getSummaryRenderer();
            n.appendChild(summaryNode);
            _this.summaries[i] = summary;
            summary.update(summaryNode);
        });
    };
    MultiLevelRenderColumn.prototype.updateHeader = function (node) {
        var r = _super.prototype.updateHeader.call(this, node);
        node = isAsyncUpdate(r) ? r.item : r;
        var wrapper = node.getElementsByClassName(cssClass('nested'))[0];
        if (!wrapper) {
            return r; // too early
        }
        node.appendChild(wrapper); // ensure the last one
        return this.updateNested(wrapper, r);
    };
    MultiLevelRenderColumn.prototype.updateWidthRule = function (style) {
        var mc = this.mc;
        // need this for chrome to work properly
        var widths = mc.children.map(function (c) { return "minmax(0, " + round(c.getWidth()) + "fr)"; });
        var clazz = multiLevelGridCSSClass(this.ctx.idPrefix, this.c);
        style.updateRule("stacked-" + this.c.id, "." + clazz, {
            display: 'grid',
            gridTemplateColumns: widths.join(' ')
        });
        return clazz;
    };
    MultiLevelRenderColumn.prototype.updateNested = function (wrapper, r) {
        var _this = this;
        var sub = this.mc.children;
        this.matchChildren(wrapper, sub);
        var children = Array.from(wrapper.children);
        var toWait = [];
        var header;
        if (isAsyncUpdate(r)) {
            toWait.push(r.ready);
            header = r.item;
        }
        else {
            header = r;
        }
        sub.forEach(function (c, i) {
            var node = children[i];
            updateHeader(node, c);
            if (!_this.renderers || !_this.renderers.summary) {
                return;
            }
            var summary = node.getElementsByClassName(cssClass('summary'))[0];
            var oldRenderer = summary.dataset.renderer;
            var currentRenderer = c.getSummaryRenderer();
            if (oldRenderer !== currentRenderer) {
                var renderer = _this.ctx.summaryRenderer(c, false);
                summary.remove();
                summary = _this.ctx.asElement(renderer.template);
                summary.classList.add(cssClass('summary'), cssClass('th-summary'), cssClass("renderer-" + currentRenderer));
                summary.dataset.renderer = currentRenderer;
                _this.summaries[i] = renderer;
                node.appendChild(summary);
            }
            var ready = _this.summaries[i].update(summary);
            if (ready) {
                toWait.push(ready);
            }
        });
        if (toWait.length === 0) {
            return header;
        }
        return {
            item: header,
            ready: abortAbleAll(toWait)
        };
    };
    return MultiLevelRenderColumn;
}(RenderColumn));
export default MultiLevelRenderColumn;
//# sourceMappingURL=MultiLevelRenderColumn.js.map