import '../../assert/js/assert.js';
import './PhetioIDUtils.js';
import '../../globals.js';
import TEmitter from '../../axon/js/TEmitter.js';
import IntentionalAny from '../../phet-core/js/types/IntentionalAny.js';
import PickRequired from '../../phet-core/js/types/PickRequired.js';
import StrictOmit from '../../phet-core/js/types/StrictOmit.js';
import PhetioObject, { PhetioObjectMetadataInput, PhetioObjectOptions } from './PhetioObject.js';
import Tandem from './Tandem.js';
import { PhetioElementMetadata, PhetioState } from './TandemConstants.js';
import IOType from './types/IOType.js';
export type ClearOptions = {
    phetioState?: PhetioState | null;
};
type SelfOptions = {
    supportsDynamicState?: boolean;
    containerSuffix?: string;
    phetioDynamicElementName?: string;
};
export type PhetioDynamicElementContainerOptions = SelfOptions & StrictOmit<PhetioObjectOptions, 'phetioDynamicElement'> & PickRequired<PhetioObjectOptions, 'phetioType'>;
declare abstract class PhetioDynamicElementContainer<T extends PhetioObject, CreateElementArguments extends IntentionalAny[] = []> extends PhetioObject {
    private readonly _archetype;
    readonly elementCreatedEmitter: TEmitter<[T, string]>;
    readonly elementDisposedEmitter: TEmitter<[T, string]>;
    private notificationsDeferred;
    private readonly deferredCreations;
    private readonly deferredDisposals;
    readonly supportsDynamicState: boolean;
    protected phetioDynamicElementName: string;
    protected createElement: (t: Tandem, ...args: CreateElementArguments) => T;
    protected defaultArguments: CreateElementArguments | (() => CreateElementArguments);
    /**
     * @param createElement - function that creates a dynamic readonly element to be housed in
     * this container. All of this dynamic element container's elements will be created from this function, including the
     * archetype.
     * @param defaultArguments - arguments passed to createElement when creating the archetype
     * @param [providedOptions] - describe the Group itself
     */
    constructor(createElement: (t: Tandem, ...args: CreateElementArguments) => T, defaultArguments: CreateElementArguments | (() => CreateElementArguments), providedOptions?: PhetioDynamicElementContainerOptions);
    /**
     * @returns true if all children of a single dynamic element (based on phetioID) have had their state set already.
     */
    private stateSetOnAllChildrenOfDynamicElement;
    /**
     * Archetypes are created to generate the baseline file, or to validate against an existing baseline file.  They are
     * PhetioObjects and registered with the phetioEngine, but not send out via notifications from PhetioEngine.phetioElementAddedEmitter(),
     * because they are intended for internal usage only.  Archetypes should not be created in production code.
     *
     * PhetioDynamicElementContainer calls this method internally to create and assign its own archetype, but this method
     * can additionally be called with alternate archetypeTandem and/or createElementArgs to create alternate archetypes.
     * This can be necessary in situations that require archetypes provided to other archetypes, or with other forms
     * of dependency injection, such as in https://github.com/phetsims/tandem/issues/312
     */
    createArchetype(archetypeTandem?: Tandem, createElementArgs?: (CreateElementArguments | (() => CreateElementArguments))): T | null;
    /**
     * Create a dynamic PhetioObject element for this container
     * @param componentName
     * @param argsForCreateFunction
     * @param containerParameterType - null in PhET brand
     */
    createDynamicElement(componentName: string, argsForCreateFunction: CreateElementArguments, containerParameterType: IOType | null): T;
    /**
     * A dynamic element should be an instrumented PhetioObject with phetioDynamicElement: true
     */
    private assertDynamicPhetioObject;
    /**
     * Emit a created or disposed event.
     */
    private emitDataStreamEvent;
    /**
     * Emit events when dynamic elements are created.
     */
    private createdEventListener;
    /**
     * Emit events when dynamic elements are disposed.
     */
    private disposedEventListener;
    dispose(): void;
    /**
     * Dispose a contained element
     */
    protected disposeElement(element: T): void;
    /**
     * Called when clearing the contents of this container to ready things for setting its state. In general, this class
     * is set up to destroy and then recreate all of its elements instead of mutating them.
     */
    abstract clear(clearOptions?: ClearOptions): void;
    /**
     * Flush a single element from the list of deferred disposals that have not yet notified about the disposal. This
     * should never be called publicly, instead see `disposeElement`
     */
    private notifyElementDisposedWhileDeferred;
    /**
     * Should be called by subtypes upon element creation, see PhetioGroup as an example.
     */
    protected notifyElementCreated(createdElement: T): void;
    /**
     * Flush a single element from the list of deferred creations that have not yet notified about the disposal. This
     * is only public to support specific order dependencies in the PhetioStateEngine, otherwise see `this.notifyElementCreated()`
     * (PhetioGroupTests, phet-io) - only the PhetioStateEngine should notify individual elements created.
     */
    notifyElementCreatedWhileDeferred(createdElement: T): void;
    /**
     * When set to true, creation and disposal notifications will be deferred until set to false. When set to false,
     * this function will flush all the notifications for created and disposed elements (in that order) that occurred
     * while this container was deferring its notifications.
     */
    setNotificationsDeferred(notificationsDeferred: boolean): void;
    /**
     * @throws error if trying to access when archetypes aren't being created.
     */
    get archetype(): T;
    /**
     * Add the phetioDynamicElementName for API tracking
     */
    getMetadata(object: PhetioObjectMetadataInput): PhetioElementMetadata;
}
export default PhetioDynamicElementContainer;
//# sourceMappingURL=PhetioDynamicElementContainer.d.ts.map