import { EntityTypeUid, IComponent, IEntity, IEntityModel, IEntityProxy, IdentityComponent } from "./identity-component-CR1ULadR.js";

//#region src/entities/entity-events.d.ts

/**
 * Represents a unique identifier for an entity event.
 * Can be either a string or a number.
 */
type EntityEventUid = string | number;
/**
 * A filter function for entity event subscriptions.
 * Returns true if the event should be processed, false otherwise.
 */
type EntityEventSubscriptionFilter = (event: IEntityEvent<IEventData>) => boolean;
/**
 * The `IEventData` interface represents the data associated with an entity event.
 * It contains at least the `Event Unique Identifier`.
 */
interface IEventData {
  uid: EntityEventUid;
}
/**
 * The `IEntityEvent` interface represents a basic building block for a Publish/Subscribe pattern.
 * It is used to synchronize state between multiple entities.
 *
 * The events are scheduled as part of the `EntityUpdate` model.
 * Systems subscribe and receive updates with the events included in their `SystemContext`.
 */
interface IEntityEvent<TEventData extends IEventData> {
  origin: IEntityProxy;
  target?: IEntityProxy;
  data: TEventData;
}
/**
 * The `IEntityEventsManager` interface represents a Publish/Subscribe broker for `IEntityEvent` instances.
 * It keeps track of entity subscriptions (as part of the Observer design pattern).
 */
interface IEntityEventsManager {
  /**
   * Subscribes an entity to a specific event.
   * @param uid - The unique identifier of the event.
   * @param entity - The entity subscribing to the event.
   * @param filter - An optional filter function to determine if the event should be processed.
   */
  subscribe(uid: EntityEventUid, entity: IEntityProxy, filter?: EntityEventSubscriptionFilter): void;
  /**
   * Unsubscribes an entity from a specific event.
   * @param uid - The unique identifier of the event.
   * @param entity - The entity unsubscribing from the event.
   */
  unsubscribe(uid: EntityEventUid, entity: IEntityProxy): void;
  /**
   * Retrieves the entities subscribed to a specific event.
   * @param event - The event to retrieve subscriptions for.
   * @returns An array of entities subscribed to the event.
   */
  getSubscriptions(event: IEntityEvent<IEventData>): IEntityProxy[];
  /**
   * Retrieves the unique identifiers of events subscribed to by a specific entity.
   * @param entity - The entity to retrieve subscriptions for.
   * @returns An array of unique identifiers of events subscribed to by the entity.
   */
  getSubscriptionsForEntity(entity: IEntityProxy): EntityEventUid[];
  /**
   * Removes all subscriptions for all entities.
   */
  clearSubscriptions(): void;
  /**
   * Removes all subscriptions for a specific event.
   * @param uid - The unique identifier of the event to remove subscriptions from.
   */
  clearSubscriptionsForEvent(uid: EntityEventUid): void;
  /**
   * Removes all subscriptions for a specific entity.
   * @param entity - The entity to remove subscriptions from.
   */
  clearSubscriptionsForEntity(entity: IEntityProxy): void;
}
/**
 * The `IEntityEventsDispatcher` interface represents the main access point for dispatching events to entities.
 * It can leverage the `IEntityEventsManager` to find subscribers and the `IEntityUpdateQueue` to register events
 * into each observer entity's next update.
 */
interface IEntityEventsDispatcher {
  /**
   * Dispatches a single event to entities.
   * @param event - The event to dispatch.
   * @param targets - The entities to dispatch the event to.
   */
  dispatchEvent(event: IEntityEvent<IEventData>, ...targets: IEntityProxy[]): void;
  /**
   * Dispatches multiple events to entities.
   * @param events - The events to dispatch.
   * @param targets - The entities to dispatch the events to.
   */
  dispatchEvents(events: IEntityEvent<IEventData>[], ...targets: IEntityProxy[]): void;
}
//#endregion
//#region src/entities/entity-snapshot.d.ts
/**
 * The `IEntitySnapshot` interface represents a serializable state of an Entity.
 * It can contain the full or partial state of the Entity, including its identity, components, proxies, and events.
 * This interface is used to capture Entity state changes (deltas) or update existing Entity with changes from a remote source.
 */
interface IEntitySnapshot {
  /**
   * The identity of the Entity.
   */
  readonly identity?: Readonly<IdentityComponent<IEntityModel>>;
  /**
   * An array of components associated with the Entity.
   */
  readonly components?: IComponent[];
  /**
   * An array of proxies associated with the Entity.
   */
  readonly proxies?: IEntityProxy[];
  /**
   * An array of events associated with the Entity.
   */
  readonly events?: IEntityEvent<IEventData>[];
}
/**
 * The `IEntitySnapshotProvider` interface is the main provider for creating and updating Entity snapshots.
 * It provides methods to apply a snapshot to an Entity and to create a snapshot from an Entity.
 */
interface IEntitySnapshotProvider {
  /**
   * Applies a snapshot to an Entity.
   * This method updates the Entity's state based on the provided snapshot.
   *
   * @param entity - The Entity to apply the snapshot to.
   * @param snapshot - The snapshot to apply to the Entity.
   */
  applySnapshot(entity: IEntity, snapshot: IEntitySnapshot): void;
  /**
   * Creates a snapshot from an Entity.
   * This method captures the current state of the Entity and returns it as a snapshot.
   *
   * @param entity - The Entity to create a snapshot from.
   * @returns The created snapshot.
   */
  createSnapshot(entity: IEntity): IEntitySnapshot;
}
//#endregion
//#region src/entities/entity-queue.d.ts
/**
 * The `EntityUpdateType` enum specifies whether the current Entity should be `updated` or `removed`.
 */
