import { GardState } from 'wordgard/state';
import { Menu, Command } from 'wordgard/command';
import { KeyBinding, InputRule, Wordgard } from 'wordgard/editor';
import { PhraseSet } from 'wordgard/phrases';

/**
{@link Doc Schema element} that provides the outer document plot
type for a document with block content.
*/
declare function blockDoc(): GardState.Extension;
/**
Outer document {@link InlineDoc schema element} for a document
that contains only inline content.
*/
declare function inlineDoc(): GardState.Extension;
/**
The basic {@link Paragraph paragraph} schema element, with a
{@link paragraph.button menu button} and {@link
paragraph.keyBinding key binding} to switch to it.
*/
declare function paragraph(): GardState.Extension;
declare namespace paragraph {
    /**
    Binds `Ctrl-Shift-0` to switching the selected textblocks to
    regular paragraphs.
    */
    const keyBinding: KeyBinding;
    /**
    Button in the {@link Menu.Submenu.textblockStyle
    `textblockStyle`} menu that makes the selected textblocks
    paragraphs.
    */
    const button: Menu.Button;
}
/**
Support for heading blocks. Includes the {@link Heading schema
element}, some {@link heading.keyBindings key bindings}, menu
buttons, and an {@link heading.createOnHash input rule} to
switch to this block type.
*/
declare function heading(): GardState.Extension;
declare namespace heading {
    /**
    Binds `Ctrl-Shift-1` through `Ctrl-Shift-6` to make the selected
    textblocks headings of the given level.
    */
    const keyBindings: KeyBinding[];
    /**
    Button for the {@link Menu.Submenu.textblockStyle textblock
    style} menu that switches to a level 1 heading.
    */
    const button1: Menu.Button;
    /**
    Menu button that switches to a level 2 heading.
    */
    const button2: Menu.Button;
    /**
    Menu button that switches to a level 3 heading.
    */
    const button3: Menu.Button;
    /**
    Input rule that will switch to a heading when one to six hash
    characters, followed by a space, are typed at the start of a
    textblock, using the number of hash characters to determine the
    heading level.
    */
    const createOnHash: InputRule;
}
/**
Extensions to add support for code blocks. Includes the {@link
CodeBlock schema element}, a {@link codeBlock.keyBinding key
binding}, a {@link codeBlock.button menu button}, and an {@link
codeBlock.createOnBackticks input rule}.
*/
declare function codeBlock(): GardState.Extension;
declare namespace codeBlock {
    /**
    Binds `Ctrl-Shift-\` to switch the selected textblocks to a code
    block.
    */
    const keyBinding: KeyBinding;
    /**
    Button for the {@link Menu.Submenu.textblockStyle textblock
    style} menu that switches to a code block.
    */
    const button: Menu.Button;
    /**
    Input rule that switches the current textblock to a code block
    when you type three backticks at its start.
    */
    const createOnBackticks: InputRule;
}
/**
Extensions that add support for text alignment—the {@link
Alignment} mark, a set of {@link alignment.keyBindings key
bindings}, and a {@link alignment.button menu button}.
*/
declare function alignment(): GardState.Extension;
declare namespace alignment {
    /**
    Bind `Mod-Shift-l` to left-align, `Mod-Shift-r` to right-align,
    and `Mod-Shift-e` to center.
    */
    const keyBindings: KeyBinding[];
    /**
    A button that sets text alignments to start.
    */
    const buttonStart: Menu.Button;
    /**
    A button that sets text alignment to end.
    */
    const buttonEnd: Menu.Button;
    /**
    Menu button that sets text alignment to center.
    */
    const buttonCenter: Menu.Button;
    /**
    A button that pops up a submenu for alignment choice. Includes
    {@link alignment.buttonStart}, {@link alignment.buttonEnd}, and
    {@link alignment.buttonCenter} as default content, so if you
    include this you don't have to explicitly include those.
    */
    const button: Menu.Submenu;
}
/**
Add support for selecting a text direction per textblock. Includes
the {@link Direction} mark, the {@link direction.textblockDir |
extension} to make the editor interpret that, and a {@link
direction.button menu button}.
*/
declare function direction(): GardState.Extension;
declare namespace direction {
    /**
    This extension makes the editor state understand the effect the
    {@link Direction} mark has on text direction, so that cursor
    motion and such behaves correctly in blocks that have it.
    */
    const textblockDir: GardState.Extension;
    /**
    Menu button to choose a left-to-right text direction.
    */
    const buttonLTR: Menu.Button;
    /**
    Button to choose a right-to-left text direction.
    */
    const buttonRTL: Menu.Button;
    /**
    Button that enables automatic text direction, where the content
    of the textblock determines direction.
    */
    const buttonAuto: Menu.Button;
    /**
    Menu button for choosing text direction. Includes {@link
    direction.buttonLTR `buttonLTR`}, {@link direction.buttonRTL
    `buttonRTL`}, and {@link direction buttonAuto `buttonAuto`} as
    default content.
    */
    const button: Menu.Submenu;
}
/**
Support for blockquotes. Adds the {@link Blockquote schema
element}, a {@link blockquote.button menu button}, an {@link
blockquote.createOnGT input rule}, and a {@link blockquote.theme
default style}.
*/
declare function blockquote(): GardState.Extension;
declare namespace blockquote {
    /**
    Menu button that toggles a blockquote wrapper.
    */
    const button: Menu.Button;
    /**
    Input rule that wraps the current block in a blockquote when you
    type a greater-than sign followed by a space at its start.
    */
    const createOnGT: InputRule;
    /**
    Simple style that shows a border next to blockquotes to make
    them easy to see.
    */
    const theme: GardState.Extension;
}
/**
Support extension for horizontal rules. Provides the {@link
HorizontalRule schema element} and an {@link
horizontalRule.createOnDashes input rule}.
*/
declare function horizontalRule(): GardState.Extension;
declare namespace horizontalRule {
    /**
    Input rule that will create a horizontal rule if you type three
    dashes into an empty textblock.
    */
    const createOnDashes: InputRule;
}

