# src/explorer/ClassesExplorer.js

    import {TreeViewPlugin, math} from "@xeokit/xeokit-sdk/dist/xeokit-sdk.es.js";
    import {Controller} from "../Controller.js";
    import {TreeViewContextMenu} from "../contextMenus/TreeViewContextMenu.js";

    /** @private */
    class ClassesExplorer extends Controller {

        constructor(parent, cfg = {}) {

            super(parent);

            if (!cfg.classesTabElement) {
                throw "Missing config: classesTabElement";
            }

            if (!cfg.showAllClassesButtonElement) {
                throw "Missing config: showAllClassesButtonElement";
            }

            if (!cfg.hideAllClassesButtonElement) {
                throw "Missing config: hideAllClassesButtonElement";
            }

            if (!cfg.classesElement) {
                throw "Missing config: classesElement";
            }

            this._classesTabElement = cfg.classesTabElement;
            this._showAllClassesButtonElement = cfg.showAllClassesButtonElement;
            this._hideAllClassesButtonElement = cfg.hideAllClassesButtonElement;
            this._classesTabButtonElement = this._classesTabElement.querySelector(".xeokit-tab-btn");

            if (!this._classesTabButtonElement) {
                throw "Missing DOM element: xeokit-tab-btn";
            }

            const classesElement = cfg.classesElement;

            this._treeView = new TreeViewPlugin(this.viewer, {
                containerElement: classesElement,
                hierarchy: "types",
                autoAddModels: false,
                pruneEmptyNodes: true
            });

            this._treeViewContextMenu = new TreeViewContextMenu(this.bimViewer, {
                hideOnAction: true
            });

            this._treeView.on("contextmenu", (e) => {
                this._treeViewContextMenu.context = {
                    bimViewer: this.bimViewer,
                    viewer: e.viewer,
                    treeViewPlugin: e.treeViewPlugin,
                    treeViewNode: e.treeViewNode
                };
                this._treeViewContextMenu.show(e.event.pageX, e.event.pageY);
            });

            this._treeView.on("nodeTitleClicked", (e) => {
                const scene = this.viewer.scene;
                const objectIds = [];
                e.treeViewPlugin.withNodeTree(e.treeViewNode, (treeViewNode) => {
                    if (treeViewNode.objectId) {
                        objectIds.push(treeViewNode.objectId);
                    }
                });
                const checked = e.treeViewNode.checked;
                if (checked) {
                    scene.setObjectsXRayed(objectIds, false);
                    scene.setObjectsVisible(objectIds, false);
                    scene.setObjectsPickable(objectIds, true);
                } else {
                    scene.setObjectsXRayed(objectIds, false);
                    scene.setObjectsVisible(objectIds, true);
                    scene.setObjectsPickable(objectIds, true);
                }
            });

            this._onModelLoaded = this.viewer.scene.on("modelLoaded", (modelId) => {
                if (this.viewer.metaScene.metaModels[modelId]) {
                    const modelInfo = this.bimViewer._modelsExplorer.getModelInfo(modelId);
                    if (!modelInfo) {
                        return;
                    }
                    this._treeView.addModel(modelId, {
                        rootName: modelInfo.name
                    });
                }
            });

            this._onModelUnloaded = this.viewer.scene.on("modelUnloaded", (modelId) => {
                if (this.viewer.metaScene.metaModels[modelId]) {
                    this._treeView.removeModel(modelId);
                }
            });

            this.bimViewer.on("reset", () => {
                this._treeView.collapse();
            });
        }

        setEnabled(enabled) {
            if (!enabled) {
                this._classesTabButtonElement.classList.add("disabled");
                this._showAllClassesButtonElement.classList.add("disabled");
                this._hideAllClassesButtonElement.classList.add("disabled");
            } else {
                this._classesTabButtonElement.classList.remove("disabled");
                this._showAllClassesButtonElement.classList.remove("disabled");
                this._hideAllClassesButtonElement.classList.remove("disabled");
            }
        }

        expandTreeViewToDepth(depth) {
            this._treeView.expandToDepth(depth);
        }

        showNodeInTreeView(objectId) {
            this._treeView.collapse();
            this._treeView.showNode(objectId);
        }

        unShowNodeInTreeView() {
            this._treeView.unShowNode();
        }

        destroy() {
            super.destroy();
            this._treeView.destroy();
            this._treeViewContextMenu.destroy();
            this.viewer.scene.off(this._onModelLoaded);
            this.viewer.scene.off(this._onModelUnloaded);
        }
    }

    export {ClassesExplorer};