import { UuidGenerator } from "./helpers";
import { EventBus } from "./helpers/event_bus";
import { StateUpdateMessage } from "./types/collaborative/transport_service";
import { CommandDispatcher } from "./types/commands";
import { Getters } from "./types/getters";
import { Mode, ModelConfig } from "./types/model";
import { GridRenderingContext, LayerName } from "./types/rendering";
import { SelectionStreamProcessor } from "./types/selection_stream_processor";
import { WorkbookData } from "./types/workbook_data";
import { XLSXExport } from "./types/xlsx";
/**
 * Model
 *
 * The Model class is the owner of the state of the Spreadsheet. However, it
 * has more a coordination role: it defers the actual state manipulation work to
 * plugins.
 *
 * At creation, the Model instantiates all necessary plugins. They each have
 * a private state (for example, the Selection plugin has the current selection).
 *
 * State changes are then performed through commands.  Commands are dispatched
 * to the model, which will then relay them to each plugins (and the history
 * handler). Then, the model will trigger an 'update' event to notify whoever
 * is concerned that the command was applied (if it was not canceled).
 *
 * Also, the model has an unconventional responsibility: it actually renders the
 * visible viewport on a canvas. This is because each plugins actually manage a
 * specific concern about the content of the spreadsheet, and it is more natural
 * if they are able to read data from their internal state to represent it on the
 * screen.
 *
 * Note that the Model can be used in a standalone way to manipulate
 * programmatically a spreadsheet.
 */
export declare class Model extends EventBus<any> implements CommandDispatcher {
    private corePlugins;
    private statefulUIPlugins;
    private range;
    private session;
    /**
     * In a collaborative context, some commands can be replayed, we have to ensure
     * that these commands are not replayed on the UI plugins.
     */
    private isReplayingCommand;
    /**
     * A plugin can draw some contents on the canvas. But even better: it can do
     * so multiple times.  The order of the render calls will determine a list of
     * "layers" (i.e., earlier calls will be obviously drawn below later calls).
     * This list simply keeps the renderers+layer information so the drawing code
     * can just iterate on it
     */
    private renderers;
    /**
     * Internal status of the model. Important for command handling coordination
     */
    private status;
    /**
     * The config object contains some configuration flag and callbacks
     */
    readonly config: ModelConfig;
    private corePluginConfig;
    private coreViewPluginConfig;
    private uiPluginConfig;
    private state;
    readonly selection: SelectionStreamProcessor;
    /**
     * Getters are the main way the rest of the UI read data from the model. Also,
     * it is shared between all plugins, so they can also communicate with each
     * other.
     */
    getters: Getters;
    /**
     * Getters that are accessible from the core plugins. It's a subset of `getters`,
     * without the UI getters
     */
    private coreGetters;
    uuidGenerator: UuidGenerator;
    private readonly handlers;
    private readonly uiHandlers;
    private readonly coreHandlers;
    constructor(data?: any, config?: Partial<ModelConfig>, stateUpdateMessages?: StateUpdateMessage[], uuidGenerator?: UuidGenerator, verboseImport?: boolean);
    joinSession(): void;
    leaveSession(): Promise<void>;
    private setupUiPlugin;
    private setupCoreViewPlugin;
    /**
     * Initialize and properly configure a plugin.
     *
     * This method is private for now, but if the need arise, there is no deep
     * reason why the model could not add dynamically a plugin while it is running.
     */
    private setupCorePlugin;
    private onRemoteRevisionReceived;
    private setupSession;
    private setupSessionEvents;
    private setupConfig;
    private setupExternalConfig;
    private setupCorePluginConfig;
    private setupCoreViewPluginConfig;
    private setupUiPluginConfig;
    /**
     * Check if the given command is allowed by all the plugins and the history.
     */
    private checkDispatchAllowed;
    private processCommandResults;
    private checkDispatchAllowedRemoteCommand;
    private checkDispatchAllowedCoreCommand;
    private checkDispatchAllowedLocalCommand;
    private finalize;
    /**
     * Check if a command can be dispatched, and returns a DispatchResult object with the possible
     * reasons the dispatch failed.
     */
    canDispatch: CommandDispatcher["dispatch"];
    /**
     * The dispatch method is the only entry point to manipulate data in the model.
     * This is through this method that commands are dispatched most of the time
     * recursively until no plugin want to react anymore.
     *
     * CoreCommands dispatched from this function are saved in the history.
     *
     * Small technical detail: it is defined as an arrow function.  There are two
     * reasons for this:
     * 1. this means that the dispatch method can be "detached" from the model,
     *    which is done when it is put in the environment (see the Spreadsheet
     *    component)
     * 2. This allows us to define its type by using the interface CommandDispatcher
     */
    dispatch: CommandDispatcher["dispatch"];
    /**
     * Dispatch a command from a Core Plugin (or the History).
     * A command dispatched from this function is not added to the history.
     */
    private dispatchFromCorePlugin;
    /**
     * Dispatch the given command to the given handlers.
     * It will call `beforeHandle` and `handle`
     */
    private dispatchToHandlers;
    /**
     * When the Grid component is ready (= mounted), it has a reference to its
     * canvas and need to draw the grid on it.  This is then done by calling this
     * method, which will dispatch the call to all registered plugins.
     *
     * Note that nothing prevent multiple grid components from calling this method
     * each, or one grid component calling it multiple times with a different
     * context. This is probably the way we should do if we want to be able to
     * freeze a part of the grid (so, we would need to render different zones)
     */
    drawLayer(context: GridRenderingContext, layer: LayerName): void;
    /**
     * As the name of this method strongly implies, it is useful when we need to
     * export data out of the model.
     */
    exportData(): WorkbookData;
    _exportData(shouldSquish: boolean): WorkbookData;
    updateMode(mode: Mode): void;
    /**
     * Exports the current model data into a list of serialized XML files
     * to be zipped together as an *.xlsx file.
     *
     * We need to trigger a cell revaluation  on every sheet and ensure that even
     * async functions are evaluated.
     * This prove to be necessary if the client did not trigger that evaluation in the first place
     * (e.g. open a document with several sheet and click on download before visiting each sheet)
     */
    exportXLSX(): Promise<XLSXExport>;
}