/**
Enable support for bullet lists. Includes the schema elements, the {@link
bulletList.toggleButton menu button}, and the {@link
bulletList.createOnDash input rule}.
*/
declare function bulletList(config?: {
    /**
    By defaults, list items contain {@link doc.Node.Group.Content
    block content}. Set this to false to allow only inline content.
    */
    blockItems?: boolean;
}): GardState.Extension[];
declare namespace bulletList {
    /**
    This rule wraps the current textblock in a bullet list when the
    user starts it by typing an optional space, a dash, and then another
    space.
    */
    const createOnDash: InputRule;
    /**
    A menu button that toggles bullet list wrapping for the selection.
    */
    const toggleButton: Menu.Button;
}
/**
Returns extensions that enable ordered list support, including the
schema elements, {@link orderedList.toggleButton menu button},
and {@link orderedList.createOnNumber input rule}.
*/
declare function orderedList(config?: {
    blockItems?: boolean;
}): GardState.Extension[];
declare namespace orderedList {
    /**
    An input rule that, when the user starts a textblock with an
    optional space, a number, a period, and a space, wraps the block
    in an ordered list.
    */
    const createOnNumber: InputRule;
    /**
    A menu button that toggles an ordered list wrapper for the
    selected textblocks.
    */
    const toggleButton: Menu.Button;
}

/**
Returns an extension that enables {@link LineBreak line breaks}.
*/
declare function lineBreak(): GardState.Extension;
/**
Enable the {@link strong}, {@link emphasis}, and {@link link}
marks.
*/
declare function basicMarks(): GardState.Extension;
/**
Enable {@link strong}, {@link emphasis}, {@link code}, {@link
link}, {@link underline}, {@link strikethrough}, {@link
superscript}, {@link color}, and {@link backgroundColor}.
*/
declare function inlineMarks(): GardState.Extension;
/**
Add the elements of a simple rich text schema: {@link blockDoc},
{@link basicMarks}, {@link paragraph}, {@link heading}, and {@link
lineBreak}.
*/
declare function basicSchema(): GardState.Extension;
/**
Add the extensions for a simple schema where the document is a
single textblock: {@link inlineDoc}, {@link basicMarks}, {@link
image}, and {@link lineBreak}.
*/
declare function inlineSchema(): GardState.Extension;
/**
Returns an extension with all the schema elements included in this
module, in a {@link blockDoc block document}. Note that new
elements may appear in this schema as new versions of the library
add new features.
*/
declare function fullSchema(): GardState.Extension;

