"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateColumnPickerOrder = exports.populateColumnPicker = exports.handleColumnPickerItemClick = exports.addColumnTitleElementWhenDefined = exports.addCloseButtomElement = void 0;
/* eslint-disable @typescript-eslint/no-this-alias */
const utils_1 = require("@slickgrid-universal/utils");
const slickColumnPicker_1 = require("./slickColumnPicker");
const slickGridMenu_1 = require("./slickGridMenu");
const PICKER_CHECK_ICON = 'mdi-icon-picker-check';
const PICKER_UNCHECK_ICON = 'mdi-icon-picker-uncheck';
/** Create a Close button element and add it to the Menu element */
function addCloseButtomElement(menuElm) {
    const context = this;
    const closePickerButtonElm = (0, utils_1.createDomElement)('button', {
        type: 'button', className: 'close',
        ariaLabel: 'Close',
        textContent: '×',
        dataset: { dismiss: context instanceof slickColumnPicker_1.SlickColumnPicker ? 'slick-column-picker' : 'slick-grid-menu' }
    });
    menuElm.appendChild(closePickerButtonElm);
}
exports.addCloseButtomElement = addCloseButtomElement;
/** When "columnTitle" option is provided, let's create a div element to show "Columns" list title */
function addColumnTitleElementWhenDefined(menuElm) {
    const context = this;
    if (context.addonOptions?.columnTitle) {
        context._columnTitleElm = (0, utils_1.createDomElement)('div', { className: 'slick-menu-title', textContent: context.addonOptions?.columnTitle ?? context._defaults.columnTitle }, menuElm);
    }
}
exports.addColumnTitleElementWhenDefined = addColumnTitleElementWhenDefined;
/**
 * When clicking an input checkboxes from the column picker list to show/hide a column (or from the picker extra commands like forcefit columns)
 * @param event - input checkbox event
 * @returns
 */
