import { Channels } from "@nteract/messaging";
import { CellType, CellId } from "@nteract/commutable";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
import * as React from "react";
import { ContentRef } from "@nteract/core";
import { IEditor } from "./layoutSchedule";
import * as intersectionObserver from "./intersectionObserver";
export declare type IModelContentChangedEvent = monaco.editor.IModelContentChangedEvent;
/**
 * Settings for configuring keyboard shortcuts with Monaco
 */
export interface IMonacoShortCutProps {
    cellType: CellType;
    cellFocusDirection: string | undefined;
    setCellFocusDirection: (direction?: string) => void;
    focusCell: (payload: {
        id: CellId;
        contentRef: ContentRef;
    }) => void;
    focusAboveCellCommandMode: () => void;
    focusBelowCellCommandMode: () => void;
    insertCellBelow: (contentRef: ContentRef, cellType: CellType) => void;
    executeCell: () => void;
    focusEditor: () => void;
    focusNextCellEditor: (setPosition?: boolean) => void;
    focusPreviousCellEditor: () => void;
    unfocusEditor: () => void;
}
/**
 * Common props passed to the editor component
 */
export interface IMonacoComponentProps {
    id: string;
    contentRef: ContentRef;
    theme: string;
    readOnly?: boolean;
    channels?: Channels | undefined;
    value: string;
    editorType?: string;
    editorFocused?: boolean;
    onChange?: (value: string, event?: any) => void;
    onFocusChange?: (focus: boolean) => void;
}
/**
 * Props passed for configuring Monaco Editor
 */
export interface IMonacoConfiguration {
    /**
     * modelUri acts an identifier to query the editor model
     * without being tied to the UI
     * Calling the getModel(modelUri) API
     */
    modelUri?: monaco.Uri;
    enableCompletion?: boolean;
    shouldRegisterDefaultCompletion?: boolean;
    onCursorPositionChange?: (selection: monaco.ISelection | null) => void;
    onRegisterDocumentFormattingEditProvider?: (languageId: string) => void;
    enableFormatting?: boolean;
    onRegisterCompletionProvider?: (languageId: string) => void;
    language: string;
    lineNumbers?: boolean;
    /** For better perf in resizing, when this is true, defer and batch the layout changes to avoid each editor layouting change cause individual browser refresh */
    batchLayoutChanges?: boolean;
    /**
     * whether we call editor.layout() when the container has been resized even if the editor is not focused
     * this way we don't need special CSS styles overriding monaco's built-in styles to make the editor resize
     * This is better used together with batchLayoutChanges set to true so all editors layouts changes can be batched for better perf
     */
    shouldUpdateLayoutWhenNotFocused?: boolean;
    /**
     * whether we should call editor.layout() when the container is not in the viewport
     * default is false
     */
    skipLayoutWhenNotInViewport?: boolean;
    /**
     * whether we should call editor.layout() when the container or its parent is hidden by "display:none" or the height is set to 0
     * default is false
     */
    skipLayoutWhenHidden?: boolean;
    /** automatically adjust size to fit content, default is true */
    autoFitContentHeight?: boolean;
    /** set a max content height in number of pixels, this only works when autoFitContentHeight is true*/
    maxContentHeight?: number;
    /**
     * Set the initial dimensions of the editor layout and the container
     */
    initialDimension?: monaco.editor.IDimension;
    /** set height of editor to fit the specified number of lines in display */
    numberOfLines?: number;
    indentSize?: number;
    tabSize?: number;
    options?: monaco.editor.IEditorOptions;
    shortcutsOptions?: IMonacoShortCutProps;
    shortcutsHandler?: (editor: monaco.editor.IStandaloneCodeEditor, settings?: IMonacoShortCutProps) => void;
    cursorPositionHandler?: (editor: monaco.editor.IStandaloneCodeEditor, settings?: IMonacoProps) => void;
    commandHandler?: (editor: monaco.editor.IStandaloneCodeEditor) => void;
    onDidCreateEditor?: (editor: monaco.editor.IStandaloneCodeEditor) => void;
}
/**
 * Initial props for Monaco Editor received from agnostic component
 */