/**
Extension that enables strong emphasis support. Includes the
{@link Strong schema element}, {@link strong.keyBinding key
binding}, and {@link strong.button menu button}.
*/
declare function strong(): GardState.Extension;
declare namespace strong {
    /**
    Binds `Mod-b` to toggle strong emphasis.
    */
    const keyBinding: KeyBinding;
    /**
    A menu button that toggles strong emphasis.
    */
    const button: Menu.Button;
}
/**
Returns extensions for the emphasis mark—the {@link Emphasis
schema element}, a {@link emphasis.keyBinding key binding}, and
a {@link emphasis.button menu button}.
*/
declare function emphasis(): GardState.Extension;
declare namespace emphasis {
    /**
    Binds `Mod-i` to toggle emphasis.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button that toggles emphasis.
    */
    const button: Menu.Button;
}
/**
Returns extensions that enable the code font mark. Includes the
{@link Code schema element}, a {@link code.keyBinding key
binding}, and a {@link code.button menu button}.
*/
declare function code(): GardState.Extension;
declare namespace code {
    /**
    Binds `` Mod-` `` to toggle the code font mark.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button for toggling code font.
    */
    const button: Menu.Button;
}
/**
Returns an extension bundle for the underline mark, including the
{@link Underline schema element}, a {@link underline.keyBinding
key bindding}, and a {@link underline.button menu button}.
*/
declare function underline(): GardState.Extension;
declare namespace underline {
    /**
    Binds `Mod-u` to toggle the underline mark.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button for toggling underline.
    */
    const button: Menu.Button;
}
/**
Extensions to support a strikethrough mark—the {@link
Strikethrough schema element}, a {@link strikethrough.keyBinding
key binding}, and a {@link strikethrough.button menu button}.
*/
declare function strikethrough(): GardState.Extension;
declare namespace strikethrough {
    /**
    Binds `Mod-/` to toggle strikethrough.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button that toggles the strikethrough mark.
    */
    const button: Menu.Button;
}
/**
Add support for a superscript mark. Includes the {@link
Superscript schema element}, a {@link superscript.keyBinding
key binding}, and a {@link superscript.button menu button}.
*/
declare function superscript(): GardState.Extension;
declare namespace superscript {
    /**
    Binds `Mod-.` to toggle superscript.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button for toggling superscript.
    */
    const button: Menu.Button;
}
/**
Support for a subscript mark. Includes the {@link Subscript
schema element}, a {@link subscript.keyBinding key binding}, and
a {@link subscript.button menu button}.
*/
declare function subscript(): GardState.Extension;
declare namespace subscript {
    /**
    Binds `Mod-,` to toggle the subscript mark.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button for toggling subscript.
    */
    const button: Menu.Button;
}

/**
User interface component that shows a grid of colors and allows
the user to pick one, for use in a menu.
*/
declare class ColorPicker {
    dom: HTMLElement;
    private width;
    private selPos;
    private options;
    private constructor();
    /**
    Construct the color picker. `finish` will be called when a color
    is selected.
    */
    static create(wg: Wordgard, finish: (color: string) => void): ColorPicker;
    private move;
}
declare namespace ColorPicker {
    /**
    The type used for color options.
    */
    type Option = {
        /**
        Reference to a phrase giving the name of the color.
        */
        name: PhraseSet.Ref;
        /**
        An optional second phrase to show after the name.
        */
        detail?: PhraseSet.Ref;
        /**
        The color as a CSS color string, or the empty string to
        indicate that this option clears the color.
        */
        value: string;
    };
    /**
    Facet used to configure the width (in color widgets) of the
    color picker. Defaults to 10.
    */
    const width: GardState.Facet<number, number>;
    /**
    Facet used to configure color picker options. The default is a
    collection of 80 colors, starting with an empty one for clearing
    color.
    */
    const options: GardState.Facet<readonly Option[], readonly Option[]>;
    /**
    Base theme for the color picker.
    */
    const theme: GardState.Extension;
}
/**
Adds support for a text color mark. Includes the {@link Color
schema element}, the {@link color.button menu button}, and the
{@link ColorPicker.theme color picker styles}.
*/
declare function color(): GardState.Extension;
declare namespace color {
    /**
    A button that shows a color picker to change the text color.
    */
    const button: Menu.Submenu;
}
/**
Adds support for a background color mark. Includes the {@link
BackgroundColor schema element}, the {@link
backgroundColor.button menu button}, and the {@link
ColorPicker.theme color picker styles}.
*/
declare function backgroundColor(): GardState.Extension;
declare namespace backgroundColor {
    /**
    A button that expands a submenu with a color picker that can be
    used to change the text background color.
    */
    const button: Menu.Submenu;
}