function handleColumnPickerItemClick(event) {
    const context = this;
    const controlType = context instanceof slickColumnPicker_1.SlickColumnPicker ? 'columnPicker' : 'gridMenu';
    const iconContainerElm = event.target?.closest('.icon-checkbox-container');
    const iconElm = iconContainerElm?.querySelector('.mdi');
    const isChecked = !!(event.target.checked);
    event.target.ariaChecked = String(isChecked);
    togglePickerCheckbox(iconElm, isChecked);
    if (event.target.dataset.option === 'autoresize') {
        // when calling setOptions, it will resize with ALL Columns (even the hidden ones)
        // we can avoid this problem by keeping a reference to the visibleColumns before setOptions and then setColumns after
        const previousVisibleColumns = context.getVisibleColumns();
        context.grid.setOptions({ forceFitColumns: isChecked });
        context.grid.setColumns(previousVisibleColumns);
        return;
    }
    if (event.target.dataset.option === 'syncresize') {
        context.grid.setOptions({ syncColumnCellResize: isChecked });
        return;
    }
    if (event.target.type === 'checkbox') {
        context._areVisibleColumnDifferent = true;
        const columnId = event.target.dataset.columnid || '';
        const visibleColumns = [];
        context._columnCheckboxes.forEach((columnCheckbox, idx) => {
            if (columnCheckbox.checked) {
                visibleColumns.push(context.columns[idx]);
            }
        });
        if (!visibleColumns.length) {
            event.target.checked = true;
            togglePickerCheckbox(iconElm, true);
            return;
        }
        context.grid.setColumns(visibleColumns);
        // keep reference to the updated visible columns list
        if (!context.sharedService.visibleColumns || (Array.isArray(visibleColumns) && visibleColumns.length !== context.sharedService.visibleColumns.length)) {
            context.sharedService.visibleColumns = visibleColumns;
        }
        // when using row selection, SlickGrid will only apply the "selected" CSS class on the visible columns only
        // and if the row selection was done prior to the column being shown then that column that was previously hidden (at the time of the row selection)
        // will not have the "selected" CSS class because it wasn't visible at the time.
        // To bypass this problem we can simply recall the row selection with the same selection and that will trigger a re-apply of the CSS class
        // on all columns including the column we just made visible
        if (context.gridOptions.enableRowSelection && isChecked) {
            const rowSelection = context.grid.getSelectedRows();
            context.grid.setSelectedRows(rowSelection);
        }
        // if we're using frozen columns, we need to readjust pinning when the new hidden column becomes visible again on the left pinning container
        // we need to readjust frozenColumn index because SlickGrid freezes by index and has no knowledge of the columns themselves
        const frozenColumnIndex = context.gridOptions.frozenColumn ?? -1;
        if (frozenColumnIndex >= 0) {
            context.extensionUtility.readjustFrozenColumnIndexWhenNeeded(frozenColumnIndex, context.columns, visibleColumns);
        }
        const callbackArgs = {
            columnId,
            showing: isChecked,
            allColumns: context.columns,
            visibleColumns,
            columns: visibleColumns,
            grid: context.grid
        };
        // execute user callback when defined
        context.pubSubService.publish(`on${(0, utils_1.titleCase)(controlType)}ColumnsChanged`, callbackArgs);
        if (typeof context.addonOptions?.onColumnsChanged === 'function') {
            context.addonOptions.onColumnsChanged(event, callbackArgs);
        }
        context.onColumnsChanged.notify(callbackArgs, null, context);
    }
}
exports.handleColumnPickerItemClick = handleColumnPickerItemClick;
function togglePickerCheckbox(iconElm, checked = false) {
    if (iconElm) {
        iconElm.className = `mdi ${checked ? PICKER_CHECK_ICON : PICKER_UNCHECK_ICON}`;
    }
}
function generatePickerCheckbox(columnLiElm, inputId, inputData, checked = false) {
    const labelElm = (0, utils_1.createDomElement)('label', { className: 'checkbox-picker-label', htmlFor: inputId });
    const divElm = (0, utils_1.createDomElement)('div', { className: 'icon-checkbox-container' });
    const inputElm = (0, utils_1.createDomElement)('input', { id: inputId, type: 'checkbox', dataset: inputData });
    const colInputDivElm = (0, utils_1.createDomElement)('div', { className: `mdi ${checked ? PICKER_CHECK_ICON : PICKER_UNCHECK_ICON}` });
    const labelSpanElm = (0, utils_1.createDomElement)('span', { className: 'checkbox-label' });
    divElm.appendChild(inputElm);
    divElm.appendChild(colInputDivElm);
    labelElm.appendChild(divElm);
    labelElm.appendChild(labelSpanElm);
    columnLiElm.appendChild(labelElm);
    if (checked) {
        inputElm.ariaChecked = 'true';
        inputElm.checked = true;
    }
    return { inputElm, labelElm, labelSpanElm };
}
function populateColumnPicker(addonOptions) {
    const context = this;
    const menuPrefix = context instanceof slickGridMenu_1.SlickGridMenu ? 'gridmenu-' : '';
    for (const column of context.columns) {
        const columnId = column.id;
        const columnLiElm = document.createElement('li');
        if (column.excludeFromColumnPicker) {
            columnLiElm.className = 'hidden';
        }
        const inputId = `${context._gridUid}-${menuPrefix}colpicker-${columnId}`;
        const isChecked = context.grid.getColumnIndex(columnId) >= 0;
        const { inputElm, labelElm, labelSpanElm } = generatePickerCheckbox(columnLiElm, inputId, { columnid: `${columnId}` }, isChecked);
        context._columnCheckboxes.push(inputElm);
        const headerColumnValueExtractorFn = typeof addonOptions?.headerColumnValueExtractor === 'function' ? addonOptions.headerColumnValueExtractor : context._defaults.headerColumnValueExtractor;
        const columnLabel = headerColumnValueExtractorFn(column, context.gridOptions);
        this.grid.applyHtmlCode(labelSpanElm, columnLabel);
        columnLiElm.appendChild(labelElm);
        context._listElm.appendChild(columnLiElm);
    }
    if (!addonOptions.hideForceFitButton || !addonOptions.hideSyncResizeButton) {
        context._listElm.appendChild(document.createElement('hr'));
    }
    if (!(addonOptions?.hideForceFitButton)) {
        const fitLiElm = document.createElement('li');
        const inputId = `${context._gridUid}-${menuPrefix}colpicker-forcefit`;
        const { labelSpanElm } = generatePickerCheckbox(fitLiElm, inputId, { option: 'autoresize' }, context.gridOptions.forceFitColumns);
        labelSpanElm.textContent = addonOptions?.forceFitTitle ?? '';
        context._listElm.appendChild(fitLiElm);
    }
    if (!(addonOptions?.hideSyncResizeButton)) {
        const syncLiElm = document.createElement('li');
        const inputId = `${context._gridUid}-${menuPrefix}colpicker-syncresize`;
        const { labelSpanElm } = generatePickerCheckbox(syncLiElm, inputId, { option: 'syncresize' }, context.gridOptions.forceFitColumns);
        labelSpanElm.textContent = addonOptions?.syncResizeTitle ?? '';
        context._listElm.appendChild(syncLiElm);
    }
}
exports.populateColumnPicker = populateColumnPicker;
/**
 * Because columns can be reordered, we have to update the `columns` to reflect the new order, however we can't just take `grid.getColumns()`,
 * as it does not include columns currently hidden by the picker. We create a new `columns` structure by leaving currently-hidden
 * columns in their original ordinal position and interleaving the results of the current column sort.
 */
function updateColumnPickerOrder() {
    const context = this;
    const current = context.grid.getColumns().slice(0);
    const ordered = new Array(context.columns.length);
    for (let i = 0; i < ordered.length; i++) {
        const columnIdx = context.grid.getColumnIndex(context.columns[i].id);
        if (columnIdx === undefined) {
            // if the column doesn't return a value from getColumnIndex, it is hidden. Leave it in this position.
            ordered[i] = context.columns[i];
        }
        else {
            // otherwise, grab the next visible column.
            ordered[i] = current.shift();
        }
    }
    // the new set of ordered columns becomes the new set of column picker columns
    context._columns = ordered;
}
exports.updateColumnPickerOrder = updateColumnPickerOrder;
//# sourceMappingURL=extensionCommonUtils.js.map