declare enum EntityUpdateType {
  update = "update",
  remove = "remove",
}
/**
 * The `IEntityUpdate` interface represents an Entity update that should be applied over an existing Entity.
 */
interface IEntityUpdate {
  /**
   * The type of the update, which can be either `update` or `remove`.
   */
  type: EntityUpdateType;
  /**
   * The proxy of the Entity that needs to be updated.
   */
  entity: IEntityProxy;
  /**
   * Optional. The model of the Entity that needs to be updated.
   */
  model?: IEntityModel;
  /**
   * Optional. The snapshot of the Entity that needs to be updated.
   */
  snapshot?: IEntitySnapshot;
}
/**
 * The `IEntityUpdateQueue` interface is the main mechanism to queue and retrieve `EntityUpdate` instances.
 *
 * The interface can be implemented using a simple queue mechanism, or perhaps, a Priority Queue.
 */
interface IEntityUpdateQueue {
  /**
   * The number of `EntityUpdate` instances currently in the queue.
   */
  readonly size: number;
  /**
   * Adds an `EntityUpdate` instance to the end of the queue.
   * @param change - The `EntityUpdate` instance to be added.
   */
  enqueue(change: IEntityUpdate): void;
  /**
   * Removes and returns the `EntityUpdate` instance at the front of the queue.
   * @returns The `EntityUpdate` instance at the front of the queue.
   */
  dequeue(): IEntityUpdate;
  /**
   * Returns the `EntityUpdate` instance at the front of the queue without removing it.
   * @returns The `EntityUpdate` instance at the front of the queue.
   */
  peek(): IEntityUpdate;
  /**
   * Removes all `EntityUpdate` instances from the queue.
   */
  clear(): void;
}
//#endregion
//#region src/entities/entity-repository.d.ts
/**
 * The `IEntityRepository` is the central storage for keeping track of existing Entities.
 * It provides basic CRUD functionality.
 */
interface IEntityRepository {
  /**
   * Returns the number of entities in the repository.
   */
  readonly size: number;
  /**
   * Checks if the repository contains an entity represented by the given proxy.
   * @param proxy - The proxy of the entity to check.
   * @returns True if the repository contains the entity, false otherwise.
   */
  has(proxy: IEntityProxy): boolean;
  /**
   * Retrieves an entity from the repository by its proxy.
   * @template TEntity - The type of the entity to retrieve.
   * @param proxy - The proxy of the entity to retrieve.
   * @returns The retrieved entity.
   */
  get<TEntity extends IEntity>(proxy: IEntityProxy): TEntity;
  /**
   * Retrieves all entities of a specific type from the repository.
   * @template TEntity - The type of the entities to retrieve.
   * @param entityType - The type UID of the entities to retrieve.
   * @returns An array of the retrieved entities.
   */
  getAll<TEntity extends IEntity>(entityType: EntityTypeUid): TEntity[];
  /**
   * Iterator over all entities in the repository.
   * @returns An iterator of all entities in the repository.
   */
  listAll(): IterableIterator<IEntity>;
  /**
   * Adds or updates an entity in the repository.
   * @param entity - The entity to add or update.
   */
  set(entity: IEntity): void;
  /**
   * Deletes an entity from the repository by its proxy.
   * @param proxy - The proxy of the entity to delete.
   */
  delete(proxy: IEntityProxy): void;
  /**
   * Clears all entities of a specific type from the repository.
   * @param entityType - The type UID of the entities to clear.
   */
  clear(entityType: EntityTypeUid): void;
}
//#endregion
//#region src/entities/entity-scheduler.d.ts
/**
 * The `IEntityScheduler` is the main way of queuing `IEntityUpdate` instances on an Interval (based on time or a custom implementation).
 *
 * It usually reads the Entities from the `IEntityRepository`, and uses the `IEntityUpdateQueue` to enqueue Entity updates.
 */
interface IEntityScheduler {
  /**
   * Schedules an entity for updates at a specified interval.
   *
   * @param entityProxy - The entity to schedule for updates.
   * @param intervalMs - The interval at which to schedule updates, in milliseconds. If not provided, the default interval will be used.
   */
  schedule(entityProxy: IEntityProxy, intervalMs?: number): void;
  /**
   * Removes an entity from the scheduler.
   *
   * @param entityProxy - The entity to remove from the scheduler.
   */
  remove(entityProxy: IEntityProxy): void;
  /**
   * Checks if an entity is currently scheduled for updates.
   *
   * @param entityProxy - The entity to check.
   * @returns `true` if the entity is scheduled, `false` otherwise.
   */
  has(entityProxy: IEntityProxy): boolean;
}
//#endregion
export { EntityEventSubscriptionFilter, EntityEventUid, EntityUpdateType, IEntityEvent, IEntityEventsDispatcher, IEntityEventsManager, IEntityRepository, IEntityScheduler, IEntitySnapshot, IEntitySnapshotProvider, IEntityUpdate, IEntityUpdateQueue, IEventData };
//# sourceMappingURL=index-C3UGZqUG.d.ts.map