import { __assign, __decorate, __extends, __metadata, __spreadArray } from "tslib";
import { Component, Prop } from 'vue-property-decorator';
import { DetailsHeader } from './DetailsHeader';
import { DetailsRow } from './DetailsRow';
import BaseComponent from '../BaseComponent';
import { classNamesFunction } from '@uifabric-vue/utilities';
import { List } from '../List';
import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow/DetailsRow.styles';
var getClassNames = classNamesFunction();
var DetailsListBase = /** @class */ (function (_super) {
    __extends(DetailsListBase, _super);
    function DetailsListBase() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.lastWidth = -1;
        _this.lastSelectionMode = undefined;
        _this.columnOverrides = {};
        _this.lastSortedColumnKey = '';
        return _this;
    }
    DetailsListBase.prototype.render = function (h) {
        var _this = this;
        var _a = this, classNames = _a.classNames, items = _a.items, adjustedColumns = _a.adjustedColumns, compact = _a.compact;
        return h('div', {
            class: classNames.root,
            attrs: {
                dataIsScrollable: 'false',
            },
        }, [
            h('div', { attrs: { role: 'grid' } }, [
                h('div', { class: classNames.headerWrapper }, [
                    this.$scopedSlots.DetailsHeader
                        ? this.$scopedSlots.DetailsHeader({ defaultRender: this.onRenderDetailsHeader })
                        : this.onRenderDetailsHeader(),
                ]),
                h('div', { class: classNames.contentWrapper }, [
                    h(List, {
                        ref: 'list',
                        attrs: {
                            role: 'presentation',
                            items: items,
                        },
                        scopedSlots: {
                            item: function (_a) {
                                var item = _a.item;
                                return h(DetailsRow, {
                                    attrs: {
                                        item: item,
                                        columns: adjustedColumns,
                                        compact: compact,
                                    },
                                    scopedSlots: _this.$scopedSlots,
                                    on: {
                                        click: function (ev) { return _this.$emit('item-clicked', ev, item); },
                                    },
                                });
                            },
                        },
                    }),
                ]),
            ]),
        ]);
    };
    Object.defineProperty(DetailsListBase.prototype, "classNames", {
        get: function () {
            var _a = this, styles = _a.styles, theme = _a.theme, className = _a.className, compact = _a.compact;
            return getClassNames(styles, {
                theme: theme,
                compact: compact,
                isFixed: false,
                isHorizontalConstrained: false,
                className: className,
            });
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DetailsListBase.prototype, "adjustedColumns", {
        get: function () {
            return this._adjustColumns(this.$props);
        },
        enumerable: false,
        configurable: true
    });
    DetailsListBase.prototype.onRenderDetailsHeader = function () {
        var h = this.$createElement;
        return h(DetailsHeader, { attrs: { columns: this.adjustedColumns } });
    };
    DetailsListBase.prototype.created = function () {
        var _this = this;
        var DEFAULT_COLUMN = {
            key: '',
            name: '',
            fieldName: '',
            className: '',
            styles: null,
            minWidth: 0,
            ariaLabel: '',
            isRowHeader: false,
            maxWidth: 0,
            columnActionsMode: 1,
            iconName: '',
            isIconOnly: false,
            iconClassName: '',
            isCollapsible: false,
            isSorted: false,
            isSortedDescending: false,
            isResizable: false,
            isMultiline: false,
            onRender: null,
            getValueKey: null,
            isFiltered: false,
            onColumnClick: null,
            onColumnContextMenu: null,
            onColumnResize: null,
            isGrouped: false,
            data: {},
            calculatedWidth: 0,
            currentWidth: 0,
            headerClassName: '',
            isPadded: false,
            sortAscendingAriaLabel: '',
            sortDescendingAriaLabel: '',
            groupAriaLabel: '',
            filterAriaLabel: '',
            isMenuOpen: false,
        };
        var _loop_1 = function (key) {
            if (Object.prototype.hasOwnProperty.call(DEFAULT_COLUMN, key)) {
                // @ts-ignore
                var value_1 = DEFAULT_COLUMN[key];
                this_1.columns.forEach(function (col) {
                    // @ts-ignore
                    _this.$set(col, key, col[key] !== undefined ? col[key] : value_1);
                });
            }
        };
        var this_1 = this;
        for (var key in DEFAULT_COLUMN) {
            _loop_1(key);
        }
    };
    DetailsListBase.prototype._rememberCalculatedWidth = function (column, newCalculatedWidth) {
        var overrides = this._getColumnOverride(column.key);
        overrides.calculatedWidth = newCalculatedWidth;
        overrides.currentWidth = newCalculatedWidth;
    };
    DetailsListBase.prototype._getColumnOverride = function (key) {
        return (this.columnOverrides[key] = this.columnOverrides[key] || {});
    };
    DetailsListBase.prototype._adjustColumns = function (newProps, forceUpdate, resizingColumnIndex) {
        var adjustedColumns = this._getAdjustedColumns(newProps, forceUpdate, resizingColumnIndex);
        // const { viewport } = this
        var viewportWidth = 1000;
        if (adjustedColumns) {
            // this.adjustedColumns = adjustedColumns
            this.lastWidth = viewportWidth;
        }
        return adjustedColumns;
    };
    /** Returns adjusted columns, given the viewport size and layout mode. */
    DetailsListBase.prototype._getAdjustedColumns = function (newProps, forceUpdate, resizingColumnIndex) {
        var _this = this;
        var newItems = newProps.items, layoutMode = newProps.layoutMode, selectionMode = newProps.selectionMode, viewport = newProps.viewport;
        var viewportWidth = viewport && viewport.width ? viewport.width : 0;
        var newColumns = newProps.columns;
        var columns = this ? this.columns : [];
        var lastWidth = this ? this.lastWidth : -1;
        var lastSelectionMode = this ? this.lastSelectionMode : undefined;
        if (!forceUpdate && lastWidth === viewportWidth && lastSelectionMode === selectionMode && (!columns || newColumns === columns)) {
            return [];
        }
        newColumns = newColumns || buildColumns(newItems, true);
        var adjustedColumns;
        if (layoutMode !== 0) {
            adjustedColumns = this._getFixedColumns(newColumns);
            // Preserve adjusted column calculated widths.
            adjustedColumns.forEach(function (column) {
                _this._rememberCalculatedWidth(column, column.calculatedWidth);
            });
        }
        else {
            if (resizingColumnIndex !== undefined) {
                adjustedColumns = this._getJustifiedColumnsAfterResize(newColumns, viewportWidth, newProps, resizingColumnIndex);
            }
            else {
                adjustedColumns = this._getJustifiedColumns(newColumns, viewportWidth, newProps, 0);
            }
            adjustedColumns.forEach(function (column) {
                _this._getColumnOverride(column.key).currentWidth = column.calculatedWidth;
            });
        }
        return adjustedColumns;
    };
    /** Builds a set of columns based on the given columns mixed with the current overrides. */
    DetailsListBase.prototype._getFixedColumns = function (newColumns) {
        var _this = this;
        return newColumns.map(function (column) {
            var newColumn = __assign(__assign({}, column), _this.columnOverrides[column.key]);
            if (!newColumn.calculatedWidth) {
                newColumn.calculatedWidth = newColumn.maxWidth || newColumn.minWidth || MIN_COLUMN_WIDTH;
            }
            return newColumn;
        });
    };
    DetailsListBase.prototype._getJustifiedColumnsAfterResize = function (newColumns, viewportWidth, props, resizingColumnIndex) {
        var _this = this;
        var fixedColumns = newColumns.slice(0, resizingColumnIndex);
        fixedColumns.forEach(function (column) { return (column.calculatedWidth = _this._getColumnOverride(column.key).currentWidth); });
        var fixedWidth = fixedColumns.reduce(function (total, column, i) { return total + getPaddedWidth(column, i === 0, props); }, 0);
        var remainingColumns = newColumns.slice(resizingColumnIndex);
        var remainingWidth = viewportWidth - fixedWidth;
        return __spreadArray(__spreadArray([], fixedColumns, true), this._getJustifiedColumns(remainingColumns, remainingWidth, props, resizingColumnIndex), true);
    };
    /** Builds a set of columns to fix within the viewport width. */
    DetailsListBase.prototype._getJustifiedColumns = function (newColumns, viewportWidth, props, firstIndex) {
        var _this = this;
        var _a = props.selectionMode, selectionMode = _a === void 0 ? 0 : _a, checkboxVisibility = props.checkboxVisibility;
        var rowCheckWidth = selectionMode !== 0 && checkboxVisibility !== checkboxVisibility.hidden ? 10 : 0;
        var groupExpandWidth = 1 * 10;
        var totalWidth = 0; // offset because we have one less inner padding.
        var availableWidth = viewportWidth - (rowCheckWidth + groupExpandWidth);
        var adjustedColumns = newColumns.map(function (column, i) {
            var newColumn = __assign(__assign(__assign({}, column), { calculatedWidth: column.minWidth || MIN_COLUMN_WIDTH }), _this.columnOverrides[column.key]);
            var isFirst = i + firstIndex === 0;
            totalWidth += getPaddedWidth(newColumn, isFirst, props);
            return newColumn;
        });
        var lastIndex = adjustedColumns.length - 1;
        // Shrink or remove collapsable columns.
        while (lastIndex > 0 && totalWidth > availableWidth) {
            var column = adjustedColumns[lastIndex];
            var minWidth = column.minWidth || MIN_COLUMN_WIDTH;
            var overflowWidth = totalWidth - availableWidth;
            // tslint:disable-next-line:deprecation
            if (column.calculatedWidth - minWidth >= overflowWidth || !(column.isCollapsible || column.isCollapsable)) {
                var originalWidth = column.calculatedWidth;
                column.calculatedWidth = Math.max(column.calculatedWidth - overflowWidth, minWidth);
                totalWidth -= originalWidth - column.calculatedWidth;
            }
            else {
                totalWidth -= getPaddedWidth(column, false, props);
                adjustedColumns.splice(lastIndex, 1);
            }
            lastIndex--;
        }
        // Then expand columns starting at the beginning, until we've filled the width.
        for (var i = 0; i < adjustedColumns.length && totalWidth < availableWidth; i++) {
            var column = adjustedColumns[i];
            var isLast = i === adjustedColumns.length - 1;
            var overrides = this.columnOverrides[column.key];
            if (overrides && overrides.calculatedWidth && !isLast) {
                continue;
            }
            var spaceLeft = availableWidth - totalWidth;
            var increment = void 0;
            if (isLast) {
                increment = spaceLeft;
            }
            else {
                var maxWidth = column.maxWidth;
                var minWidth = column.minWidth || maxWidth || MIN_COLUMN_WIDTH;
                increment = maxWidth ? Math.min(spaceLeft, maxWidth - minWidth) : spaceLeft;
            }
            column.calculatedWidth = column.calculatedWidth + increment;
            totalWidth += increment;
        }
        return adjustedColumns;
    };
    __decorate([
        Prop({ type: Array, required: true }),
        __metadata("design:type", Array)
    ], DetailsListBase.prototype, "columns", void 0);
    __decorate([
        Prop({ type: Array, default: function () { return []; } }),
        __metadata("design:type", Array)
    ], DetailsListBase.prototype, "items", void 0);
    __decorate([
        Prop({ type: Boolean, default: false }),
        __metadata("design:type", Boolean)
    ], DetailsListBase.prototype, "compact", void 0);
    DetailsListBase = __decorate([
        Component
    ], DetailsListBase);
    return DetailsListBase;
}(BaseComponent));
export { DetailsListBase };
var MIN_COLUMN_WIDTH = 100; // this is the global min width
export function buildColumns(items, canResizeColumns, onColumnClick, sortedColumnKey, isSortedDescending, groupedColumnKey, isMultiline) {
    var columns = [];
    if (items && items.length) {
        var firstItem = items[0];
        for (var propName in firstItem) {
            if (Object.prototype.hasOwnProperty.call(firstItem, propName)) {
                columns.push({
                    key: propName,
                    name: propName,
                    fieldName: propName,
                    minWidth: MIN_COLUMN_WIDTH,
                    maxWidth: 300,
                    isCollapsable: !!columns.length,
                    isCollapsible: !!columns.length,
                    isMultiline: isMultiline === undefined ? false : isMultiline,
                    isSorted: sortedColumnKey === propName,
                    isSortedDescending: !!isSortedDescending,
                    isRowHeader: false,
                    columnActionsMode: 0,
                    isResizable: canResizeColumns,
                    onColumnClick: onColumnClick,
                    isGrouped: groupedColumnKey === propName,
                });
            }
        }
    }
    return columns;
}
function getPaddedWidth(column, isFirst, props) {
    var _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
    return (column.calculatedWidth +
        cellStyleProps.cellLeftPadding +
        cellStyleProps.cellRightPadding +
        (column.isPadded ? cellStyleProps.cellExtraRightPadding : 0));
}
//# sourceMappingURL=DetailsList.base.js.map