/**
 * DevExtreme (esm/__internal/grids/tree_list/data_controller/m_data_controller.js)
 * Version: 24.1.7-build-24272-1937
 * Build date: Sat Sep 28 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
import {
    equalByValue
} from "../../../../core/utils/common";
import {
    Deferred
} from "../../../../core/utils/deferred";
import {
    extend
} from "../../../../core/utils/extend";
import {
    DataController,
    dataControllerModule
} from "../../../grids/grid_core/data_controller/m_data_controller";
import dataSourceAdapterProvider from "../data_source_adapter/m_data_source_adapter";
import treeListCore from "../m_core";
export class TreeListDataController extends DataController {
    _getDataSourceAdapter() {
        return dataSourceAdapterProvider
    }
    _getNodeLevel(node) {
        let level = -1;
        while (node.parent) {
            if (node.visible) {
                level++
            }
            node = node.parent
        }
        return level
    }
    _generateDataItem(node, options) {
        return {
            rowType: "data",
            node: node,
            key: node.key,
            data: node.data,
            isExpanded: this.isRowExpanded(node.key, options),
            level: this._getNodeLevel(node)
        }
    }
    _loadOnOptionChange() {
        this._dataSource.load()
    }
    _isItemEquals(item1, item2) {
        if (item1.isSelected !== item2.isSelected) {
            return false
        }
        if (item1.node && item2.node && item1.node.hasChildren !== item2.node.hasChildren) {
            return false
        }
        if (item1.level !== item2.level || item1.isExpanded !== item2.isExpanded) {
            return false
        }
        return super._isItemEquals.apply(this, arguments)
    }
    _isCellChanged(oldRow, newRow, visibleRowIndex, columnIndex, isLiveUpdate) {
        const firstDataColumnIndex = this._columnsController.getFirstDataColumnIndex();
        if (columnIndex === firstDataColumnIndex && oldRow.isSelected !== newRow.isSelected) {
            return true
        }
        return super._isCellChanged.apply(this, arguments)
    }
    init() {
        this.createAction("onRowExpanding");
        this.createAction("onRowExpanded");
        this.createAction("onRowCollapsing");
        this.createAction("onRowCollapsed");
        super.init.apply(this, arguments)
    }
    keyOf(data) {
        const dataSource = this._dataSource;
        if (dataSource) {
            return dataSource.keyOf(data)
        }
    }
    key() {
        const dataSource = this._dataSource;
        if (dataSource) {
            return dataSource.getKeyExpr()
        }
    }
    publicMethods() {
        return super.publicMethods().concat(["expandRow", "collapseRow", "isRowExpanded", "getRootNode", "getNodeByKey", "loadDescendants", "forEachNode"])
    }
    changeRowExpand(key) {
        if (this._dataSource) {
            const args = {
                key: key
            };
            const isExpanded = this.isRowExpanded(key);
            this.executeAction(isExpanded ? "onRowCollapsing" : "onRowExpanding", args);
            if (!args.cancel) {
                return this._dataSource.changeRowExpand(key).done((() => {
                    this.executeAction(isExpanded ? "onRowCollapsed" : "onRowExpanded", args)
                }))
            }
        }
        return (new Deferred).resolve()
    }
    isRowExpanded(key, cache) {
        return this._dataSource && this._dataSource.isRowExpanded(key, cache)
    }
    expandRow(key) {
        if (!this.isRowExpanded(key)) {
            return this.changeRowExpand(key)
        }
        return (new Deferred).resolve()
    }
    collapseRow(key) {
        if (this.isRowExpanded(key)) {
            return this.changeRowExpand(key)
        }
        return (new Deferred).resolve()
    }
    getRootNode() {
        return this._dataSource && this._dataSource.getRootNode()
    }
    optionChanged(args) {
        switch (args.name) {
            case "rootValue":
            case "parentIdExpr":
            case "itemsExpr":
            case "filterMode":
            case "expandNodesOnFiltering":
            case "autoExpandAll":
            case "hasItemsExpr":
            case "dataStructure":
                this._columnsController.reset();
                this._items = [];
                this._refreshDataSource();
                args.handled = true;
                break;
            case "expandedRowKeys":
            case "onNodesInitialized":
                if (this._dataSource && !this._dataSource._isNodesInitializing && !equalByValue(args.value, args.previousValue)) {
                    this._loadOnOptionChange()
                }
                args.handled = true;
                break;
            case "maxFilterLengthInRequest":
                args.handled = true;
                break;
            default:
                super.optionChanged(args)
        }
    }
    getNodeByKey(key) {
        if (!this._dataSource) {
            return
        }
        return this._dataSource.getNodeByKey(key)
    }
    getChildNodeKeys(parentKey) {
        if (!this._dataSource) {
            return
        }
        return this._dataSource.getChildNodeKeys(parentKey)
    }
    loadDescendants(keys, childrenOnly) {
        if (!this._dataSource) {
            return
        }
        return this._dataSource.loadDescendants(keys, childrenOnly)
    }
    forEachNode() {
        this._dataSource.forEachNode.apply(this, arguments)
    }
}
treeListCore.registerModule("data", {
    defaultOptions: () => extend({}, dataControllerModule.defaultOptions(), {
        itemsExpr: "items",
        parentIdExpr: "parentId",
        rootValue: 0,
        dataStructure: "plain",
        expandedRowKeys: [],
        filterMode: "withAncestors",
        expandNodesOnFiltering: true,
        autoExpandAll: false,
        onNodesInitialized: null,
        maxFilterLengthInRequest: 1500,
        paging: {
            enabled: false
        }
    }),
    controllers: {
        data: TreeListDataController
    }
});
