/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module NavigationAids
 */
import "./SheetNavigationAid.scss";
import classnames from "classnames";
import * as React from "react";
import { IModelApp } from "@itwin/core-frontend";
import { UiComponents } from "@itwin/components-react";
import { ViewportComponentEvents } from "@itwin/imodel-components-react";
import { UiFramework } from "../UiFramework";
import { ViewUtilities } from "../utils/ViewUtilities";
import { NavigationAidControl } from "./NavigationAidControl";
import { CardContainer, SheetsModalFrontstage } from "./SheetsModalFrontstage";
import { IconButton, ProgressRadial } from "@itwin/itwinui-react";
import { SvgChevronLeft, SvgChevronRight } from "@itwin/itwinui-icons-react";
/** A Sheet Navigation Aid control.
 * @alpha
 */
class SheetNavigationAidControl extends NavigationAidControl {
    constructor(info, options) {
        super(info, options);
        this.reactNode = React.createElement(SheetNavigationAid, { iModelConnection: options.imodel });
    }
    // istanbul ignore next
    getSize() {
        return "96px";
    }
}
SheetNavigationAidControl.navigationAidId = "SheetNavigationAid";
export { SheetNavigationAidControl };
/** A Sheet Navigation Aid.
 * @alpha
 */
export class SheetNavigationAid extends React.Component {
    constructor(props) {
        super(props);
        this._isMounted = false;
        /** @internal */
        this.state = {
            index: 0,
            sheetData: [],
        };
        /** Sets index of newly selected card */
        this._handleCardSelected = (event) => {
            event &&
                this.setState({
                    index: event.index,
                });
        };
        /** Updates view to the next lowest index in sheetData */
        // istanbul ignore next
        this._handleOnClickLeftArrow = () => {
            this.setState((prevState) => ({
                index: prevState.index <= 0
                    ? prevState.sheetData.length - 1
                    : prevState.index - 1,
            }), async () => this._updateView());
        };
        /** Updates view to next highest index in sheetData */
        // istanbul ignore next
        this._handleOnClickRightArrow = () => {
            this.setState((prevState) => ({
                index: (prevState.index + 1) % prevState.sheetData.length,
            }), async () => this._updateView());
        };
        /** Handles a Viewport change & synchs the index */
        // istanbul ignore next
        this._handleSelectedViewportChanged = (args) => {
            if (args.current) {
                this._handleViewportChanged(args.current);
            }
        };
        // istanbul ignore next
        this._handleViewIdChanged = (args) => {
            if (this._viewport === args.viewport)
                this._handleViewportChanged(args.viewport);
        };
        /** Handles a Viewport change & synchs the index */
        // istanbul ignore next
        this._handleViewportChanged = (viewport) => {
            const className = ViewUtilities.getBisBaseClass(viewport.view.classFullName);
            if (ViewUtilities.isSheet(className)) {
                this._viewport = viewport;
                const viewId = this._viewport.view.id.toString();
                const index = this.state.sheetData.findIndex((sheetData) => {
                    return viewId === sheetData.viewId;
                });
                if (index >= 0)
                    this.setState({ index });
            }
        };
        /** Opens a new SheetsModelFrontstage on sheetName click */
        // istanbul ignore next
        this._handleOnClickSheetName = () => {
            UiFramework.frontstages.openModalFrontstage(this.modalFrontstage());
        };
        this._viewport = IModelApp.viewManager.selectedView;
    }
    /** Adds listeners when components mounts */
    async componentDidMount() {
        this._isMounted = true;
        CardContainer.onCardSelectedEvent.addListener(this._handleCardSelected);
        ViewportComponentEvents.onViewIdChangedEvent.addListener(this._handleViewIdChanged);
        IModelApp.viewManager.onSelectedViewportChanged.addListener(this._handleSelectedViewportChanged);
        const stateData = await this._setupSheets();
        if (this._isMounted)
            this.setState(stateData);
    }
    /** Removes listeners when component will unmount */
    componentWillUnmount() {
        this._isMounted = false;
        CardContainer.onCardSelectedEvent.removeListener(this._handleCardSelected);
        ViewportComponentEvents.onViewIdChangedEvent.removeListener(this._handleViewIdChanged);
        IModelApp.viewManager.onSelectedViewportChanged.removeListener(this._handleSelectedViewportChanged);
    }
    /** Queries for sheet info and sets as sheetData */
    async _setupSheets() {
        const stateData = {
            index: 0,
            sheetData: [],
        };
        // istanbul ignore else
        if (!this.props.iModelConnection ||
            !this.props.iModelConnection.views.getViewList)
            return stateData;
        // istanbul ignore next
        let viewId = "";
        // istanbul ignore next
        if (this._viewport) {
            viewId = this._viewport.view.id.toString();
        }
        // istanbul ignore next
        const sheets = await this.props.iModelConnection.views.getViewList({
            from: "BisCore.SheetViewDefinition",
        });
        // istanbul ignore next
        sheets.forEach((viewSpec, index) => {
            stateData.sheetData.push({ name: viewSpec.name, viewId: viewSpec.id });
            if (viewSpec.id === viewId)
                stateData.index = index;
        });
        // istanbul ignore next
        return stateData;
    }
    /** @internal */
    render() {
        const name = this.state.sheetData.length > 0
            ? /* istanbul ignore next */ this.state.sheetData[this.state.index].name
            : "";
        const sheet = UiFramework.translate("general.sheet");
        const ofStr = UiComponents.translate("general.of");
        const leftIndex = this.state.index === 0
            ? this.state.sheetData.length - 1
            : /* istanbul ignore next */ this.state.index - 1;
        const rightIndex = this.state.index >= this.state.sheetData.length - 1
            ? 0
            : /* istanbul ignore next */ this.state.index + 1;
        const leftTitle = this.state.sheetData[leftIndex]
            ? /* istanbul ignore next */ this.state.sheetData[leftIndex].name
            : undefined;
        const rightTitle = this.state.sheetData[rightIndex]
            ? /* istanbul ignore next */ this.state.sheetData[rightIndex].name
            : undefined;
        let content;
        // istanbul ignore if
        if (this.state.sheetData.length > 0) {
            content = (React.createElement(React.Fragment, null,
                React.createElement("div", { className: "sheet-title" }, sheet),
                React.createElement("div", { className: "sheet-name", title: name, onClick: this._handleOnClickSheetName, role: "button", tabIndex: -1 }, name),
                React.createElement("div", { className: "sheet-container" },
                    React.createElement(IconButton, { size: "small", styleType: "borderless", onClick: this._handleOnClickLeftArrow, tabIndex: -1, title: leftTitle },
                        React.createElement(SvgChevronLeft, null)),
                    React.createElement("div", null,
                        this.state.index + 1,
                        " ",
                        ofStr,
                        " ",
                        this.state.sheetData.length),
                    React.createElement(IconButton, { size: "small", styleType: "borderless", onClick: this._handleOnClickRightArrow, role: "button", tabIndex: -1, title: rightTitle },
                        React.createElement(SvgChevronRight, null)))));
        }
        else {
            content = React.createElement(ProgressRadial, { size: "x-small", indeterminate: true });
        }
        return (React.createElement("div", { className: classnames("uifw-sheet-navigation", this.props.className), style: this.props.style },
            React.createElement("div", { className: "gradient" }),
            content));
    }
    /** Updates view to currently set sheet */
    // istanbul ignore next
    async _updateView() {
        const viewState = await this.props.iModelConnection.views.load(this.state.sheetData[this.state.index].viewId);
        if (this._viewport)
            this._viewport.changeView(viewState);
    }
    /** Creates a new SheetsModalFrontstage */
    // istanbul ignore next
    modalFrontstage() {
        return new SheetsModalFrontstage(this.state.sheetData, this.props.iModelConnection, this.state.index);
    }
}
//# sourceMappingURL=SheetNavigationAid.js.map