/**
* @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/**
* @module comments/annotations/annotationsuis
* @publicApi
*/
import { ContextPlugin, type Plugin, type Editor, type Context, type PluginDependenciesOf } from "@ckeditor/ckeditor5-core";
import { type Emitter } from "@ckeditor/ckeditor5-utils";
import { AnnotationCollection } from "./annotationcollection.js";
import { Annotations } from "./annotations.js";
import { type Annotation } from "./annotation.js";
/**
* A repository of annotations UIs.
*
* The main entry point for {@link module:comments/annotations/annotationsuis~AnnotationsUIs#register registering} UIs
* and activating the annotations UI(s), which display annotation views.
*
* To register a custom annotations UI use following code in the annotations UI plugin `init()` function:
*
* ```ts
* const annotationsUIs = editor.plugins.get( 'annotationsUIs' );
*
* annotationsUIs.register( customAnnotationsUIPlugin );
* ```
*
* Note that the custom annotations UI must implement {@link module:comments/annotations/annotationsuis~AnnotationsUI
* the `AnnotationsUI` interface}.
*
* To activate an annotations UI, use the {@link module:comments/annotations/annotationsuis~AnnotationsUIs#switchTo
* `switchTo( uiName )`} method. This method activates the given UI and deactivates all the other UIs.
* All annotations will be handled by the activated UI.
*
* It is also possible to activate multiple annotations UIs at the same time and make the UIs handle different sets of annotations.
* To do that, use the {@link module:comments/annotations/annotationsuis~AnnotationsUIs#activate `activate( uiName, filter )`} method.
*
* ```ts
* // Suggestions annotations are shown inline in a balloon:
* annotationsUIs.activate( 'inline', annotation => annotation.type.startsWith( 'suggestion' ) );
*
* // At the same time, comments annotations are shown in a sidebar:
* annotationsUIs.activate( 'wideSidebar', annotation => annotation.type === 'comment' );
* ```
*
* Limitations:
*
* * Some annotations UI plugins might collide with each other (like {@link module:comments/annotations/narrowsidebar~NarrowSidebar} and
* {@link module:comments/annotations/widesidebar~WideSidebar} that operates on the same sidebar). They cannot be activated at the same
* time.
* * It is not possible to display the same annotation in two different annotations UIs. In this scenario an error will be thrown.
*/
export declare class AnnotationsUIs extends ContextPlugin {
	/**
	* A set of names of the active annotations UIs.
	*
	* To activate the annotations UI, use {@link module:comments/annotations/annotationsuis~AnnotationsUIs#activate}
	* or {@link #switchTo} methods.
	*/
	activeUIs: Set<string>;
	/**
	* @inheritDoc
	*/
	static get requires(): PluginDependenciesOf<[Annotations]>;
	/**
	* @inheritDoc
	*/
	static get pluginName(): "AnnotationsUIs";
	/**
	* @inheritDoc
	*/
	static override get isOfficialPlugin(): true;
	/**
	* @inheritDoc
	*/
	static override get isPremiumPlugin(): true;
	/**
	* @inheritDoc
	*/
	constructor(context: Context | Editor);
	/**
	* @inheritDoc
	*/
	init(): void;
	/**
	* Returns `true` if at least one registered UI is active.
	*/
	hasActive(): boolean;
	/**
	* Returns `true` if the given UI is active.
	*/
	isActive(uiName: string): boolean;
	/**
	* Activates an annotations UI.
	*
	* Note that the custom annotations UI should be {@link #register registered} before the activation.
	*
	* The `filter` parameter can be used to display on some of the annotations in the given annotations UI. Thanks to that,
	* all annotations can be split into various annotations UIs.
	*
	* The `filter` function takes an {@link module:comments/annotations/annotation~Annotation} instance as the first and only parameter,
	* and should return `true` if that annotation should be placed in the given annotations UI.
	*
	* @param uiName The name of the annotations UI to activate.
	* @param filter The annotation filter function. If not specified, the UI will use all annotations.
	*/
	activate(uiName: string, filter?: (annotation: Annotation) => boolean): void;
	/**
	* Deactivates annotations UI with given name.
	*
	* @param uiName The name of the annotations UI to deactivate.
	*/
	deactivate(uiName: string): void;
	/**
	* Switches the annotations UI to the one with given name.
	*
	* It preserves the currently active annotation.
	*
	* @param uiName The name of the annotations UI to switch to.
	*/
	switchTo(uiName: string): void;
	/**
	* Deactivates all annotations UIs.
	*/
	deactivateAll(): void;
	/**
	* Registers an annotations UI. It might be one of:
	*
	* * {@link module:comments/annotations/widesidebar~WideSidebar},
	* * {@link module:comments/annotations/narrowsidebar~NarrowSidebar},
	* * {@link module:comments/annotations/inlineannotations~InlineAnnotations}.
	*
	* It is possible to provide your own, custom annotations UI plugin. It has to implement
	* {@link module:comments/annotations/annotationsuis~AnnotationsUI the `AnnotationsUI` interface}.
	*
	* @param uiName Annotations UI name.
	* @param annotationsUI Annotations UI plugin instance.
	*/
	register(uiName: string, annotationsUI: AnnotationsUI<ContextPlugin | Plugin>): void;
	/**
	* Refilters annotations to proper UIs based on filters provided earlier during the
	* {@link module:comments/annotations/annotationsuis~AnnotationsUIs#activate annotations UIs activation}.
	*
	* This method should be used if the annotations UIs filtering functions return different results than before
	* for some annotations. It only reattaches these annotations, which should change their UIs.
	*/
	refilterAnnotations(): void;
	/**
	* @inheritDoc
	*/
	override destroy(): void;
	/**
	* A default pass-by filter function that returns `true` for all annotations to be used when no filter for UI is provided.
	*/
	defaultFilter(): boolean;
}
/**
* An interface for the annotations UI plugin class.
*
* The annotations UI class handles displaying, focusing, activating and hiding annotations views.
*
* The annotations UI class must be a plugin, so it has to extend the {@link module:core/plugin~Plugin} or
* {@link module:core/contextplugin~ContextPlugin} class.
*
* Examples of `AnnotationsUI` are:
*
* * {@link module:comments/annotations/widesidebar~WideSidebar},
* * {@link module:comments/annotations/narrowsidebar~NarrowSidebar},
* * {@link module:comments/annotations/inlineannotations~InlineAnnotations}.
*
* You can use the following snippet as a base for your own annotations UI:
*
* ```ts
* class MyAnnotationsUI extends ContextPlugin {
* 	constructor( ...args ) {
* 		super( ...args );
*
* 		this.set( 'activeAnnotation', null );
* 	}
*
* 	attach( annotations ) {
* 		// Do something when an annotation is added.
* 		this.listenTo( annotations, 'add', ( evt, annotation ) => { ... } );
*
* 		// Do something when an annotation is removed.
* 		this.listenTo( annotations, 'remove', ( evt, annotation ) => { ... } );
* 	}
*
* 	detach() {
* 		this.stopListening();
* 	}
*
* 	setActiveAnnotation( annotation ) {
* 		if ( this.activeAnnotation ) {
* 			this.activeAnnotation.isActive = false;
*
* 			// You can do something in your UI with the annotation that is no longer active.
* 		}
*
* 		this.activeAnnotation = annotation;
* 		this.activeAnnotation.isActive = true;
*
* 		// You can do something in your UI to highlight the active annotation.
* 	}
* }
* ```
*/
export interface AnnotationUI {
	/**
	* Observable `activeAnnotation` property. {@link module:comments/annotations/annotationsuis~AnnotationsUIs} listens to changes on that
	* property.
	*
	* To make this property observable use `this.set( 'activeAnnotation', null )` in the constructor.
	*/
	activeAnnotation: Annotation | null;
	/**
	* Creates everything needed for the UI and attaches all listeners. This method is called when the UI is activated.
	*
	* The observable collection of annotations is passed as the first argument,
	* and the annotations UI is responsible for reacting to its changes.
	*/
	attach: (annotationCollection: AnnotationCollection) => void;
	/**
	* Destroys the UI and removes all listeners. This method is called when the UI is deactivated.
	*/
	detach: () => void;
	/**
	* Sets or unsets the active annotation. This method is called when an annotation is activated, for example, user puts their
	* selection into a marker connected with given annotation.
	*
	* This method should change the UI so the new active annotation is differentiated from other annotations.
	*
	* This method should set the
	* {@link #activeAnnotation `AnnotationUI#activeAnnotation`} property.
	*
	* It also should set {@link module:comments/annotations/annotation~Annotation#isActive `Annotation#isActive`} of the deactivated
	* and the activated annotation.
	*
	* @param annotation The new active annotation or null when no annotation is active.
	*/
	setActiveAnnotation: (annotation: Annotation | null) => void;
	_setSelectedAnnotations?: (annotations: Array<Annotation>) => void;
}
export type AnnotationsUI<T extends Emitter> = T & AnnotationUI;
