/*!
 * Jodit Editor (https://xdsoft.net/jodit/)
 * Released under MIT see LICENSE.txt in the project root for license information.
 * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
 */
/**
 * @module types
 */
import type { IFileBrowser } from "./file-browser";
import type { IUIButton, IUIElement, IUIIconState, IUIList } from "./ui";
import type { IViewBased } from "./view";
import type { IJodit } from "./jodit";
import type { Modes, IDictionary, HTMLTagNames, Nullable, IContainer, IComponent, IBound } from "./types";
import type { IMods } from "./traits";
interface IControlType<T extends IViewBased = IJodit | IViewBased | IFileBrowser, B extends IToolbarButton = IToolbarButton> {
    name?: string;
    text?: string;
    textTemplate?: (jodit: T, value: string) => string;
    mode?: Modes;
    hotkeys?: string | string[];
    data?: IDictionary;
    isInput?: boolean;
    component?: 'button' | 'select';
    isVisible?: (editor: T, control: IControlType) => boolean;
    /**
     * You can use it function for control - active/not active button
     *
     * @see copyformat plugin
     * @example
     * ```javascript
     * var editor = Jodit.make('.selectorclass', {
     *     buttons: {
     *          checkbox: {
     *              data: {
     *                  active: false,
     *              },
     *              iconURL: 'checkbox.png',
     *              exec: function (a, b, btn) {
     *                  btn.data.active = !btn.data.active;
     *              },
     *              isActive: function (editor, btn) {
     *                  return !!btn.data.active;
     *              }
     *          }
     *     }
     * })
     * ```
     */
    isActive?: (editor: T, button: B) => boolean;
    update?: (editor: T, button: B) => void;
    isChildActive?: (editor: T, button: B) => boolean; // for list
    getContent?: (editor: T, button: B) => string | HTMLElement;
    /**
     * You can use it function for control - disable/enable button
     *
     * @see copyformat plugin
     * @example
     * ```javascript
     * var editor = Jodit.make('.selectorclass', {
     *     buttons: {
     *          checkbox: {
     *              data: {
     *                  enable: false,
     *              },
     *              iconURL: 'checkbox.png',
     *              exec: function (a, b, btn) {
     *                  btn.data.active = !btn.data.active;
     *              },
     *              isDisabled: function (editor, btn) {
     *                  return !!btn.data.enable;
     *              }
     *          }
     *     }
     * })
     * ```
     */
    isDisabled?: (editor: T, button: B) => boolean;
    isChildDisabled?: (editor: T, button: B) => boolean;
    /**
     * Drop-down list. A hash or array. You must specify the command which will be submitted for the hash key
     * (or array value) (see .[[IJodit.execCommand]] or define 'exec' function. See example
     * @example
     * ```javascript
     * Jodit.make('#editor2', {
     *     buttons: Jodit.defaultOptions.buttons.concat([{
     *        name: 'listsss',
     *        iconURL: 'stuf/dummy.png',
     *        list: {
     *            h1: 'insert Header 1',
     *            h2: 'insert Header 2',
     *            clear: 'Empty editor',
     *        },
     *        exec: (editor, current, control) => {
     *             var key = control.args[0],
     *                value = control.args[1];
     *
     *             if (key === 'clear') {
     *                 this.setEditorValue('');
     *                 return;
     *             }
     *             this.s.insertNode(this.c.element(key, ''));
     *             this.message.info('Was inserted ' + value);
     *        },
     *        template: function (key, value) {
     *            return '<div>' + value + '</div>';
     *        }
     *  });
     * ```
     */
    list?: IDictionary<string | number> | string[] | number[];
    /**
     * The command executes when the button is pressed. Allowed all
     * @see https://developer.mozilla.org/ru/docs/Web/API/Document/execCommand#commands
     * and several specific [[IJodit.execCommand]]
     */
    command?: string;
    tagRegExp?: RegExp;
    /**
     * Tag list:  when cursor inward tag from this list, button will be highlighted
     */
    tags?: HTMLTagNames[];
    css?: IDictionary<string | string[]>;
    /**
     * String name for existing icons.
     * @example
     * ```javascript
     * var editor = Jodit.make('.editor', {
     *  buttons: [
     *      {
     *          icon: 'source',
     *          exec: function (editor) {
     *              editor.toggleMode();
     *          }
     *      }
     *  ]
     * })
     * ```
     */
    icon?: string | IUIIconState;
    /**
     * Use this property if you want set background image for the button. This icon can be 16 * 16 px in SVG or
     * another image formats
     */
    iconURL?: string;
    /**
     * Buttons hint
     */
    tooltip?: string | ((editor: T, control: IControlType<T, B>, button?: B) => string);
    /**
     * This function will be executed when the button is pressed.
     */
    exec?: (view: T, current: Nullable<Node>, options: {
        control: IControlType<T, B>;
        originalEvent: Event;
        button: IToolbarButton;
    }) => any;
    /**
     * Allows you to set a separate handler for list items
     * @example
     * ```javascript
     * Jodit.make('.editor', {
     * 	buttons: [
     * 		{
     * 			name: 'add-date',
     * 			iconURL: 'stuf/dummy.png',
     * 			list: {
     * 				options: 'Open options',
     * 			},
     * 			exec(editor, current, control) {
     * 				editor.s.insertHTML(new Date().toString());
     * 			},
     * 			childExec(editor, current, control) {
     * 				if (control.args[0] === 'options') {
     * 					editor.alert('Options');
     * 				}
     * 			}
     * 		}
     * 	]
     * })
     * ```
     */
    childExec?: (view: T, current: Nullable<Node>, options: {
        parentControl: IControlType<T, B>;
        control: IControlType<T, B>;
        originalEvent: Event;
        button: IToolbarButton;
    }) => any;
    args?: any[];
    /**
     * The method which will be called for each element of button.list
     */
    template?: (jodit: T, key: string, value: string) => string;
    childTemplate?: (jodit: T, key: string, value: string, button: IToolbarButton) => string;
    /**
     * After click on the button it will show popup element which consist value that this function returned
     * @example
     * ```javascript
     * var editor = Jodit.make('.editor', {
     *    buttons: [
     *      {
     *          icon: "insertCode",
     *          popup: function (editor) {
     *              var div = document.createElement('div'), button = dccument.createElement('button');
     *              div.innerHTML = 'Hi! Click button and enter your code';
     *              button.innerHTML = 'Click me';
     *
     *              div.appendChild(button);
     *
     *              button.addEventListener('click', function (e) {
     *                  editor.s.insertHTML(prompt("Enter your code"));
     *                  return false;
     *              });
     *              return div;
     *          }
     *      }
     *    ]
     * });
     * ```
     */
    popup?: (jodit: T, current: Nullable<Node>, close: () => void, button: B) => string | HTMLElement | IUIElement | false;
    defaultValue?: string | string[];
    value?: (jodit: T, button: B) => string | undefined;
    mods?: IMods['mods'];
}
interface IControlListItem {
    title: string;
    value: string;
}
interface IControlTypeStrong extends IControlType {
    name: NonNullable<IControlType['name']>;
}
interface IControlTypeContent extends IControlTypeStrong {
    getContent: NonNullable<IControlTypeStrong['getContent']>;
}
export interface Controls<T extends IViewBased = IJodit | IViewBased> {
    [controlName: string]: IControlType<T> | Controls<T>;
}
export type Buttons = Array<string | IControlType>;
export type ButtonGroup = string | 'source' | 'font-style' | 'script' | 'list' | 'indent' | 'font' | 'color' | 'media' | 'state' | 'clipboard' | 'insert' | 'history' | 'search' | 'other' | 'info';
export interface ButtonsGroup {
    group: ButtonGroup;
    buttons: Buttons;
}
export type ButtonsGroups = Array<IControlType | string | ButtonsGroup>;
export type ButtonsOption = string | ButtonsGroups;
type RequireKeys<T extends object, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
type IControlTypeStrongList = RequireKeys<IControlTypeStrong, 'list'>;
interface IToolbarButton extends IUIButton {
    control: IControlTypeStrong;
    target: Nullable<HTMLElement>;
}
interface IToolbarCollection extends IUIList {
    setDirection(direction: 'rtl' | 'ltr'): void;
    firstButton: Nullable<IToolbarButton>;
    shouldBeDisabled(button: IToolbarButton): boolean | void;
    shouldBeActive(button: IToolbarButton): boolean | void;
    getTarget(button: IToolbarButton): Node | null;
    show(): void;
    hide(): void;
    showInline(bound?: IBound): void;
}
export interface IStatusBar extends IContainer, IComponent, IMods {
    show(): void;
    hide(): void;
    isShown: boolean;
    getHeight(): number;
    append(el: HTMLElement, inTheRight?: boolean): void;
}
export interface IProgressBar extends IUIElement {
    show(): IProgressBar;
    hide(): IProgressBar;
    progress(percentage: number): IProgressBar;
    /**
     * Show file upload animation - file icon flies from `from` to `to` and fades out
     */
    showFileUploadAnimation(from?: {
        x: number;
        y: number;
    }, to?: {
        x: number;
        y: number;
    }): void;
}
