/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module ContentView
 */
import { UiEvent } from "@itwin/appui-abstract";
import { ViewUtilities } from "../utils/ViewUtilities";
import { InternalContentLayoutManager } from "./InternalContentLayoutManager";
import { IModelApp } from "@itwin/core-frontend";
import { Logger } from "@itwin/core-bentley";
import { UiFramework } from "../UiFramework";
import { ActiveContentChangedEvent, MouseDownChangedEvent, } from "../framework/FrameworkContent";
import { InternalContentDialogManager } from "../dialog/InternalContentDialogManager";
/** Content View Manager class.
 * @internal
 */
class InternalContentViewManager {
    /** Determines if the mouse is down in a content view */
    static get isMouseDown() {
        return this._mouseDown;
    }
    /** Sets the mouse down status for a content view */
    static setMouseDown(mouseDown) {
        this._mouseDown = mouseDown;
        this.onMouseDownChangedEvent.emit({ mouseDown });
    }
    /** Gets the active content as a React.ReactNode. */
    static getActive() {
        return this._activeContent;
    }
    static getControlFromElement(content, activeContentGroup, floatingControls, logIfNotFound = false) {
        if (floatingControls === null || floatingControls === void 0 ? void 0 : floatingControls.length) {
            // if we find a React node that matches exactly, return its containing control
            let control = floatingControls.find((contentControl) => contentControl.reactNode === content);
            if (control)
                return control;
            // if we don't find a React node that matches exactly, rely on the id specified by the creator
            let controlId;
            if (content && content.key) {
                const key = content.key;
                // key has format `${contentProps.id}::${this.groupId}` which is stored as unique id
                controlId = key.split("::", 1)[0];
            }
            floatingControls.forEach((contentControl) => {
                const node = contentControl.reactNode;
                const key = node === null || node === void 0 ? void 0 : node.key;
                const nodeId = key && key.split("::", 1)[0];
                if (nodeId === controlId)
                    control = contentControl;
            });
            if (control)
                return control;
        }
        // if it's not a floating control, look through the content area views
        // istanbul ignore else
        if (activeContentGroup) {
            const activeContentControl = activeContentGroup.getControlFromElement(content);
            if (activeContentControl)
                return activeContentControl;
        }
        if (logIfNotFound)
            Logger.logError(UiFramework.loggerCategory(this), `getControlFromElement: no control found for element`);
        return undefined;
    }
    /** Return the active ContentControl. */
    static getActiveContentControl() {
        let activeContentControl;
        const activeFrontstageDef = UiFramework.frontstages.activeFrontstageDef;
        // istanbul ignore else
        if (this._activeContent && activeFrontstageDef) {
            const activeContentGroup = activeFrontstageDef.contentGroup;
            activeContentControl = this.getControlFromElement(this._activeContent, activeContentGroup, activeFrontstageDef.floatingContentControls);
        }
        return activeContentControl;
    }
    static addFloatingContentControl(contentControl) {
        const activeFrontstageDef = UiFramework.frontstages.activeFrontstageDef;
        // istanbul ignore else
        if (activeFrontstageDef && contentControl) {
            activeFrontstageDef.addFloatingContentControl(contentControl);
        }
    }
    static dropFloatingContentControl(contentControl) {
        const activeFrontstageDef = UiFramework.frontstages.activeFrontstageDef;
        // istanbul ignore else
        if (activeFrontstageDef && contentControl)
            activeFrontstageDef.dropFloatingContentControl(contentControl);
    }
    /** Sets the active [[ContentControl]] */
    static setActive(activeContent, forceEventProcessing = false) {
        // istanbul ignore else
        if (this._activeContent !== activeContent || forceEventProcessing) {
            const oldContent = this._activeContent;
            this._activeContent = activeContent;
            const activeFrontstageDef = UiFramework.frontstages.activeFrontstageDef;
            // istanbul ignore else
            if (activeFrontstageDef) {
                const activeContentGroup = activeFrontstageDef.contentGroup;
                // istanbul ignore else
                const oldContentControl = this.getControlFromElement(oldContent, activeContentGroup, activeFrontstageDef.floatingContentControls);
                const activeContentControl = this.getControlFromElement(activeContent, activeContentGroup, activeFrontstageDef.floatingContentControls, true);
                // Only call setActiveView if going to or coming from a non-viewport ContentControl
                // istanbul ignore else
                if (activeContentControl) {
                    // istanbul ignore next
                    const doSetActiveView = forceEventProcessing ||
                        !activeContentControl.viewport ||
                        /* istanbul ignore next */ (oldContentControl &&
                            /* istanbul ignore next */ !oldContentControl.viewport);
                    // istanbul ignore else
                    if (doSetActiveView) {
                        activeFrontstageDef.setActiveView(activeContentControl, oldContentControl);
                        this.onActiveContentChangedEvent.emit({
                            activeContent,
                            oldContent,
                        });
                    }
                    else {
                        if (activeContentControl.viewport &&
                            activeContentControl.viewport !==
                                IModelApp.viewManager.selectedView) {
                            void IModelApp.viewManager.setSelectedView(activeContentControl.viewport);
                        }
                    }
                }
            }
        }
    }
    /** Refreshes the active [[ContentControl]] */
    static refreshActive(activeContent) {
        this.layouts.refreshActive();
        this.setActive(activeContent, true);
    }
    /**
     * Determines if content displays a Sheet view.
     * @param content ContentControl to check
     */
    static isContentSheetView(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.isSheetView(content.viewport);
    }
    /**
     * Determines if content displays a Drawing view.
     * @param content ContentControl to check
     */
    static isContentDrawingView(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.isDrawingView(content.viewport);
    }
    /**
     * Determines if content displays a Spatial view.
     * @param content ContentControl to check
     */
    static isContentSpatialView(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.isSpatialView(content.viewport);
    }
    /**
     * Determines if content displays a Orthographic view.
     * @param content ContentControl to check
     */
    static isContentOrthographicView(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.isOrthographicView(content.viewport);
    }
    /**
     * Determines if content displays a 3d view.
     * @param content ContentControl to check
     */
    static isContent3dView(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.is3dView(content.viewport);
    }
    /**
     * Determines if viewport supports use of a camera.
     * @param content ContentControl to check
     */
    static contentSupportsCamera(content) {
        if (!content || !content.viewport)
            return false;
        return ViewUtilities.viewSupportsCamera(content.viewport);
    }
    /**
     * Manage content layouts.
     * @beta
     */
    static get layouts() {
        return InternalContentLayoutManager;
    }
    /**
     * Manage dialogs displaying managed content.
     * @beta
     */
    static get dialogs() {
        return InternalContentDialogManager;
    }
}
InternalContentViewManager._mouseDown = false;
/** Gets the [[MouseDownChangedEvent]] */
InternalContentViewManager.onMouseDownChangedEvent = new MouseDownChangedEvent();
/** Gets the [[ActiveContentChangedEvent]] */
InternalContentViewManager.onActiveContentChangedEvent = new ActiveContentChangedEvent();
/** Fires when floating contents are added or removed */
InternalContentViewManager.onAvailableContentChangedEvent = new UiEvent();
export { InternalContentViewManager };
//# sourceMappingURL=InternalContentViewManager.js.map