/**
 * DevExtreme (esm/__internal/grids/grid_core/selection/m_selection.js)
 * Version: 23.1.6 (build 23316-0110)
 * Build date: Sun Nov 12 2023
 *
 * Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import $ from "../../../../core/renderer";
import {
    equalByValue
} from "../../../../core/utils/common";
import {
    Deferred
} from "../../../../core/utils/deferred";
import {
    extend
} from "../../../../core/utils/extend";
import {
    each
} from "../../../../core/utils/iterator";
import {
    touch
} from "../../../../core/utils/support";
import {
    isDefined
} from "../../../../core/utils/type";
import {
    applyBatch
} from "../../../../data/array_utils";
import {
    name as clickEventName
} from "../../../../events/click";
import eventsEngine from "../../../../events/core/events_engine";
import holdEvent from "../../../../events/hold";
import {
    addNamespace,
    isCommandKeyPressed
} from "../../../../events/utils/index";
import messageLocalization from "../../../../localization/message";
import Selection from "../../../../ui/selection/selection";
import errors from "../../../../ui/widget/ui.errors";
import modules from "../m_modules";
import gridCoreUtils from "../m_utils";
var EDITOR_CELL_CLASS = "dx-editor-cell";
var ROW_CLASS = "dx-row";
var ROW_SELECTION_CLASS = "dx-selection";
var SELECT_CHECKBOX_CLASS = "dx-select-checkbox";
var CHECKBOXES_HIDDEN_CLASS = "dx-select-checkboxes-hidden";
var COMMAND_SELECT_CLASS = "dx-command-select";
var SELECTION_DISABLED_CLASS = "dx-selection-disabled";
var DATA_ROW_CLASS = "dx-data-row";
var SHOW_CHECKBOXES_MODE = "selection.showCheckBoxesMode";
var SELECTION_MODE = "selection.mode";
var processLongTap = function(that, dxEvent) {
    var selectionController = that.getController("selection");
    var rowsView = that.getView("rowsView");
    var $row = $(dxEvent.target).closest(".".concat(DATA_ROW_CLASS));
    var rowIndex = rowsView.getRowIndex($row);
    if (rowIndex < 0) {
        return
    }
    if ("onLongTap" === that.option(SHOW_CHECKBOXES_MODE)) {
        if (selectionController.isSelectionWithCheckboxes()) {
            selectionController.stopSelectionWithCheckboxes()
        } else {
            selectionController.startSelectionWithCheckboxes()
        }
    } else {
        if ("onClick" === that.option(SHOW_CHECKBOXES_MODE)) {
            selectionController.startSelectionWithCheckboxes()
        }
        if ("always" !== that.option(SHOW_CHECKBOXES_MODE)) {
            selectionController.changeItemSelection(rowIndex, {
                control: true
            })
        }
    }
};
var isSeveralRowsSelected = function(that, selectionFilter) {
    var keyIndex = 0;
    var store = that._dataController.store();
    var key = store && store.key();
    var isComplexKey = Array.isArray(key);
    if (!selectionFilter.length) {
        return false
    }
    if (isComplexKey && Array.isArray(selectionFilter[0]) && "and" === selectionFilter[1]) {
        for (var i = 0; i < selectionFilter.length; i++) {
            if (Array.isArray(selectionFilter[i])) {
                if (selectionFilter[i][0] !== key[keyIndex] || "=" !== selectionFilter[i][1]) {
                    return true
                }
                keyIndex++
            }
        }
        return false
    }
    return key !== selectionFilter[0]
};
var selectionCellTemplate = (container, options) => {
    var {
        component: component
    } = options;
    var rowsView = component.getView("rowsView");
    if (component.option("renderAsync") && !component.option("selection.deferred")) {
        options.value = component.isRowSelected(options.row.key)
    }
    rowsView.renderSelectCheckBoxContainer($(container), options)
};
var selectionHeaderTemplate = (container, options) => {
    var {
        column: column
    } = options;
    var $cellElement = $(container);
    var columnHeadersView = options.component.getView("columnHeadersView");
    $cellElement.addClass(EDITOR_CELL_CLASS);
    columnHeadersView._renderSelectAllCheckBox($cellElement, column);
    columnHeadersView._attachSelectAllCheckBoxClickEvent($cellElement)
};
export class SelectionController extends modules.Controller {
    init() {
        var _a;
        var {
            deferred: deferred,
            selectAllMode: selectAllMode,
            mode: mode
        } = null !== (_a = this.option("selection")) && void 0 !== _a ? _a : {};
        if ("infinite" === this.option("scrolling.mode") && !deferred && "multiple" === mode && "allPages" === selectAllMode) {
            errors.log("W1018")
        }
        this._dataController = this.getController("data");
        this._selectionMode = mode;
        this._isSelectionWithCheckboxes = false;
        this._selection = this._createSelection();
        this._updateSelectColumn();
        this.createAction("onSelectionChanged", {
            excludeValidators: ["disabled", "readOnly"]
        });
        if (!this._dataPushedHandler) {
            this._dataPushedHandler = this._handleDataPushed.bind(this);
            this._dataController.pushed.add(this._dataPushedHandler)
        }
    }
    _handleDataPushed(changes) {
        this._deselectRemovedOnPush(changes);
        this._updateSelectedOnPush(changes)
    }
    _deselectRemovedOnPush(changes) {
        var isDeferredSelection = this.option("selection.deferred");
        var removedKeys = changes.filter(change => "remove" === change.type).map(change => change.key);
        if (isDeferredSelection) {
            var selectedKeys = this._dataController.items().filter(item => item.isSelected).map(item => item.key);
            removedKeys = removedKeys.filter(key => selectedKeys.find(selectedKey => equalByValue(selectedKey, key)))
        }
        removedKeys.length && this.deselectRows(removedKeys)
    }
    _updateSelectedOnPush(changes) {
        var isDeferredSelection = this.option("selection.deferred");
        if (isDeferredSelection) {
            return
        }
        var updateChanges = changes.filter(change => "update" === change.type);
        var data = this.getSelectedRowsData();
        applyBatch({
            keyInfo: this._selection.options,
            data: data,
            changes: updateChanges
        })
    }
    _getSelectionConfig() {
        var _a;
        var dataController = this._dataController;
        var columnsController = this.getController("columns");
        var selectionOptions = null !== (_a = this.option("selection")) && void 0 !== _a ? _a : {};
        var {
            deferred: deferred
        } = selectionOptions;
        var scrollingMode = this.option("scrolling.mode");
        var virtualPaging = "virtual" === scrollingMode || "infinite" === scrollingMode;
        var allowSelectAll = this.option("selection.allowSelectAll");
        var legacyScrollingMode = this.option("scrolling.legacyMode");
        return {
            selectedKeys: this.option("selectedRowKeys"),
            mode: this._selectionMode,
            deferred: deferred,
            maxFilterLengthInRequest: selectionOptions.maxFilterLengthInRequest,
            selectionFilter: this.option("selectionFilter"),
            ignoreDisabledItems: true,
            allowLoadByRange() {
                var hasGroupColumns = columnsController.getGroupColumns().length > 0;
                return virtualPaging && !legacyScrollingMode && !hasGroupColumns && allowSelectAll && !deferred
            },
            key: () => null === dataController || void 0 === dataController ? void 0 : dataController.key(),
            keyOf: item => null === dataController || void 0 === dataController ? void 0 : dataController.keyOf(item),
            dataFields() {
                var _a;
                return null === (_a = dataController.dataSource()) || void 0 === _a ? void 0 : _a.select()
            },
            load(options) {
                var _a;
                return (null === (_a = dataController.dataSource()) || void 0 === _a ? void 0 : _a.load(options)) || (new Deferred).resolve([])
            },
            plainItems: () => dataController.items(true),
            isItemSelected: item => item.selected,
            isSelectableItem: item => "data" === (null === item || void 0 === item ? void 0 : item.rowType) && !item.isNewRow,
            getItemData: item => isDefined(null === item || void 0 === item ? void 0 : item.rowType) ? (null === item || void 0 === item ? void 0 : item.oldData) || (null === item || void 0 === item ? void 0 : item.data) : item,
            filter: () => dataController.getCombinedFilter(deferred),
            totalCount: () => dataController.totalCount(),
            getLoadOptions(loadItemIndex, focusedItemIndex, shiftItemIndex) {
                var _a, _b;
                var {
                    sort: sort,
                    filter: filter
                } = null !== (_b = null === (_a = dataController.dataSource()) || void 0 === _a ? void 0 : _a.lastLoadOptions()) && void 0 !== _b ? _b : {};
                var minIndex = Math.min(loadItemIndex, focusedItemIndex);
                var maxIndex = Math.max(loadItemIndex, focusedItemIndex);
                if (isDefined(shiftItemIndex)) {
                    minIndex = Math.min(shiftItemIndex, minIndex);
                    maxIndex = Math.max(shiftItemIndex, maxIndex)
                }
                var take = maxIndex - minIndex + 1;
                return {
                    skip: minIndex,
                    take: take,
                    filter: filter,
                    sort: sort
                }
            },
            onSelectionChanged: this._updateSelectedItems.bind(this)
        }
    }
    _updateSelectColumn() {
        var columnsController = this.getController("columns");
        var isSelectColumnVisible = this.isSelectColumnVisible();
        columnsController.addCommandColumn({
            type: "selection",
            command: "select",
            visible: isSelectColumnVisible,
            visibleIndex: -1,
            dataType: "boolean",
            alignment: "center",
            cssClass: COMMAND_SELECT_CLASS,
            width: "auto",
            cellTemplate: selectionCellTemplate,
            headerCellTemplate: selectionHeaderTemplate
        });
        columnsController.columnOption("command:select", "visible", isSelectColumnVisible)
    }
    _createSelection() {
        var options = this._getSelectionConfig();
        return new Selection(options)
    }
    _fireSelectionChanged(options) {
        var argument = this.option("selection.deferred") ? {
            selectionFilter: this.option("selectionFilter")
        } : {
            selectedRowKeys: this.option("selectedRowKeys")
        };
        this.selectionChanged.fire(argument);
        if (options) {
            this.executeAction("onSelectionChanged", options)
        }
    }
    _updateCheckboxesState(options) {
        var {
            isDeferredMode: isDeferredMode
        } = options;
        var {
            selectionFilter: selectionFilter
        } = options;
        var {
            selectedItemKeys: selectedItemKeys
        } = options;
        var {
            removedItemKeys: removedItemKeys
        } = options;
        if ("onClick" === this.option(SHOW_CHECKBOXES_MODE)) {
            if (isDeferredMode ? selectionFilter && isSeveralRowsSelected(this, selectionFilter) : selectedItemKeys.length > 1) {
                this.startSelectionWithCheckboxes()
            } else if (isDeferredMode ? selectionFilter && !selectionFilter.length : 0 === selectedItemKeys.length && removedItemKeys.length) {
                this.stopSelectionWithCheckboxes()
            }
        }
    }
    _updateSelectedItems(args) {
        var selectionChangedOptions;
        var isDeferredMode = this.option("selection.deferred");
        var selectionFilter = this._selection.selectionFilter();
        var dataController = this._dataController;
        var items = dataController.items(true);
        var visibleItems = dataController.items();
        if (!items) {
            return
        }
        var isSelectionWithCheckboxes = this.isSelectionWithCheckboxes();
        var changedItemIndexes = this.getChangedItemIndexes(items);
        var visibleChangedItemIndexes = this.getChangedItemIndexes(visibleItems);
        this._updateCheckboxesState({
            selectedItemKeys: args.selectedItemKeys,
            removedItemKeys: args.removedItemKeys,
            selectionFilter: selectionFilter,
            isDeferredMode: isDeferredMode
        });
        if (changedItemIndexes.length || isSelectionWithCheckboxes !== this.isSelectionWithCheckboxes()) {
            dataController.updateItems({
                changeType: "updateSelection",
                itemIndexes: visibleChangedItemIndexes
            })
        }
        if (isDeferredMode) {
            this.option("selectionFilter", selectionFilter);
            selectionChangedOptions = {}
        } else if (args.addedItemKeys.length || args.removedItemKeys.length) {
            this._selectedItemsInternalChange = true;
            this.option("selectedRowKeys", args.selectedItemKeys.slice(0));
            this._selectedItemsInternalChange = false;
            selectionChangedOptions = {
                selectedRowsData: args.selectedItems.slice(0),
                selectedRowKeys: args.selectedItemKeys.slice(0),
                currentSelectedRowKeys: args.addedItemKeys.slice(0),
                currentDeselectedRowKeys: args.removedItemKeys.slice(0)
            }
        }
        this._fireSelectionChanged(selectionChangedOptions)
    }
    getChangedItemIndexes(items) {
        var itemIndexes = [];
        var isDeferredSelection = this.option("selection.deferred");
        for (var i = 0, {
                length: length
            } = items; i < length; i++) {
            var row = items[i];
            var isItemSelected = this.isRowSelected(isDeferredSelection ? row.data : row.key);
            if (this._selection.isDataItem(row) && row.isSelected !== isItemSelected) {
                itemIndexes.push(i)
            }
        }
        return itemIndexes
    }
    callbackNames() {
        return ["selectionChanged"]
    }
    optionChanged(args) {
        super.optionChanged(args);
        switch (args.name) {
            case "selection":
                var oldSelectionMode = this._selectionMode;
                this.init();
                if ("selection.showCheckBoxesMode" !== args.fullName) {
                    var selectionMode = this._selectionMode;
                    var selectedRowKeys = this.option("selectedRowKeys");
                    if (oldSelectionMode !== selectionMode) {
                        if ("single" === selectionMode) {
                            if (selectedRowKeys.length > 1) {
                                selectedRowKeys = [selectedRowKeys[0]]
                            }
                        } else if ("multiple" !== selectionMode) {
                            selectedRowKeys = []
                        }
                    }
                    this.selectRows(selectedRowKeys).always(() => {
                        this._fireSelectionChanged()
                    })
                }
                this.getController("columns").updateColumns();
                args.handled = true;
                break;
            case "selectionFilter":
                this._selection.selectionFilter(args.value);
                args.handled = true;
                break;
            case "selectedRowKeys":
                var value = args.value || [];
                if (Array.isArray(value) && !this._selectedItemsInternalChange && (this.component.getDataSource() || !value.length)) {
                    this.selectRows(value)
                }
                args.handled = true
        }
    }
    publicMethods() {
        return ["selectRows", "deselectRows", "selectRowsByIndexes", "getSelectedRowKeys", "getSelectedRowsData", "clearSelection", "selectAll", "deselectAll", "startSelectionWithCheckboxes", "stopSelectionWithCheckboxes", "isRowSelected"]
    }
    isRowSelected(arg) {
        return this._selection.isItemSelected(arg)
    }
    isSelectColumnVisible() {
        return "multiple" === this.option(SELECTION_MODE) && ("always" === this.option(SHOW_CHECKBOXES_MODE) || "onClick" === this.option(SHOW_CHECKBOXES_MODE) || this._isSelectionWithCheckboxes)
    }
    _isOnePageSelectAll() {
        return "page" === this.option("selection.selectAllMode")
    }
    isSelectAll() {
        return this._selection.getSelectAllState(this._isOnePageSelectAll())
    }
    selectAll() {
        if ("onClick" === this.option(SHOW_CHECKBOXES_MODE)) {
            this.startSelectionWithCheckboxes()
        }
        return this._selection.selectAll(this._isOnePageSelectAll())
    }
    deselectAll() {
        return this._selection.deselectAll(this._isOnePageSelectAll())
    }
    clearSelection() {
        return this.selectedItemKeys([])
    }
    refresh() {
        var _a;
        var selectedRowKeys = null !== (_a = this.option("selectedRowKeys")) && void 0 !== _a ? _a : [];
        if (!this.option("selection.deferred") && selectedRowKeys.length) {
            return this.selectedItemKeys(selectedRowKeys)
        }
        return (new Deferred).resolve().promise()
    }
    selectedItemKeys(value, preserve, isDeselect, isSelectAll) {
        return this._selection.selectedItemKeys(value, preserve, isDeselect, isSelectAll)
    }
    getSelectedRowKeys() {
        return this._selection.getSelectedItemKeys()
    }
    selectRows(keys, preserve) {
        return this.selectedItemKeys(keys, preserve)
    }
    deselectRows(keys) {
        return this.selectedItemKeys(keys, true, true)
    }
    selectRowsByIndexes(indexes) {
        var items = this._dataController.items();
        var keys = [];
        if (!Array.isArray(indexes)) {
            indexes = Array.prototype.slice.call(arguments, 0)
        }
        each(indexes, (function() {
            var item = items[this];
            if (item && "data" === item.rowType) {
                keys.push(item.key)
            }
        }));
        return this.selectRows(keys)
    }
    getSelectedRowsData() {
        return this._selection.getSelectedItems()
    }
    loadSelectedItemsWithFilter() {
        return this._selection.loadSelectedItemsWithFilter()
    }
    changeItemSelection(visibleItemIndex, keys, setFocusOnly) {
        keys = keys || {};
        if (this.isSelectionWithCheckboxes()) {
            keys.control = true
        }
        var loadedItemIndex = visibleItemIndex + this._dataController.getRowIndexOffset() - this._dataController.getRowIndexOffset(true);
        return this._selection.changeItemSelection(loadedItemIndex, keys, setFocusOnly)
    }
    focusedItemIndex(itemIndex) {
        if (isDefined(itemIndex)) {
            this._selection._focusedItemIndex = itemIndex
        } else {
            return this._selection._focusedItemIndex
        }
        return
    }
    isSelectionWithCheckboxes() {
        return "multiple" === this.option(SELECTION_MODE) && ("always" === this.option(SHOW_CHECKBOXES_MODE) || this._isSelectionWithCheckboxes)
    }
    startSelectionWithCheckboxes() {
        if ("multiple" === this.option(SELECTION_MODE) && !this.isSelectionWithCheckboxes()) {
            this._isSelectionWithCheckboxes = true;
            this._updateSelectColumn();
            return true
        }
        return false
    }
    stopSelectionWithCheckboxes() {
        if (this._isSelectionWithCheckboxes) {
            this._isSelectionWithCheckboxes = false;
            this._updateSelectColumn();
            return true
        }
        return false
    }
}
export var selectionModule = {
    defaultOptions: () => ({
        selection: {
            mode: "none",
            showCheckBoxesMode: "onClick",
            allowSelectAll: true,
            selectAllMode: "allPages",
            maxFilterLengthInRequest: 1500,
            deferred: false
        },
        selectionFilter: [],
        selectedRowKeys: []
    }),
    controllers: {
        selection: SelectionController
    },
    extenders: {
        controllers: {
            data: {
                init() {
                    var selectionController = this.getController("selection");
                    var isDeferredMode = this.option("selection.deferred");
                    this.callBase.apply(this, arguments);
                    if (isDeferredMode) {
                        selectionController._updateCheckboxesState({
                            isDeferredMode: true,
                            selectionFilter: this.option("selectionFilter")
                        })
                    }
                },
                _loadDataSource() {
                    var that = this;
                    return that.callBase().always(() => {
                        that.getController("selection").refresh()
                    })
                },
                _processDataItem(item, options) {
                    var selectionController = this.getController("selection");
                    var hasSelectColumn = selectionController.isSelectColumnVisible();
                    var isDeferredSelection = options.isDeferredSelection = void 0 === options.isDeferredSelection ? this.option("selection.deferred") : options.isDeferredSelection;
                    var dataItem = this.callBase.apply(this, arguments);
                    dataItem.isSelected = selectionController.isRowSelected(isDeferredSelection ? dataItem.data : dataItem.key);
                    if (hasSelectColumn && dataItem.values) {
                        for (var i = 0; i < options.visibleColumns.length; i++) {
                            if ("select" === options.visibleColumns[i].command) {
                                dataItem.values[i] = dataItem.isSelected;
                                break
                            }
                        }
                    }
                    return dataItem
                },
                refresh(options) {
                    var that = this;
                    var d = new Deferred;
                    this.callBase.apply(this, arguments).done(() => {
                        if (!options || options.selection) {
                            that.getController("selection").refresh().done(d.resolve).fail(d.reject)
                        } else {
                            d.resolve()
                        }
                    }).fail(d.reject);
                    return d.promise()
                },
                _handleDataChanged(e) {
                    this.callBase.apply(this, arguments);
                    if ((!e || "refresh" === e.changeType) && !this._repaintChangesOnly) {
                        this.getController("selection").focusedItemIndex(-1)
                    }
                },
                _applyChange(change) {
                    if (change && "updateSelection" === change.changeType) {
                        change.items.forEach((item, index) => {
                            var currentItem = this._items[index];
                            if (currentItem) {
                                currentItem.isSelected = item.isSelected;
                                currentItem.values = item.values
                            }
                        });
                        return
                    }
                    return this.callBase.apply(this, arguments)
                },
                _endUpdateCore() {
                    var changes = this._changes;
                    var isUpdateSelection = changes.length > 1 && changes.every(change => "updateSelection" === change.changeType);
                    if (isUpdateSelection) {
                        var itemIndexes = changes.map(change => change.itemIndexes || []).reduce((a, b) => a.concat(b));
                        this._changes = [{
                            changeType: "updateSelection",
                            itemIndexes: itemIndexes
                        }]
                    }
                    this.callBase.apply(this, arguments)
                }
            },
            contextMenu: {
                _contextMenuPrepared(options) {
                    var dxEvent = options.event;
                    if (dxEvent.originalEvent && "dxhold" !== dxEvent.originalEvent.type || options.items && options.items.length > 0) {
                        return
                    }
                    processLongTap(this, dxEvent)
                }
            }
        },
        views: {
            columnHeadersView: {
                init() {
                    this.callBase();
                    this.getController("selection").selectionChanged.add(this._updateSelectAllValue.bind(this))
                },
                _updateSelectAllValue() {
                    var $element = this.element();
                    var $editor = $element && $element.find(".".concat(SELECT_CHECKBOX_CLASS));
                    if ($element && $editor.length && "multiple" === this.option("selection.mode")) {
                        var selectAllValue = this.getController("selection").isSelectAll();
                        var hasSelection = false !== selectAllValue;
                        var isVisible = this.option("selection.allowSelectAll") ? !this.getController("data").isEmpty() : hasSelection;
                        $editor.dxCheckBox("instance").option({
                            visible: isVisible,
                            value: selectAllValue
                        })
                    }
                },
                _handleDataChanged(e) {
                    this.callBase(e);
                    if (!e || "refresh" === e.changeType || e.repaintChangesOnly && "update" === e.changeType) {
                        this.waitAsyncTemplates().done(() => {
                            this._updateSelectAllValue()
                        })
                    }
                },
                _renderSelectAllCheckBox($container, column) {
                    var that = this;
                    var selectionController = that.getController("selection");
                    var isEmptyData = that.getController("data").isEmpty();
                    var groupElement = $("<div>").appendTo($container).addClass(SELECT_CHECKBOX_CLASS);
                    that.setAria("label", messageLocalization.format("dxDataGrid-ariaSelectAll"), groupElement);
                    that.getController("editorFactory").createEditor(groupElement, extend({}, column, {
                        parentType: "headerRow",
                        dataType: "boolean",
                        value: selectionController.isSelectAll(),
                        editorOptions: {
                            visible: !isEmptyData && (that.option("selection.allowSelectAll") || false !== selectionController.isSelectAll())
                        },
                        tabIndex: that.option("useLegacyKeyboardNavigation") ? -1 : that.option("tabIndex") || 0,
                        setValue(value, e) {
                            var allowSelectAll = that.option("selection.allowSelectAll");
                            e.component.option("visible", allowSelectAll || false !== e.component.option("value"));
                            if (!e.event || selectionController.isSelectAll() === value) {
                                return
                            }
                            if (e.value && !allowSelectAll) {
                                e.component.option("value", false)
                            } else {
                                e.value ? selectionController.selectAll() : selectionController.deselectAll()
                            }
                            e.event.preventDefault()
                        }
                    }));
                    return groupElement
                },
                _attachSelectAllCheckBoxClickEvent($element) {
                    eventsEngine.on($element, clickEventName, this.createAction(e => {
                        var {
                            event: event
                        } = e;
                        if (!$(event.target).closest(".".concat(SELECT_CHECKBOX_CLASS)).length) {
                            eventsEngine.trigger($(event.currentTarget).children(".".concat(SELECT_CHECKBOX_CLASS)), clickEventName)
                        }
                        event.preventDefault()
                    }))
                }
            },
            rowsView: {
                renderSelectCheckBoxContainer($container, options) {
                    if ("data" === options.rowType && !options.row.isNewRow) {
                        $container.addClass(EDITOR_CELL_CLASS);
                        this._attachCheckBoxClickEvent($container);
                        this._renderSelectCheckBox($container, options)
                    } else {
                        gridCoreUtils.setEmptyText($container)
                    }
                },
                _renderSelectCheckBox(container, options) {
                    var groupElement = $("<div>").addClass(SELECT_CHECKBOX_CLASS).appendTo(container);
                    this.setAria("label", messageLocalization.format("dxDataGrid-ariaSelectRow"), groupElement);
                    this.getController("editorFactory").createEditor(groupElement, extend({}, options.column, {
                        parentType: "dataRow",
                        dataType: "boolean",
                        lookup: null,
                        value: options.value,
                        setValue(value, e) {
                            var _a;
                            if ("keydown" === (null === (_a = null === e || void 0 === e ? void 0 : e.event) || void 0 === _a ? void 0 : _a.type)) {
                                eventsEngine.trigger(e.element, clickEventName, e)
                            }
                        },
                        row: options.row
                    }));
                    return groupElement
                },
                _attachCheckBoxClickEvent($element) {
                    eventsEngine.on($element, clickEventName, this.createAction((function(e) {
                        var selectionController = this.getController("selection");
                        var {
                            event: event
                        } = e;
                        var rowIndex = this.getRowIndex($(event.currentTarget).closest(".".concat(ROW_CLASS)));
                        if (rowIndex >= 0) {
                            selectionController.startSelectionWithCheckboxes();
                            selectionController.changeItemSelection(rowIndex, {
                                shift: event.shiftKey
                            });
                            if ($(event.target).closest(".".concat(SELECT_CHECKBOX_CLASS)).length) {
                                this.getController("data").updateItems({
                                    changeType: "updateSelection",
                                    itemIndexes: [rowIndex]
                                })
                            }
                        }
                    })))
                },
                _update(change) {
                    var that = this;
                    var tableElements = that.getTableElements();
                    if ("updateSelection" === change.changeType) {
                        if (tableElements.length > 0) {
                            each(tableElements, (_, tableElement) => {
                                each(change.itemIndexes || [], (_, index) => {
                                    var $row;
                                    if (change.items[index]) {
                                        $row = that._getRowElements($(tableElement)).eq(index);
                                        if ($row.length) {
                                            var {
                                                isSelected: isSelected
                                            } = change.items[index];
                                            $row.toggleClass(ROW_SELECTION_CLASS, void 0 === isSelected ? false : isSelected).find(".".concat(SELECT_CHECKBOX_CLASS)).dxCheckBox("option", "value", isSelected);
                                            that.setAria("selected", isSelected, $row)
                                        }
                                    }
                                })
                            });
                            that._updateCheckboxesClass()
                        }
                    } else {
                        that.callBase(change)
                    }
                },
                _createTable() {
                    var that = this;
                    var selectionMode = that.option("selection.mode");
                    var $table = that.callBase.apply(that, arguments);
                    if ("none" !== selectionMode) {
                        if ("onLongTap" === that.option(SHOW_CHECKBOXES_MODE) || !touch) {
                            eventsEngine.on($table, addNamespace(holdEvent.name, "dxDataGridRowsView"), ".".concat(DATA_ROW_CLASS), that.createAction(e => {
                                processLongTap(that.component, e.event);
                                e.event.stopPropagation()
                            }))
                        }
                        eventsEngine.on($table, "mousedown selectstart", that.createAction(e => {
                            var {
                                event: event
                            } = e;
                            if (event.shiftKey) {
                                event.preventDefault()
                            }
                        }))
                    }
                    return $table
                },
                _createRow(row) {
                    var $row = this.callBase.apply(this, arguments);
                    if (row) {
                        var {
                            isSelected: isSelected
                        } = row;
                        if (isSelected) {
                            $row.addClass(ROW_SELECTION_CLASS)
                        }
                        var selectionMode = this.option(SELECTION_MODE);
                        if ("none" !== selectionMode) {
                            this.setAria("selected", isSelected, $row)
                        }
                    }
                    return $row
                },
                _rowClick(e) {
                    var dxEvent = e.event;
                    var isSelectionDisabled = $(dxEvent.target).closest(".".concat(SELECTION_DISABLED_CLASS)).length;
                    if (!this.isClickableElement($(dxEvent.target))) {
                        if (!isSelectionDisabled && ("multiple" !== this.option(SELECTION_MODE) || "always" !== this.option(SHOW_CHECKBOXES_MODE))) {
                            if (this.getController("selection").changeItemSelection(e.rowIndex, {
                                    control: isCommandKeyPressed(dxEvent),
                                    shift: dxEvent.shiftKey
                                })) {
                                dxEvent.preventDefault();
                                e.handled = true
                            }
                        }
                        this.callBase(e)
                    }
                },
                isClickableElement($target) {
                    var isCommandSelect = $target.closest(".".concat(COMMAND_SELECT_CLASS)).length;
                    return !!isCommandSelect
                },
                _renderCore(change) {
                    var deferred = this.callBase(change);
                    this._updateCheckboxesClass();
                    return deferred
                },
                _updateCheckboxesClass() {
                    var tableElements = this.getTableElements();
                    var selectionController = this.getController("selection");
                    var isCheckBoxesHidden = selectionController.isSelectColumnVisible() && !selectionController.isSelectionWithCheckboxes();
                    each(tableElements, (_, tableElement) => {
                        $(tableElement).toggleClass(CHECKBOXES_HIDDEN_CLASS, isCheckBoxesHidden)
                    })
                }
            }
        }
    }
};
