/**
 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module ui/panel/balloon/contextualballoon
 */
import BalloonPanelView from './balloonpanelview.js';
import View from '../../view.js';
import ButtonView from '../../button/buttonview.js';
import type ViewCollection from '../../viewcollection.js';
import { Plugin, type Editor } from '@ckeditor/ckeditor5-core';
import { FocusTracker, type Locale, type PositionOptions } from '@ckeditor/ckeditor5-utils';
import '../../../theme/components/panel/balloonrotator.css';
import '../../../theme/components/panel/fakepanel.css';
/**
 * Provides the common contextual balloon for the editor.
 *
 * The role of this plugin is to unify the contextual balloons logic, simplify views management and help
 * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}
 * instances in the editor.
 *
 * This plugin allows for creating single or multiple panel stacks.
 *
 * Each stack may have multiple views, with the one on the top being visible. When the visible view is removed from the stack,
 * the previous view becomes visible.
 *
 * It might be useful to implement nested navigation in a balloon. For instance, a toolbar view may contain a link button.
 * When you click it, a link view (which lets you set the URL) is created and put on top of the toolbar view, so the link panel
 * is displayed. When you finish editing the link and close (remove) the link view, the toolbar view is visible again.
 *
 * However, there are cases when there are multiple independent balloons to be displayed, for instance, if the selection
 * is inside two inline comments at the same time. For such cases, you can create two independent panel stacks.
 * The contextual balloon plugin will create a navigation bar to let the users switch between these panel stacks using the "Next"
 * and "Previous" buttons.
 *
 * If there are no views in the current stack, the balloon panel will try to switch to the next stack. If there are no
 * panels in any stack, the balloon panel will be hidden.
 *
 * **Note**: To force the balloon panel to show only one view, even if there are other stacks, use the `singleViewMode=true` option
 * when {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#add adding} a view to a panel.
 *
 * From the implementation point of view, the contextual ballon plugin is reusing a single
 * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance to display multiple contextual balloon
 * panels in the editor. It also creates a special {@link module:ui/panel/balloon/contextualballoon~RotatorView rotator view},
 * used to manage multiple panel stacks. Rotator view is a child of the balloon panel view and the parent of the specific
 * view you want to display. If there is more than one panel stack to be displayed, the rotator view will add a
 * navigation bar. If there is only one stack, the rotator view is transparent (it does not add any UI elements).
 */