export declare type IMonacoProps = IMonacoComponentProps & IMonacoConfiguration;
/**
 * Creates a MonacoEditor instance
 */
export default class MonacoEditor extends React.Component<IMonacoProps> implements IEditor, intersectionObserver.IIntersectable {
    editor?: monaco.editor.IStandaloneCodeEditor;
    editorContainerRef: React.RefObject<HTMLDivElement>;
    private cursorPositionListener?;
    private mouseMoveListener?;
    private intersectObservation?;
    private isInViewport;
    private deferredLayoutRequest;
    private deferredLayoutDimension?;
    constructor(props: IMonacoProps);
    onDidChangeModelContent(e: monaco.editor.IModelContentChangedEvent): void;
    readEditorDomSize(): monaco.editor.IDimension | undefined;
    getLayoutDimension(): monaco.editor.IDimension | undefined;
    isContainerHidden(): boolean;
    /**
     * write the layout to the DOM
     */
    layout(layout: monaco.editor.IDimension): void;
    /**
     * Implementation for IEditor from layoutSchedule, could cause a DOM read operation
     */
    shouldLayout(): boolean;
    requestLayout(dimension?: monaco.editor.IDimension): void;
    onIntersecting(isIntersecting: boolean): void;
    updateIntersectRegistration(): void;
    componentDidMount(): void;
    /**
     * Tells editor to check the surrounding container size and resize itself appropriately
     */
    onResize(): void;
    componentDidUpdate(prevProps: IMonacoProps): void;
    componentWillUnmount(): void;
    render(): JSX.Element;
    /**
     * Register default kernel-based completion provider.
     * @param language Language
     */
    registerDefaultCompletionProvider(language: string): void;
    private onFocus;
    private onBlur;
    private registerCursorListener;
    private unregisterCursorListener;
    /**
     * Toggle editor options based on if the editor is in active state (i.e. focused).
     * When the editor is not active, we want to deactivate some of the visual noise.
     * @param isActive Whether editor is active.
     */
    private toggleEditorOptions;
    /**
     * Register language features for target language. Call before setting language type to model.
     */
    private registerCompletionProvider;
    private registerDocumentFormatter;
    /**
     * This will hide the parameter widget if the user is not hovering over
     * the parameter widget for this monaco editor.
     *
     * Notes: See issue https://github.com/microsoft/vscode-python/issues/7851 for further info.
     * Hide the parameter widget if the following conditions have been met:
     * - Editor doesn't have focus
     * - Mouse is not over (hovering) the parameter widget
     *
     * This method is only used for blurring at the moment given that parameter widgets from
     * other cells are hidden by mouse move events.
     *
     * @private
     * @returns
     * @memberof MonacoEditor
     */
    private hideParameterWidget;
    /**
     * Hides widgets such as parameters and hover, that belong to a given parent HTML element.
     *
     * @private
     * @param {HTMLDivElement} widgetParent
     * @param {string[]} selectors
     * @memberof MonacoEditor
     */
    private hideWidgets;
    /**
     * Hides the parameters widgets related to other monaco editors.
     * Use this to ensure we only display parameters widgets for current editor (by hiding others).
     *
     * @private
     * @returns
     * @memberof MonacoEditor
     */
    private hideAllOtherParameterWidgets;
    /**
     * Return true if (x,y) coordinates overlap with an element's bounding rect.
     * @param {HTMLDivElement} element
     * @param {number} x
     * @param {number} y
     * @param {number} padding
     */
    private coordsInsideElement;
    /**
     * Hide all other widgets belonging to other cells only if the currently active
     * parameter widget (at most one) is being hovered by the user.
     * @param {number} x
     * @param {number} y
     */
    private handleCoordsOutsideWidgetActiveRegion;
}
