import { Widget } from '@lumino/widgets';
import { Message } from '@lumino/messaging';
import { Emitter, Event } from '../common/event';
import { MaybePromise } from '../common/types';
import { AbstractDialog } from './dialogs';
import { Disposable, DisposableCollection, URI } from '../common';
import { BinaryBuffer } from '../common/buffer';
export type AutoSaveMode = 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange';
export interface Saveable {
    readonly dirty: boolean;
    /** If false, the saveable will not participate in autosaving. */
    readonly autosaveable?: boolean;
    /**
     * This event is fired when the content of the `dirty` variable changes.
     */
    readonly onDirtyChanged: Event<void>;
    /**
     * This event is fired when the content of the saveable changes.
     * While `onDirtyChanged` is fired to notify the UI that the widget is dirty,
     * `onContentChanged` is used for the auto save throttling.
     */
    readonly onContentChanged: Event<void>;
    /**
     * Saves dirty changes.
     */
    save(options?: SaveOptions): MaybePromise<void>;
    /**
     * Performs the save operation with a new file name.
     */
    saveAs?(options: SaveAsOptions): MaybePromise<void>;
    /**
     * Reverts dirty changes.
     */
    revert?(options?: Saveable.RevertOptions): Promise<void>;
    /**
     * Creates a snapshot of the dirty state. See also {@link Saveable.Snapshot}.
     */
    createSnapshot?(): Saveable.Snapshot;
    /**
     * Applies the given snapshot to the dirty state.
     */
    applySnapshot?(snapshot: object): void;
    /**
     * Serializes the full state of the saveable item to a binary buffer.
     */
    serialize?(): Promise<BinaryBuffer>;
    /**
     * Optionally return file filters for the "Save As" dialog.
     * The keys of the returned object are the names of the filters and the values are arrays of file extensions.
     * For example: `{ 'Text Files': ['txt', 'text'], 'All Files': ['*'] }`
     * If no filters are provided, a default filter of `All Files (*.*)` will be used.
     */
    filters?(): {
        [name: string]: string[];
    };
}
export interface SaveableSource {
    readonly saveable: Saveable;
}
export declare class DelegatingSaveable implements Saveable {
    dirty: boolean;
    protected readonly onDirtyChangedEmitter: Emitter<void>;
    protected readonly onContentChangedEmitter: Emitter<void>;
    get onDirtyChanged(): Event<void>;
    get onContentChanged(): Event<void>;
    save(options?: SaveOptions): Promise<void>;
    revert?(options?: Saveable.RevertOptions): Promise<void>;
    createSnapshot?(): Saveable.Snapshot;
    applySnapshot?(snapshot: object): void;
    serialize?(): Promise<BinaryBuffer>;
    saveAs?(options: SaveAsOptions): MaybePromise<void>;
    protected _delegate?: Saveable;
    protected toDispose: DisposableCollection;
    set delegate(delegate: Saveable);
}
export declare class CompositeSaveable implements Saveable {
    protected isDirty: boolean;
    protected readonly onDirtyChangedEmitter: Emitter<void>;
    protected readonly onContentChangedEmitter: Emitter<void>;
    protected readonly toDispose: DisposableCollection;
    protected readonly saveablesMap: Map<Saveable, Disposable>;
    get dirty(): boolean;
    get onDirtyChanged(): Event<void>;
    get onContentChanged(): Event<void>;
    save(options?: SaveOptions): Promise<void>;
    revert(options?: Saveable.RevertOptions): Promise<void>;
    get saveables(): readonly Saveable[];
    add(saveable: Saveable): void;
    remove(saveable: Saveable): boolean;
    dispose(): void;
}
export declare namespace Saveable {
    interface RevertOptions {
        /**
         * If soft then only dirty flag should be updated, otherwise
         * the underlying data should be reverted as well.
         */
        soft?: boolean;
    }
    /**
     * A snapshot of a saveable item.
     * Applying a snapshot of a saveable on another (of the same type) using the `applySnapshot` should yield the state of the original saveable.
     */
    type Snapshot = {
        value: string;
    } | {
        read(): string | null;
    };
    namespace Snapshot {
        function read(snapshot: Snapshot): string | undefined;
    }
    function isSource(arg: unknown): arg is SaveableSource;
    function is(arg: unknown): arg is Saveable;
    function get(arg: unknown): Saveable | undefined;
    function getDirty(arg: unknown): Saveable | undefined;
    function isDirty(arg: unknown): boolean;
    function save(arg: unknown, options?: SaveOptions): Promise<void>;
    function confirmSaveBeforeClose(toClose: Iterable<Widget>, others: Widget[]): Promise<boolean | undefined>;
    function closingWidgetWouldLoseSaveable(widget: Widget, others: Widget[]): boolean;
}
export interface SaveableWidget extends Widget {
    /**
     * @param doRevert whether the saveable should be reverted before being saved. Defaults to `true`.
     */
    closeWithoutSaving(doRevert?: boolean): Promise<void>;
    closeWithSaving(options?: SaveableWidget.CloseOptions): Promise<void>;
}
export declare const close: unique symbol;
/**
 * An interface describing saveable widgets that are created by the `Saveable.apply` function.
 * The original `close` function is reassigned to a locally-defined `Symbol`
 */
export interface PostCreationSaveableWidget extends SaveableWidget {
    /**
     * The original `close` function of the widget
     */
    [close](): void;
}
export declare namespace SaveableWidget {
    function is(widget: Widget | undefined): widget is SaveableWidget;
    function getDirty<T extends Widget>(widgets: Iterable<T>): IterableIterator<SaveableWidget & T>;
    function get<T extends Widget>(widgets: Iterable<T>, filter?: (widget: T) => boolean): IterableIterator<SaveableWidget & T>;
    interface CloseOptions {
        shouldSave?(): MaybePromise<boolean | undefined>;
    }
}
/**
 * Possible formatting types when saving.
 */
export declare const enum FormatType {
    /**
     * Formatting should occur (default).
     */
    ON = 1,
    /**
     * Formatting should not occur.
     */
    OFF = 2,
    /**
     * Formatting should only occur if the resource is dirty.
     */
    DIRTY = 3
}
export declare enum SaveReason {
    Manual = 1,
    AfterDelay = 2,
    FocusChange = 3
}
export declare namespace SaveReason {
    function isManual(reason?: number): reason is typeof SaveReason.Manual;
}
export interface SaveOptions {
    /**
     * Formatting type to apply when saving.
     */
    readonly formatType?: FormatType;
    /**
     * The reason for saving the resource.
     */
    readonly saveReason?: SaveReason;
}
export interface SaveAsOptions extends SaveOptions {
    readonly target: URI;
}
export declare function setDirty(widget: Widget, dirty: boolean): void;
export declare class ShouldSaveDialog extends AbstractDialog<boolean> {
    protected shouldSave: boolean;
    protected readonly dontSaveButton: HTMLButtonElement;
    constructor(widget: Widget);
    protected appendDontSaveButton(): HTMLButtonElement;
    protected onAfterAttach(msg: Message): void;
    get value(): boolean;
    open(disposeOnResolve?: boolean): Promise<boolean | undefined>;
}
//# sourceMappingURL=saveable.d.ts.map