export default class ContextualBalloon extends Plugin {
    /**
     * The {@link module:utils/dom/position~Options#limiter position limiter}
     * for the {@link #view balloon}, used when no `limiter` has been passed into {@link #add}
     * or {@link #updatePosition}.
     *
     * By default, a function that obtains the farthest DOM
     * {@link module:engine/view/rooteditableelement~RootEditableElement}
     * of the {@link module:engine/view/document~Document#selection}.
     */
    positionLimiter: PositionOptions['limiter'];
    visibleStack?: string;
    /**
     * The currently visible view or `null` when there are no views in any stack.
     *
     * @readonly
     * @observable
     */
    visibleView: View | null;
    /**
     * A total number of all stacks in the balloon.
     *
     * @private
     * @readonly
     * @observable
     */
    _numberOfStacks: number;
    /**
     * A flag that controls the single view mode.
     *
     * @private
     * @readonly
     * @observable
     */
    _singleViewMode: boolean;
    /**
     * The map of views and their stacks.
     */
    private _viewToStack;
    /**
     * The map of IDs and stacks.
     */
    private _idToStack;
    /**
     * The common balloon panel view.
     */
    private _view;
    /**
     * Rotator view embedded in the contextual balloon.
     * Displays the currently visible view in the balloon and provides navigation for switching stacks.
     */
    private _rotatorView;
    /**
     * Displays fake panels under the balloon panel view when multiple stacks are added to the balloon.
     */
    private _fakePanelsView;
    /**
     * @inheritDoc
     */
    static get pluginName(): "ContextualBalloon";
    /**
     * @inheritDoc
     */
    constructor(editor: Editor);
    /**
     * @inheritDoc
     */
    destroy(): void;
    /**
     * The common balloon panel view.
     */
    get view(): BalloonPanelView;
    /**
     * Returns `true` when the given view is in one of the stacks. Otherwise returns `false`.
     */
    hasView(view: View): boolean;
    /**
     * Adds a new view to the stack and makes it visible if the current stack is visible
     * or it is the first view in the balloon.
     *
     * @param data The configuration of the view.
     * @param data.stackId The ID of the stack that the view is added to. Defaults to `'main'`.
     * @param data.view The content of the balloon.
     * @param data.position Positioning options.
     * @param data.balloonClassName An additional CSS class added to the {@link #view balloon} when visible.
     * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow. Defaults to `true`.
     * @param data.singleViewMode Whether the view should be the only visible view even if other stacks were added. Defaults to `false`.
     */
    add(data: ViewConfiguration): void;
    /**
     * Removes the given view from the stack. If the removed view was visible,
     * the view preceding it in the stack will become visible instead.
     * When there is no view in the stack, the next stack will be displayed.
     * When there are no more stacks, the balloon will hide.
     *
     * @param view A view to be removed from the balloon.
     */
    remove(view: View): void;
    /**
     * Updates the position of the balloon using the position data of the first visible view in the stack.
     * When new position data is given, the position data of the currently visible view will be updated.
     *
     * @param position Position options.
     */
    updatePosition(position?: Partial<PositionOptions>): void;
    /**
     * Shows the last view from the stack of a given ID.
     */
    showStack(id: string): void;
    /**
     * Initializes view instances.
     */
    private _createPanelView;
    /**
     * Returns the stack of the currently visible view.
     */
    private get _visibleStack();
    /**
     * Returns the ID of the given stack.
     */
    private _getStackId;
    /**
     * Shows the last view from the next stack.
     */
    private _showNextStack;
    /**
     * Shows the last view from the previous stack.
     */
    private _showPrevStack;
    /**
     * Creates a rotator view.
     */
    private _createRotatorView;
    /**
     * Creates a fake panels view.
     */
    private _createFakePanelsView;
    /**
     * Sets the view as the content of the balloon and attaches the balloon using position
     * options of the first view.
     *
     * @param data Configuration.
     * @param data.view The view to show in the balloon.
     * @param data.balloonClassName Additional class name which will be added to the {@link #view balloon}.
     * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow.
     */
    private _showView;
    /**
     * Returns position options of the last view in the stack.
     * This keeps the balloon in the same position when the view is changed.
     */
    private _getBalloonPosition;
}
/**
 * The configuration of the view.
 */
export interface ViewConfiguration {
    /**
     * The ID of the stack that the view is added to.
     *
     * @default 'main'
     */
    stackId?: string;
    /**
     * The content of the balloon.
     */
    view: View;
    /**
     * Positioning options.
     */
    position?: Partial<PositionOptions>;
    /**
     * An additional CSS class added to the {@link #view balloon} when visible.
     */
    balloonClassName?: string;
    /**
     * Whether the {@link #view balloon} should be rendered with an arrow.
     *
     * @default true
     */
    withArrow?: boolean;
    /**
     * Whether the view should be the only visible view even if other stacks were added.
     *
     * @default false
     */
    singleViewMode?: boolean;
}
/**
 * Rotator view is a helper class for the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon}.
 * It is used for displaying the last view from the current stack and providing navigation buttons for switching stacks.
 * See the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon} documentation to learn more.
 */
export declare class RotatorView extends View {
    /**
     * Used for checking if a view is focused or not.
     */
    readonly focusTracker: FocusTracker;
    /**
     * Navigation button for switching the stack to the previous one.
     */
    readonly buttonPrevView: ButtonView;
    /**
     * Navigation button for switching the stack to the next one.
     */
    readonly buttonNextView: ButtonView;
    /**
     * A collection of the child views that creates the rotator content.
     */
    readonly content: ViewCollection;
    /**
     * Defines whether navigation is visible or not.
     *
     * @observable
     */
    isNavigationVisible: boolean;
    /**
     * @observable
     */
    counter: string;
    /**
     * @inheritDoc
     */
    constructor(locale: Locale);
    /**
     * @inheritDoc
     */
    render(): void;
    /**
     * @inheritDoc
     */
    destroy(): void;
    /**
     * Shows a given view.
     *
     * @param view The view to show.
     */
    showView(view: View): void;
    /**
     * Hides the currently displayed view.
     */
    hideView(): void;
    /**
     * Creates a navigation button view.
     *
     * @param label The button label.
     * @param icon The button icon.
     */
    private _createButtonView;
}
