import { SlideError, VolumeAdjuster } from "@netless/ppt-player";
import { IPlugin } from "@netless/plugin-system";
import { AliTrackLogger } from "./AliTrackLogger";
import { preloadResource } from "./global";
export { ErrorType } from "@netless/ppt-player";
export declare type UrlInterrupter = (url: string) => Promise<string>;
export interface ILoaderDelegate {
    /**
     * Load JSON resources, need to return JSON text.
     * @param url Original resource address
     */
    loadJson(url: string): Promise<string>;
    /**
     * Load image resources, return Blob object.
     * @param url Original resource address
     */
    loadImage(url: string): Promise<Blob>;
    /**
     * Media file redirection, mp3 and mp4 resources will call this proxy function, and the redirected URL should be returned.
     * @param url Original resource address
     */
    redirectMedia(url: string): string;
}
export interface RtcAudio {
    /**
     * Start playing audio.
     */
    play(): void;
    /**
     * Pause audio playback, and the current playback time of the audio remains unchanged.
     */
    pause(): void;
    /**
     * When the audio object is no longer in use, it is called.
     */
    destroy(): void;
    /**
     * Set volume, parameter value range 0 ~ 1.
     */
    volume(value: number): void;
    /**
     * Get the current playing time of the audio, in seconds.
     */
    get currentTime(): number;
    /**
     * Set the current playback time of the audio, in seconds. Please note that whether the audio is playing or not, it needs to be ensured that the setting is successful.
     * If the audio is in a paused state, set this value to ensure that the next time playback resumes, it starts playing from this position.
     */
    set currentTime(time: number);
    /**
     * Return whether the audio is in a paused state.
     */
    get isPaused(): boolean;
    /**
     * Return audio duration.
     */
    get duration(): number;
    /**
     * When the audio is loaded, for example: when the audio meta data is loaded and the actual duration of the audio is known,
     * this event needs to be triggered. It is necessary to ensure that this event is triggered when
     * You can obtain the updated audio duration through the duration attribute.
     * @param event
     * @param listener
     */
    on(event: "load", listener: () => void): this;
    /**
     * Trigger when the audio is paused.
     * @param event
     * @param listener
     */
    on(event: "pause", listener: () => void): this;
    /**
     * Trigger when the audio is beginning.
     * @param event
     * @param listener
     */
    on(event: "play", listener: () => void): this;
    on(event: "resumeAllAudioInterruptByAudioSessionChanged", listener: () => void): this;
    /**
     * Remove all listeners for the specified event.
     */
    removeAllListeners(event: string): void;
}
export interface RtcAudioClazz {
    /**
     * Create an RTC player, with the URL as the audio address.
     * @param url
     */
    new (url: string): RtcAudio;
}
export declare const delay: (value: number) => Promise<unknown>;
export declare function waitUntil(fn: () => boolean, timeout: number): Promise<void>;
interface ILogger {
    info?(msg: string): void;
    error?(msg: string): void;
    warn?(msg: string): void;
}
export declare const SLIDE_EVENTS: {
    /** Synchronous event dispatch. */
    readonly syncDispatch: "syncDispatch";
    /** Synchronous event reception */
    readonly syncReceive: "syncReceive";
    /**
     * This event is only triggered in synchronous mode, indicating that synchronous messages are delayed and require full synchronization.
     */
    readonly syncEventLag: "syncEventLag";
    /** The current slide rendering starts triggering. */
    readonly renderStart: "renderStart";
    /** The current slide rendering is complete. */
    readonly renderEnd: "renderEnd";
    /** Current slide rendering error triggered. */
    readonly renderError: "renderError";
    /** Page number change triggers */
    readonly slideChange: "slideChange";
    /** Trigger at the beginning of the main sequence animation. */
    readonly mainSeqStepStart: "mainSeqStepStart";
    /** Triggered at the end of the main sequence animation. */
    readonly mainSeqStepEnd: "mainSeqStepEnd";
    /**
     * Trigger at the start of any animation.
     */
    readonly animateStart: "animateStart";
    /**
     * Trigger at the end of any animation.
     */
    readonly animateEnd: "animateEnd";
    /** slide State change trigger */
    readonly stateChange: "stateChange";
    /** ppt There is no next action trigger. **/
    readonly slideStepEnd: "slideEnd";
    /** ppt There is no previous action triggered. **/
    readonly slideStepStart: "slideStart";
    readonly useraddLink: "useraddLink";
};
export interface ISlideRenderOptions {
    /** Minimum expected rendering fps, default is 40 */
    minFPS?: number;
    /** Expected maximum rendering fps, default is 50 */
    maxFPS?: number;
    /** 渲染分辨倍率, 整数,  default is window.devicePixelRatio */
    resolution?: number;
    /** Whether to automatically adjust the resolution based on fps., default is false */
    autoResolution?: boolean;
    /** Automatically reduce rendering. fps */
    autoFPS?: boolean;
    /** Background color when playing page transition animation, accepts CSS color strings or hexadecimal color values ("#ffffff", 0xffffff) */
    transactionBgColor?: string | number;
    /**
     * Used to set the maximum display resolution. This value not only affects the canvas rendering resolution, but also affects the texture quality.
     * On low-end devices, reducing this value can greatly improve memory usage and image black screen phenomenon.
     * [0] 640 * 360
     * [1] 960 * 540;
     * [2] Normal 1280 * 720; --- default setting for mobile devices.
     * [3] HD 1920 * 1080;
     * [4] 3K 3200 × 1800, greater than 4 is calculated as 4; --- default setting for PC devices.
     * By default, PC devices are set to 3K, and mobile devices are set to 720P.
     */
    maxResolutionLevel?: number;
    /**
     * Whether to force the use of 2D rendering, forcing the use of 2D rendering will lose some 3D, filters, and effects.
     */
    forceCanvas?: boolean;
    /**
     * @deprecated The current version has fixed the screen flickering issue, so there is no need to enable this parameter.
     * Should NVIDIA graphics card detection be enabled, Windows 11 with NVIDIA graphics card may experience screen flickering when playing certain page transition animations.
     * Enabling this option will automatically detect whether it is an NVIDIA graphics card. If it is,
     * it will use different logic to play page transition animations without screen flickering, but the response time for page transitions will be slower by 200 to 1000 ms.
     */
    enableNvidiaDetect?: boolean;
    /**
     * 切页动画截图分辨率等级
     * [0] 640 * 360
     * [1] 960 * 540;
     * [2] Normal 1280 * 720; --- default setting for mobile devices.
     * [3] HD 1920 * 1080;
     * [4] 3K 3200 × 1800, greater than 4 is calculated as 4; --- default setting for PC devices.
     */
    transitionResolutionLevel?: number;
    antialias?: boolean;
}
export interface INavigatorDelegate {
    gotoPage?: (index: number) => void;
    openUrl?: (url: string) => void;
}
export interface CustomLink {
    pageIndex: number;
    shapeId: string;
    link: string;
}
export interface ISlideConfig {
    /** canvas mount dom */
    anchor: HTMLDivElement;
    /** can it interact */
    interactive: boolean;
    /** render options, Optional */
    renderOptions?: ISlideRenderOptions;
    /** Whether to display the control bar and stats */
    controller?: boolean;
    /** Whether to automatically adjust the resolution according to the window size */
    resize?: boolean;
    /** Get room time */
    timestamp?: () => number;
    /**
     * Operating mode
     *
     * "interactive" Interactive mode, everyone can operate ppt
     * "sync" Synchronization mode, only one person can operate ppt
     * "local" Local mode, no synchronization events will be triggered
     */
    mode: "interactive" | "sync" | "local" | "addLink";
    /**
     * Whether to enable global clicking, after turning on, as long as you click within the ppt viewport range,
     * and do not trigger interactive elements inside ppt, it will trigger the next action.
     * Default is false.
     */
    enableGlobalClick?: boolean;
    disableClickDebounce?: boolean;
    /**
     * The provided audio player class, used for rtc mixing
     */
    rtcAudio?: RtcAudioClazz;
    /**
     * Provide logger object for recording operation logs
     */
    logger?: ILogger;
    whiteTracker?: WhiteTracker;
    /**
     * Whether to enable local caching, after enabling, ppt remote resources will be cached in indexDB
     * Default is true
     */
    useLocalCache?: boolean;
    /**
     * Resource loading timeout, default 15 seconds
     */
    resourceTimeout?: number;
    /**
     * Remote resource proxy, for detailed use refer to README
     */
    loaderDelegate?: ILoaderDelegate;
    /**
     * PPT page navigation proxy, after adding this property,
     * the page number changes caused by actions within the ppt,
     * all go through the proxy logic.
     * PPT opens the webpage, needs to open through the openUrl method,
     * PPT page turning, needs to turn pages through the gotoPage method.
     */
    navigatorDelegate?: INavigatorDelegate;
    /**
     * Set a fixed height and width for ppt, after setting, ppt will not change automatically with the size of the parent element
     * If there is a need for scaling, you need to call the updateFixedFrameSize method
     * The units of width and height attributes are px
     */
    fixedFrameSize?: {
        width: number;
        height: number;
    };
    /**
     * Client id, in synchronization and interactive scenarios, it needs to be able to distinguish each different client.
     * For the end that receives the synchronization message, this needs to be used
     * ClientId distinguishes whether the message sent by oneself is received by oneself.
     * If in the synchronization and interactive scenarios,
     * not giving this value will cause the status to be out of sync in some cases,
     * the known scenarios are:
     * 1. A certain page of ppt has automatic animation, the next action performed during the animation,
     * on other clients may appear as the next page (i.e. page turning)
     */
    clientId?: string;
    urlInterrupter?: UrlInterrupter;
    /**
     * Whether to enable log tracking, after enabling,
     * local logs will be regularly and quantitatively uploaded to the sdk remote server
     * default is true
     */
    enableTracking?: boolean;
    enableWebAudio?: boolean;
    skipActionWhenFrozen?: boolean;
    enableAutoForward?: boolean;
    customLinks?: CustomLink[];
}
interface MediaState {
    type: "pause" | "play";
    time: number;
    frozenTime?: number;
    fullscreen?: boolean;
}
interface TimeNodeSeqState {
    step: number;
    state: "idle" | "running" | "end" | null;
}
interface ISlideState {
    taskId: string;
    url: string;
    currentSlideIndex: number;
    mainSeqStep: number;
    mainSeqState: "idle" | "running" | "end" | null;
    mediaState: {
        [key: string]: MediaState;
    };
    interactiveSeqState: {
        [key: string]: TimeNodeSeqState;
    };
}
export declare type SyncEvent = SyncInteractiveAnimEvent | SyncPrevStepEvent | SyncNextStepEvent | SyncRenderSlideEvent | SyncSetResourceEvent | SyncMediaPlayEvent | SyncMediaPauseEvent | SyncMediaSeekEvent | SyncMediaFullscreenEvent;
export interface BasicSyncEvent {
    slideIndex: number;
    uuid?: string;
    incrId?: number;
    clientId?: string;
}
export interface SyncMediaPlayEvent extends BasicSyncEvent {
    type: "mediaPlay";
    id: string;
    state: MediaState;
}
export interface SyncMediaPauseEvent extends BasicSyncEvent {
    type: "mediaPause";
    id: string;
    state: MediaState;
}
export interface SyncMediaSeekEvent extends BasicSyncEvent {
    type: "mediaSeek";
    id: string;
    time: number;
    state: MediaState;
}
export interface SyncMediaFullscreenEvent extends BasicSyncEvent {
    type: "mediaFullscreen";
    targetId: string;
    state: boolean;
}
export interface SyncInteractiveAnimEvent extends BasicSyncEvent {
    type: "interactiveAnim";
    action: string;
    seqId: string;
}
export interface SyncPrevStepEvent extends BasicSyncEvent {
    type: "prevStep";
    next: number;
}
export interface SyncNextStepEvent extends BasicSyncEvent {
    type: "nextStep";
    next: number;
}
export interface SyncRenderSlideEvent extends BasicSyncEvent {
    type: "renderSlide";
    index: number;
    isForward: boolean;
}
export interface SyncSetResourceEvent extends BasicSyncEvent {
    type: "setResource";
    taskId: string;
    url: string;
}
export interface SlideEventEmitter {
    removeAllListeners(): this;
    removeListener(event: keyof typeof SLIDE_EVENTS, fn?: any): this;
    emit(event: typeof SLIDE_EVENTS.renderStart, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.renderStart, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.renderEnd, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.renderEnd, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.slideChange, nextSlideIndex: number): boolean;
    on(event: typeof SLIDE_EVENTS.slideChange, listener: (nextSlideIndex: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncDispatch, args: SyncEvent): boolean;
    on(event: typeof SLIDE_EVENTS.syncDispatch, listener: (event: SyncEvent) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncReceive, args: SyncEvent): boolean;
    on(event: typeof SLIDE_EVENTS.syncReceive, listener: (event: SyncEvent) => void): this;
    emit(event: typeof SLIDE_EVENTS.renderError, args: {
        error: SlideError;
        index: number;
    }): boolean;
    on(event: typeof SLIDE_EVENTS.renderError, listener: (args: {
        error: SlideError;
        index: number;
    }) => void): this;
    emit(event: typeof SLIDE_EVENTS.animateStart): boolean;
    on(event: typeof SLIDE_EVENTS.animateStart, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.animateEnd): boolean;
    on(event: typeof SLIDE_EVENTS.animateEnd, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.mainSeqStepStart, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.mainSeqStepStart, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.mainSeqStepEnd, index: number): boolean;
    on(event: typeof SLIDE_EVENTS.mainSeqStepEnd, listener: (index: number) => void): this;
    emit(event: typeof SLIDE_EVENTS.stateChange, state: ISlideState): boolean;
    on(event: typeof SLIDE_EVENTS.stateChange, listener: (state: ISlideState) => void): this;
    emit(event: typeof SLIDE_EVENTS.syncEventLag): boolean;
    on(event: typeof SLIDE_EVENTS.syncEventLag, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.slideStepEnd): boolean;
    on(event: typeof SLIDE_EVENTS.slideStepEnd, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.slideStepStart): boolean;
    on(event: typeof SLIDE_EVENTS.slideStepStart, listener: () => void): this;
    emit(event: typeof SLIDE_EVENTS.useraddLink, taskId: string, pageIndex: number, shapeId: string): void;
    on(event: typeof SLIDE_EVENTS.useraddLink, listener: (taskId: string, pageIndex: number, shapeId: string) => void): this;
}
export declare type TrackerEvent = {
    name: string;
    result: string;
    reason: string;
    payload: {
        [key: string]: any;
    };
};
export declare type TrackerMeta = {
    slideVersion: string;
};
interface WhiteTracker {
    commit(event: TrackerEvent, meta: TrackerMeta): void;
}
declare const Slide_base: new () => SlideEventEmitter;
export declare class Slide extends Slide_base {
    static preloadResource: typeof preloadResource;
    static instances: Slide[];
    static _tempFrozenIds: string[];
    static _tempLog: string;
    static _tempLogIndex: number;
    static flushLog(force?: boolean): Promise<void>;
    static remoteLogAddress: string | null;
    static stopRemoteLog(): void;
    static startRemoteLog(address: string): Promise<void>;
    static appendLogString(logStr: string): void;
    static usePlugin: (plugin: IPlugin) => void;
    /**
     * 设置全局音量, 对所有 Slide 实例都生效
     */
    static volumeAdjuster: VolumeAdjuster;
    static __stageCountLimit: number;
    static setStageCountLimit(limit: number): void;
    private iosResetCache;
    private iosNewPlayer?;
    private version?;
    private __slideState;
    private userInputTime;
    private isSyncingSlideState;
    private frozenTaskManager;
    private randomId;
    private resize;
    private isAnimating;
    private renderingTaskManager;
    private isLoading;
    private interactive;
    private anchor;
    private tracker;
    private player?;
    private renderingIndex;
    private frameWidth;
    private frameHeight;
    private frame;
    private canvasContainer;
    private medianController;
    private frameResizeObserver;
    private timestamp;
    private mode;
    private enableGlobalClick;
    private lastEmitedState;
    private syncQueue;
    private playerController;
    private lock;
    private isInitResized;
    private cacheImage;
    private config;
    private isTouchStart;
    private touchStartId;
    private taskId;
    private volumeAdjuster;
    private designWidth;
    private designHeight;
    private _slideCount;
    private logger;
    private _dispatchIncrId;
    private _receiveIncrId;
    private resizeView;
    private handleViewClick;
    static trackLogger: AliTrackLogger;
    private slideNots;
    private resourceList;
    private get dispatchIncrId();
    constructor(initConfig: ISlideConfig);
    private _updateVolumeByStaticAdjuster;
    private recoverHandler;
    private reportError;
    initSlideConfig(config: ISlideConfig): ISlideConfig;
    static handleFrozenAllSlide: () => void;
    static handleReleaseAllSlide: () => void;
    static handleLogReport: (sessionId: string) => Promise<void>;
    static handleLogDownload: () => Promise<void>;
    private urlInterrupter;
    private initPlayer;
    private userInputHandle;
    private _handleViewClick;
    private handleViewTouchStart;
    private handleViewTouchEnd;
    private createController;
    private handleSlideRef;
    private updateStageCountLimit;
    private setMedianControllerAttribute;
    private frameResizeHandler;
    /**
     *  Update ppt fixed height and width, this method only takes effect when the fixedFrameSize configuration item is set.
     * @param width Width value that needs to be updated, unit px.
     * @param height Height value that needs to be updated, unit px.
     */
    updateFixedFrameSize(width: number, height: number, callback?: () => void): void;
    private _resizeView;
    private receiveSyncHandler;
    /**
     * Set the state of the entire slide, the slide will update the screen with the incoming state.
     * It is called when synchronizing the whole.
     * @param state ISlideState
     */
    setSlideState(state: Partial<ISlideState>): Promise<void>;
    private initInteractiveSeq;
    private initMedia;
    /**
     * 返回 slide 总页数
     */
    get slideCount(): number;
    /**
     * Get the width and height of the slide in pixels,
     * return the array in the form [width, height].
     * Can be called before rendering the slide.
     */
    getSizeAsync(): Promise<[number, number]>;
    /**
     * Get the total number of slides, you can call it before renderSlide.
     */
    getSlideCountAsync(): Promise<number>;
    /**
     * The state of the entire slide, pass the obtained value to another client,
     * and call setSlideState to achieve overall synchronization. Read-only property.
     * @readonly
     */
    get slideState(): ISlideState;
    /**
     * Main sequence animation steps, read-only property.
     * @readonly
     */
    get mainSeqLength(): number;
    /**
     * Main sequence animation, current step, read-only property.
     * @readonly
     */
    get mainSeqStep(): number;
    /**
     * Main sequence animation, current state, read-only property
     * "idle": Animation has not started
     * "running": Animation is in progress
     * "end": Animation has ended
     * null: The current slide does not have a main sequence animation
     * @readonly
     */
    get mainSeqState(): "idle" | "running" | "end" | null;
    /**
     * Real-time rendering properties, read-only properties.
     * @readonly
     */
    get renderOptions(): ISlideRenderOptions | null;
    /**
     * drawCall count, which means the number of times gpu drawElements is called per frame, read-only property.
     * @readonly
     */
    get drawCall(): number;
    /**
     * Rendering fps, read-only property.
     * @readonly
     */
    get renderFps(): number;
    /**
     * js runtime fps, read-only.
     * @readonly
     */
    get runtimeFps(): number;
    /**
     * Render the canvas element of the Slide.
     * @readonly
     */
    get view(): HTMLCanvasElement | null;
    /**
     * Slide width. This width is the design width determined by ppt. Read-only property.
     * @readonly
     */
    get width(): number;
    /**
     * Slide height. This height is the design height determined by ppt. Read-only property.
     * @readonly
     */
    get height(): number;
    /**
     * 更新渲染属性
     * @param renderOptions
     */
    updateRenderOption(renderOptions: ISlideRenderOptions): void;
    /**
     * Set resources after converting ppt
     * @param taskId task id
     * @param url Resource URL prefix
     */
    setResource(taskId: string, url: string): void;
    private flushDebounce;
    setResourceList(taskId: string, urls: string[]): void;
    private _renderSlide;
    private handlePrevSlide;
    private handleNextSlide;
    private handleGotoSlide;
    /**
     * Render the ppt page corresponding to the index parameter.
     * @param index Page number to display, starting from 1.
     */
    renderSlide(index: number, isForward?: boolean): void;
    private needCreateNewPlayer;
    private poseRenderSlide;
    /**
     * Render the page specified by the index directly,
     * regardless of whether the current mode is sync or interactive.
     * Calling this method will not trigger the syncDispatch event.
     * @param index Page number to render
     * @param isForward Whether to flip forward or backward, affecting the page transition animation.
     */
    doRenderSlide(index: number, isForward?: boolean): Promise<void>;
    getSnapshot(): string | null;
    /**
     * 执行下一个主序列动画
     */
    nextStep(): void;
    private doNextStep;
    /**
     * Execute the previous main sequence animation.
     */
    prevStep(): void;
    private doPrevStep;
    private isSlideStateReady;
    private emitStateChange;
    private emitSyncDispatch;
    /**
     * Reset main sequence animation.
     * @param index Number of steps to reset to.
     * @param status The state to be reset to, "start" resets to the beginning of the animation, "end" resets to the end of the animation.
     */
    setMainSeqStep(index: number, status: "start" | "end"): void;
    /**
     * Set whether interaction is allowed.
     * @param val boolean
     */
    setInteractive(val: boolean): void;
    /**
     * Pause playback, asynchronous operation.
     */
    pause(): void;
    /**
     * Resume playback state, asynchronous operation.
     */
    resume(): void;
    private _doFrozen;
    /**
     * Enter freeze state, cache the ppt screen as an image, and release the WebGL context.
     */
    frozen(callback?: () => void): void;
    private _doRelease;
    /**
     * Recover from frozen state.
     */
    release(callback?: () => void): void;
    private _doDestroy;
    private waitLoadEnd;
    preload(index: number): Promise<void>;
    preloadResource(index: number): Promise<void>;
    /**
     * Destruction method.
     */
    destroy(): void;
    /**
     * Destroy the local cache of the current Slide instance, need to be called before destroy.
     */
    clearSlideCache(): void;
    /**
     * Return whether there is a next action in the ppt.
     */
    hasNextStep(): boolean;
    /**
     * Return whether there is a previous action in the ppt.
     */
    hasPrevStep(): boolean;
    /**
     * Capture a screenshot of the current state.
     * @return 图片 dataUrl, if failed return null
     */
    snapshot(): Promise<string | null>;
    /**
     * Capture a screenshot of the final step of the animation.
     * @param index The index of the slide to be captured.
     * @return 图片 dataUrl, if failed return null
     */
    snapshotWithTimingEnd(index: number): Promise<string | null>;
    /**
     * Set the global volume of this Slide instance, asynchronous operation,
     * only modify the local volume, will not trigger synchronous events.
     * @param v Value range 0 ~ 1
     */
    updateGlobalVolume(v: number): void;
    /**
     * Get the global volume of this Slide instance..
     */
    getGlobalVolume(): number;
    /**
     * Destroy all local cache of historical records.
     */
    static clearLocalCache(): void;
    /**
     * @deprecated This API is no longer functional. Please use `slideInstance.clearSlideCache` and `Slide.clearLocalCache` instead.
     */
    static disposeLocalCache(): void;
    getNoteForCurrentSlide(slideIndex: number): Promise<any>;
}
