import '../../../../../assert/js/assert.js';
import '../../../../../globals.js';
/**
 * "Group Sort Interaction" overview:
 * Model type for the "group sort" interaction. This interaction behaves as such:
 * - Alt input treats the entire group as a single entity. Instead of using scenery focus control, it is handled internally.
 * - Focusing on the group highlights a "selected" group item. The interaction starts in "selection" state.
 * - Interaction keys change the "selection" (focus) of a group item. Focus highlight around the selected item is solid.
 * - The selected item is grabbable (see note below).
 * - Space/enter are used to "grab" the selection, turning the interaction state to "sorting" state. Pressing again
 *   toggles back to "selection" state. In sorting state, the focus highlight is dashed.
 * - Interaction keys in "sorting" state sort the group item, which changes the value of that group item.
 *
 * NOTE: "focus" in this interaction is called "selection" as to not overload the term. This is because the
 * "focused" group item is stored and changed even when it doesn't have browser focus on it. See selectedGroupItemProperty.
 *
 * Class Overview:
 * This class holds model information about the state of the group sort interaction. This includes specifics about
 * whether the interaction is in "selection" or "sorting" state. Also about if portions of the interaction have
 * "successfully" occurred such that hint cues don't need to be displayed anymore.
 *
 * A note about mouse input:
 * All group sort instances thus far have been accompanied by mouse/touch input as well. Though this goes beyond the
 * scope of group sort to implement, there are mouse-specific Properties here in the model that help sync group
 * sort state/cueing with the visual cueing too. Please follow instructions below to make sure those are used
 * appropriately.
 *
 * A note about using with scenes:
 * In general, there is just one instance of this per model, and not per scene. This is because if someone can
 * successfully grab and sort in one scene, then that learned understanding about the interaction should transfer to
 * the next scene.
 *
 * A note about PhET-iO:
 * Properties that handle visual cue states are not PhET-iO instrumented, because they are considered transient.
 * See showMouseCueProperty for the extent of PhET-iO customization.
 *
 * Implementation steps (these steps apply to the model and view):
 * - use with GroupSortInteractionView
 * - reset selectedGroupItemProperty with a sim-specific heuristic when the underlying model needs to update the best
 *   first selection. (Also see GroupSortInteractionView.getGroupItemToSelect for a hook to apply this on group focus).
 * - the grab/release cue is created for you, and can be repositioned by accessing from your GroupSortInteractionView instance.
 * - Handle your own keyboard and mouse "sort indicator cue node" (see registerUpdateSortCueNode())
 * - use setMouseSortedGroupItem( true ) on mouse/touch sorting interactions to make sure that the mouse sort cue visibility is correct.
 * - mouseSortCueVisibleProperty should be set by client, using mouseSortCueShouldBeVisible() in addition to any sim-specific logic required.
 * - It is best to use one model per screen and one view per scene.
 * - use GroupSortInteractionView.groupSortGroupFocusHighlightPath.shape to set the group highlight dynamically
 * - use positionSortCueNodeEmitter to update the position of the sort cue for the keyboard interaction.
 * - use enabledProperty to control if sorting is enabled. Note that focus and selection are always available (for keyboard tab order consistency)
 * - Note that if GroupSelectModel is PhET-iO instrumented, ItemModel must be a PhetioObject.
 *
 * @author Michael Kauzmann (PhET Interactive Simulations)
 * @author Marla Schulz (PhET Interactive Simulations)
 */
import BooleanProperty from '../../../../../axon/js/BooleanProperty.js';
import EnabledComponent, { EnabledComponentOptions } from '../../../../../axon/js/EnabledComponent.js';
import Property from '../../../../../axon/js/Property.js';
import TReadOnlyProperty from '../../../../../axon/js/TReadOnlyProperty.js';
import { PhetioObjectOptions } from '../../../../../tandem/js/PhetioObject.js';
type SelfOptions<ItemModel> = {
    getGroupItemValue: (itemModel: ItemModel) => number | null;
    initialMouseSortCueVisible?: boolean;
} & Pick<PhetioObjectOptions, 'tandem'>;
type ParentOptions = EnabledComponentOptions;
export type GroupSelectModelOptions<ItemModel> = SelfOptions<ItemModel> & ParentOptions;
export default class GroupSelectModel<ItemModel> extends EnabledComponent {
    readonly selectedGroupItemProperty: Property<ItemModel | null>;
    readonly isGroupItemKeyboardGrabbedProperty: BooleanProperty;
    readonly grabReleaseCueVisibleProperty: TReadOnlyProperty<boolean>;
    readonly keyboardSortCueVisibleProperty: TReadOnlyProperty<boolean>;
    readonly isKeyboardFocusedProperty: BooleanProperty;
    readonly hasKeyboardGrabbedGroupItemProperty: BooleanProperty;
    readonly hasKeyboardSortedGroupItemProperty: BooleanProperty;
    readonly hasKeyboardSelectedGroupItemProperty: BooleanProperty;
    readonly mouseSortCueVisibleProperty: Property<boolean>;
    private readonly showMouseCueProperty;
    readonly hasMouseSortedGroupItemProperty: BooleanProperty;
    readonly hasGroupItemBeenSortedProperty: TReadOnlyProperty<boolean>;
    readonly getGroupItemValue: (itemModel: ItemModel) => number | null;
    constructor(providedOptions?: GroupSelectModelOptions<ItemModel>);
    setMouseSortedGroupItem(sortedByMouse: boolean): void;
    mouseSortCueShouldBeVisible(): boolean;
    /**
     * Reset the interaction without changing the cueing logic. This is best called during a data "erase" and also when
     * switching between scenes.
     */
    resetInteractionState(): void;
    reset(): void;
    clearSelection(): void;
    registerUpdateSortCueNode(updateSortIndicatorNode: () => void): void;
    interrupt(): void;
    dispose(): void;
}
export {};
//# sourceMappingURL=GroupSelectModel.d.ts.map