import { TypedEventEmitter, EventType, MatrixClient, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { NamespacedValue } from "matrix-js-sdk/src/NamespacedValue";
import { MatrixRTCSession } from "matrix-js-sdk/src/matrixrtc";
import type { ClientWidgetApi } from "matrix-widget-api";
import type { IApp } from "../stores/WidgetStore";
import { JitsiCallMemberContent } from "../call-types";
export declare enum ConnectionState {
    Lobby = "lobby",
    WidgetLoading = "widget_loading",
    Disconnected = "disconnected",
    Connecting = "connecting",
    Connected = "connected",
    Disconnecting = "disconnecting"
}
export declare const isConnected: (state: ConnectionState) => boolean;
export declare enum Layout {
    Tile = "tile",
    Spotlight = "spotlight"
}
export declare enum CallEvent {
    ConnectionState = "connection_state",
    Participants = "participants",
    Layout = "layout",
    Destroy = "destroy"
}
interface CallEventHandlerMap {
    [CallEvent.ConnectionState]: (state: ConnectionState, prevState: ConnectionState) => void;
    [CallEvent.Participants]: (participants: Map<RoomMember, Set<string>>, prevParticipants: Map<RoomMember, Set<string>>) => void;
    [CallEvent.Layout]: (layout: Layout) => void;
    [CallEvent.Destroy]: () => void;
}
/**
 * A group call accessed through a widget.
 */
export declare abstract class Call extends TypedEventEmitter<CallEvent, CallEventHandlerMap> {
    /**
     * The widget used to access this call.
     */
    readonly widget: IApp;
    protected readonly client: MatrixClient;
    protected readonly widgetUid: string;
    protected readonly room: Room;
    /**
     * The time after which device member state should be considered expired.
     */
    abstract readonly STUCK_DEVICE_TIMEOUT_MS: number;
    private _messaging;
    /**
     * The widget's messaging, or null if disconnected.
     */
    protected get messaging(): ClientWidgetApi | null;
    private set messaging(value);
    get roomId(): string;
    private _connectionState;
    get connectionState(): ConnectionState;
    protected set connectionState(value: ConnectionState);
    get connected(): boolean;
    private _participants;
    /**
     * The participants in the call, as a map from members to device IDs.
     */
    get participants(): Map<RoomMember, Set<string>>;
    protected set participants(value: Map<RoomMember, Set<string>>);
    protected constructor(
    /**
     * The widget used to access this call.
     */
    widget: IApp, client: MatrixClient);
    /**
     * Gets the call associated with the given room, if any.
     * @param {Room} room The room.
     * @returns {Call | null} The call.
     */
    static get(room: Room): Call | null;
    /**
     * Performs a routine check of the call's associated room state, cleaning up
     * any data left over from an unclean disconnection.
     */
    abstract clean(): Promise<void>;
    /**
     * Contacts the widget to connect to the call or prompt the user to connect to the call.
     * @param {MediaDeviceInfo | null} audioInput The audio input to use, or
     *   null to start muted.
     * @param {MediaDeviceInfo | null} audioInput The video input to use, or
     *   null to start muted.
     */
    protected abstract performConnection(audioInput: MediaDeviceInfo | null, videoInput: MediaDeviceInfo | null): Promise<void>;
    /**
     * Contacts the widget to disconnect from the call.
     */
    protected abstract performDisconnection(): Promise<void>;
    /**
     * Starts the communication between the widget and the call.
     * The call then waits for the necessary requirements to actually perform the connection
     * or connects right away depending on the call type. (Jitsi, Legacy, ElementCall...)
     * It uses the media devices set in MediaDeviceHandler.
     * The widget associated with the call must be active
     * for this to succeed.
     * Only call this if the call state is: ConnectionState.Disconnected.
     */
    start(): Promise<void>;
    /**
     * Disconnects the user from the call.
     */
    disconnect(): Promise<void>;
    /**
     * Manually marks the call as disconnected and cleans up.
     */
    setDisconnected(): void;
    /**
     * Stops all internal timers and tasks to prepare for garbage collection.
     */
    destroy(): void;
    private onMyMembership;
    private onStopMessaging;
    private beforeUnload;
}
export type { JitsiCallMemberContent };
/**
 * A group call using Jitsi as a backend.
 */
export declare class JitsiCall extends Call {
    static readonly MEMBER_EVENT_TYPE = "io.element.video.member";
    readonly STUCK_DEVICE_TIMEOUT_MS: number;
    private resendDevicesTimer;
    private participantsExpirationTimer;
    private constructor();
    static get(room: Room): JitsiCall | null;
    static create(room: Room): Promise<void>;
    private updateParticipants;
    /**
     * Updates our member state with the devices returned by the given function.
     * @param fn A function from the current devices to the new devices. If it
     *     returns null, the update is skipped.
     */
    private updateDevices;
    clean(): Promise<void>;
    private addOurDevice;
    private removeOurDevice;
    protected performConnection(audioInput: MediaDeviceInfo | null, videoInput: MediaDeviceInfo | null): Promise<void>;
    protected performDisconnection(): Promise<void>;
    setDisconnected(): void;
    destroy(): void;
    private onRoomState;
    private onConnectionState;
    private onDock;
    private onUndock;
    private onHangup;
}
/**
 * A group call using MSC3401 and Element Call as a backend.
 * (somewhat cheekily named)
 */
export declare class ElementCall extends Call {
    session: MatrixRTCSession;
    static readonly CALL_EVENT_TYPE: NamespacedValue<string, EventType.GroupCallPrefix>;
    static readonly MEMBER_EVENT_TYPE: NamespacedValue<string, EventType.GroupCallMemberPrefix>;
    readonly STUCK_DEVICE_TIMEOUT_MS: number;
    private settingsStoreCallEncryptionWatcher;
    private terminationTimer;
    private _layout;
    get layout(): Layout;
    protected set layout(value: Layout);
    private static generateWidgetUrl;
    private static createOrGetCallWidget;
    private static getWidgetData;
    private onCallEncryptionSettingsChange;
    private constructor();
    static get(room: Room): ElementCall | null;
    static create(room: Room, skipLobby?: boolean): Promise<void>;
    protected sendCallNotify(): Promise<void>;
    protected performConnection(audioInput: MediaDeviceInfo | null, videoInput: MediaDeviceInfo | null): Promise<void>;
    protected performDisconnection(): Promise<void>;
    setDisconnected(): void;
    destroy(): void;
    private onRTCSessionEnded;
    /**
     * Sets the call's layout.
     * @param layout The layout to switch to.
     */
    setLayout(layout: Layout): Promise<void>;
    private onMembershipChanged;
    private updateParticipants;
    private onHangup;
    private onTileLayout;
    private onSpotlightLayout;
    clean(): Promise<void>;
}