/**
Extensions for a link mark—the {@link Link schema element}, a
{@link link.keyBinding key binding}, a {@link link.button menu
button}, the {@link link.tooltip link tooltip}, and the {@link
link.pasteOver paste-link handler}.
*/
declare function link(): GardState.Extension;
declare namespace link {
    /**
    Binds `Mod-k` to toggle the link mark.
    */
    const keyBinding: KeyBinding;
    /**
    Menu button that will remove the link mark from the selection if
    present, or prompt for a target and make the current selection a
    link.
    */
    const button: Menu.Button;
    /**
    Extension that displays a tooltip with the link target below the
    cursor when that is in a link.
    */
    const tooltip: GardState.Extension;
    /**
    Registers a paste handler that, when a URI is pasted over a
    selection, will add a link to the selection instead of replacing
    it with the pasted text.
    */
    const pasteOver: GardState.Extension;
}

/**
Support for block figures. Adds the same support extensions as
{@link image}, but includes the {@link Figure} schema element instead.
*/
declare function figure(conf?: {
    /**
    When enabled, also support {@link CaptionedFigure captioned figures}.
    */
    captioned?: boolean;
}): GardState.Extension;
/**
Add resizing functionality for images and figures. Includes the
{@link ImageSize} mark, the {@link imageResizing.dragHandle drag
handle}, and {@link imageResizing.keyBindings key bindings}.
*/
declare function imageResizing(): GardState.Extension;
declare namespace imageResizing {
    /**
    Returns a command that resizes the currently selected image or
    figure. When `relative` is fale, `by` indicates a pixel amount,
    which can be positive or negative. When it is true, `by` is a
    scaling factor, which should be between 0 and 1 to shrink the
    image, and greater than1 to grow it.
    */
    const resizeCommand: (by: number, relative?: boolean) => Command;
    /**
    Binds `Ctrl-Alt-l` (`Ctrl-Cmd-l` on Mac) to grow an image by
    10%, and `Ctrl-Alt-k` (`Ctrl-Cmd-k` on Mac) to shrink it by 10%.
    */
    const keyBindings: KeyBinding[];
    /**
    Extension that displays a drag handle when the user hovers over
    an image or figure, which can be dragged to adjust the element's
    width.
    */
    const dragHandle: GardState.Extension;
}
/**
Returns extensions that add support for inline images. That
includes the {@link Image schema element}, the {@link ImageAlt
alt text mark}, the {@link image.button menu button}, a {@link
image.keyBinding key binding}, and a {@link image.dropHandler
drop handler for image files}.
*/
declare function image(): GardState.Extension;
declare namespace image {
    /**
    Binds `Ctrl-Alt-i` to open the image insert/update dialog.
    */
    const keyBinding: KeyBinding;
    /**
    A menu button that opens a dialog to insert an image or figure,
    or to adjust the currently selected image or figure.
    */
    const button: Menu.Button;
    /**
    A custom drop handler that checks whether an image file is being
    dropped. When an {@link image.uploader uploader} has been
    defined, it will feed the file to that, and insert an image with
    the resulting URI when it finishes.
    */
    const dropHandler: GardState.Extension;
    /**
    The command that opens the image dialog.
    */
    const insert: Command;
    /**
    A facet that you can use to register a handler for image
    uploads. Your function will be passed a file object, an editor
    instance, and a function that it can call to indicate progress,
    and should return a promise that resolves to a URI for the
    uploaded image.
    */
    const uploader: GardState.Facet<(file: File, wg: Wordgard, progress: (percent: number) => void) => Promise<string>, readonly ((file: File, wg: Wordgard, progress: (percent: number) => void) => Promise<string>)[]>;
}

export { ColorPicker, alignment, backgroundColor, basicMarks, basicSchema, blockDoc, blockquote, bulletList, code, codeBlock, color, direction, emphasis, figure, fullSchema, heading, horizontalRule, image, imageResizing, inlineDoc, inlineMarks, inlineSchema, lineBreak, link, orderedList, paragraph, strikethrough, strong, subscript, superscript, underline };
