import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { ColorState, SketchPicker } from 'react-color';
import { Doc, StrListCast } from '../../../../fields/Doc';
import { InkTool } from '../../../../fields/InkField';
import { createSchema, makeInterface } from '../../../../fields/Schema';
import { ScriptField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, NumCast, StrCast } from '../../../../fields/Types';
import { WebField } from '../../../../fields/URLField';
import { DocumentType } from '../../../documents/DocumentTypes';
import { Scripting } from "../../../util/Scripting";
import { SelectionManager } from '../../../util/SelectionManager';
import { ColorScheme } from '../../../util/SettingsManager';
import { UndoManager } from '../../../util/UndoManager';
import { CollectionViewType } from '../../collections/CollectionView';
import { ContextMenu } from '../../ContextMenu';
import { DocComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { GestureOverlay } from '../../GestureOverlay';
import { Colors } from '../../global/globalEnums';
import { SetActiveInkColor } from '../../InkingStroke';
import { StyleProp } from '../../StyleProvider';
import { FieldView, FieldViewProps } from '.././FieldView';
import './FontIconBox.scss';
import { RichTextMenu } from '../formattedText/RichTextMenu';
const FontIconSchema = createSchema({
    icon: "string",
});

export enum ButtonType {
    MenuButton = "menuBtn",
    DropdownList = "drpdownList",
    DropdownButton = "drpdownBtn",
    ClickButton = "clickBtn",
    DoubleButton = "dblBtn",
    ToggleButton = "tglBtn",
    ColorButton = "colorBtn",
    ToolButton = "toolBtn",
    NumberButton = "numBtn",
    EditableText = "editableText"
}

export enum NumButtonType {
    Slider = "slider",
    DropdownOptions = "list",
    Inline = "inline"
}

export interface ButtonProps extends FieldViewProps {
    type?: ButtonType;
}

type FontIconDocument = makeInterface<[typeof FontIconSchema]>;
const FontIconDocument = makeInterface(FontIconSchema);
@observer
export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(FontIconDocument) {
    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
    showTemplate = (): void => {
        const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
        dragFactory && this.props.addDocTab(dragFactory, "add:right");
    }
    dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
    useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };

    specificContextMenu = (): void => {
        if (!Doc.UserDoc().noviceMode) {
            const cm = ContextMenu.Instance;
            cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
            cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
            cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
        }
    }

    // Determining UI Specs
    @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
    @observable private icon = StrCast(this.dataDoc.icon, "user") as any;
    @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen);
    @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList);
    @observable private type = StrCast(this.rootDoc.btnType);

    /**
     * Types of buttons in dash:
     * - Main menu button (LHS)
     * - Tool button
     * - Expandable button (CollectionLinearView)
     * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
     * - Action button
     * - Dropdown button 
     * - Color button
     * - Dropdown list
     * - Number button
    **/

    _batch: UndoManager.Batch | undefined = undefined;
    /**
     * Number button
     */
    @computed get numberButton() {
        const numBtnType: string = StrCast(this.rootDoc.numBtnType);
        const setValue = (value: number) => {
            // Script for running the toggle
            const script: string = StrCast(this.rootDoc.script) + "(" + value + ")";
            ScriptField.MakeScript(script)?.script.run();
        };

        // Script for checking the outcome of the toggle
        const checkScript: string = StrCast(this.rootDoc.script) + "(0, true)";
        const checkResult: number = ScriptField.MakeScript(checkScript)?.script.run().result;


        if (numBtnType === NumButtonType.Slider) {
            const dropdown =
                <div
                    className="menuButton-dropdownBox"
                    onPointerDown={e => e.stopPropagation()}
                >
                    <input type="range" step="1" min={NumCast(this.rootDoc.numBtnMin, 0)} max={NumCast(this.rootDoc.numBtnMax, 100)} value={checkResult}
                        className={"menu-slider"} id="slider"
                        onPointerDown={() => this._batch = UndoManager.StartBatch("presDuration")}
                        onPointerUp={() => this._batch?.end()}
                        onChange={e => { e.stopPropagation(); setValue(Number(e.target.value)); }}
                    />
                </div>;
            return (
                <div
                    className={`menuButton ${this.type} ${numBtnType}`}
                    onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
                >
                    {checkResult}
                    {this.rootDoc.dropDownOpen ? dropdown : null}
                </div>
            );
        } else if (numBtnType === NumButtonType.DropdownOptions) {
            const items: number[] = [];
            for (let i = 0; i < 100; i++) {
                if (i % 2 === 0) {
                    items.push(i);
                }
            }
            const list = items.map((value) => {
                return <div className="list-item" key={`${value}`}
                    style={{
                        backgroundColor: value === checkResult ? Colors.LIGHT_BLUE : undefined
                    }}
                    onClick={() => setValue(value)}>
                    {value}
                </div>;
            });
            return (
                <div
                    className={`menuButton ${this.type} ${numBtnType}`}
                >
                    <div className={`button`} onClick={action((e) => setValue(checkResult - 1))}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"minus"} />
                    </div>
                    <div
                        className={`button ${'number'}`}
                        onPointerDown={(e) => {
                            e.stopPropagation();
                            e.preventDefault();
                        }}
                        onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}
                    >
                        <input
                            style={{ width: 30 }}
                            className="button-input"
                            type="number"
                            value={checkResult}
                            onChange={action((e) => setValue(Number(e.target.value)))}
                        />
                    </div>
                    <div className={`button`} onClick={action((e) => setValue(checkResult + 1))}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"plus"} />
                    </div>
                    {this.rootDoc.dropDownOpen ?
                        <div>
                            <div className="menuButton-dropdownList"
                                style={{ left: "25%" }}>
                                {list}
                            </div>
                            <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
                        </div> : null}

                </div>
            );
        } else {
            return (
                <div>

                </div>
            );
        }


    }

    /**
     * Dropdown button
     */
    @computed get dropdownButton() {
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
        return (
            <div className={`menuButton ${this.type} ${active}`}
                style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
                onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}>
                <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
                <div
                    className="menuButton-dropdown"
                    style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
                    <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
                </div>
                {this.rootDoc.dropDownOpen ?
                    <div className="menuButton-dropdownBox">
                        {/* DROPDOWN BOX CONTENTS */}
                    </div> : null}
            </div>
        );
    }

    /**
     * Dropdown list
     */
    @computed get dropdownListButton() {
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);

        const script: string = StrCast(this.rootDoc.script);

        let noviceList: string[] = [];
        let text: string | undefined;
        let dropdown = true;
        let icon: IconProp = "caret-down";
        let noneSelected: boolean = false;

        if (script === 'setView') {
            const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
            if (selected && StrCast(selected.Document.type) === DocumentType.COL) {
                text = StrCast(selected.Document._viewType);
            } else if (selected) {
                dropdown = false;
                text = StrCast(selected.Document.type);
                icon = Doc.toIcon(selected.Document);
            } else {
                dropdown = false;
                noneSelected = true;
                text = "None selected";
            }
            noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
        } else if (script === 'setFont') {
            const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
            if (selected && StrCast(selected.Document.type) === DocumentType.RTF) {
                text = StrCast(selected.Document._fontFamily);
            } else {
                const fontFamily = StrCast(Doc.UserDoc()._fontFamily);
                text = fontFamily;
            }
            noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia",
                "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
        }

        // Get items to place into the list
        const list = this.buttonList.map((value) => {
            if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) {
                return;
            }
            const click = () => {
                const s = ScriptField.MakeScript(script + '("' + value + '")');
                if (s) {
                    s.script.run().result;
                }
            };
            return <div className="list-item" key={`${value}`}
                style={{
                    fontFamily: script === 'setFont' ? value : undefined,
                    backgroundColor: value === text ? Colors.LIGHT_BLUE : undefined
                }}
                onClick={click}>
                {value[0].toUpperCase() + value.slice(1)}
            </div>;
        });

        const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
                {this.label}
            </div>;

        return (
            <div className={`menuButton ${this.type} ${active}`}
                style={{ backgroundColor: this.rootDoc.dropDownOpen ? Colors.MEDIUM_BLUE : backgroundColor, color: color, display: dropdown ? undefined : "flex" }}
                onClick={dropdown ? () => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
                {dropdown || noneSelected ? (null) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />}
                <div className="menuButton-dropdown-header">
                    {text && text[0].toUpperCase() + text.slice(1)}
                </div>
                {label}
                {!dropdown ? (null) : <div className="menuButton-dropDown">
                    <FontAwesomeIcon icon={icon} color={color} size="sm" />
                </div>}
                {this.rootDoc.dropDownOpen ?
                    <div>
                        <div className="menuButton-dropdownList"
                            style={{ left: 0 }}>
                            {list}
                        </div>
                        <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
                    </div>
                    : null}
            </div>
        );
    }

    /**
     * Color button
     */
    @computed get colorButton() {
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);

        const script: string = StrCast(this.rootDoc.script);
        const scriptCheck: string = script + "(undefined, true)";
        const boolResult = ScriptField.MakeScript(scriptCheck)?.script.run().result;

        let stroke: boolean = false;
        let strokeIcon: any;
        if (script === "setStrokeColor") {
            stroke = true;
            const checkWidth = ScriptField.MakeScript("setStrokeWidth(0, true)")?.script.run().result;
            const width = 20 + (checkWidth / 100) * 70;
            const height = 20 + (checkWidth / 100) * 70;
            strokeIcon = (<div style={{ borderRadius: "100%", width: width + '%', height: height + '%', backgroundColor: boolResult ? boolResult : "#FFFFFF" }} />)
        }

        const colorOptions: string[] = ['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
            '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
            '#FFFFFF', '#f1efeb'];

        const colorBox = (func: (color: ColorState) => void) => <SketchPicker
            disableAlpha={!stroke}
            onChange={func} color={boolResult ? boolResult : "#FFFFFF"}
            presetColors={colorOptions} />;
        const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
                {this.label}
            </div>;

        const dropdownCaret = <div
            className="menuButton-dropDown"
            style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
            <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
        </div>;

        const click = (value: ColorState) => {
            const hex: string = value.hex;
            const s = ScriptField.MakeScript(script + '("' + hex + '", false)');
            if (s) {
                s.script.run().result;
            }
        };
        return (
            <div className={`menuButton ${this.type} ${active}`}
                style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
                onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
                onPointerDown={e => e.stopPropagation()}>
                {stroke ? strokeIcon : <><FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                    <div className="colorButton-color"
                        style={{ backgroundColor: boolResult ? boolResult : "#FFFFFF" }}
                    ></div></>}
                {label}
                {/* {dropdownCaret} */}
                {this.rootDoc.dropDownOpen ?
                    <div>
                        <div className="menuButton-dropdownBox"
                            onPointerDown={e => e.stopPropagation()}
                            onClick={e => e.stopPropagation()}>
                            {colorBox(click)}
                        </div>
                        <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
                    </div>
                    : null}
            </div>
        );
    }

    @computed get toggleButton() {
        // Determine the type of toggle button
        const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);

        // Colors
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);

        // Button label
        const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
                {this.label}
            </div>;

        if (switchToggle) {
            return (
                <div className={`menuButton ${this.type} ${'switch'}`}>
                    <label className="switch">
                        <input type="checkbox"
                            checked={backgroundColor === Colors.MEDIUM_BLUE}
                        />
                        <span className="slider round"></span>
                    </label>
                </div>
            );
        } else {
            return (
                <div className={`menuButton ${this.type}`}
                    style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
                    <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                    {label}
                </div>
            );
        }
    }



    /**
     * Default
     */
    @computed get defaultButton() {
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        return (
            <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu}
                style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
                <div className="menuButton-wrap">
                    <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} />
                    {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>}
                </div>
            </div>
        );
    }

    @computed get editableText() {
        // Script for running the toggle
        const script: string = StrCast(this.rootDoc.script);

        // Script for checking the outcome of the toggle
        let checkScript: string = StrCast(this.rootDoc.script) + "('', true)";

        // Function to run the script
        const checkResult = ScriptField.MakeScript(checkScript)?.script.run().result;

        const setValue = (value: string, shiftDown?: boolean): boolean => {
            ScriptField.MakeScript(script + "('" + value + "')")?.script.run();
            return true;
        };
        return (
            <div className="menuButton editableText">
                <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={"lock"} />
                <EditableView GetValue={() => checkResult} SetValue={setValue} contents="...">
                </EditableView>
            </div>
        );
    }


    render() {
        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
        // Variables called through eval (from button)
        const numSelected = SelectionManager.Views().length;

        const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark;

        const active: string = StrCast(this.rootDoc.dropDownOpen);
        const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}>
                {this.label}
            </div>;
        const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
                {this.label}
            </div>;

        // TODO:glr Add label of button type
        let button = this.defaultButton;

        switch (this.type) {
            case ButtonType.EditableText:
                console.log("Editable text");
                button = this.editableText;
                break;
            case ButtonType.NumberButton:
                button = this.numberButton;
                break;
            case ButtonType.DropdownButton:
                button = this.dropdownButton;
                break;
            case ButtonType.DropdownList:
                button = this.dropdownListButton;
                break;
            case ButtonType.ColorButton:
                button = this.colorButton;
                break;
            case ButtonType.ToolButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor: backgroundColor, color: color }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                        {label}
                    </div>
                );
                break;
            case ButtonType.ToggleButton:
                button = this.toggleButton;
                break;
            case ButtonType.ClickButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor, opacity: 1 }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                        {label}
                    </div>
                );
                break;
            case ButtonType.MenuButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ color: color, backgroundColor: backgroundColor }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />
                        {menuLabel}
                    </div >
                );
                break;
            default:
                break;
        }

        return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button :
            <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
                {button}
            </Tooltip>;
    }
}


// toggle: Set overlay status of selected document
Scripting.addGlobal(function setView(view: string) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
    selected ? selected.Document._viewType = view : console.log("[FontIconBox.tsx] changeView failed");
});

// toggle: Set overlay status of selected document
Scripting.addGlobal(function setBackgroundColor(color?: string, checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
    if (checkResult) {
        if (selected) {
            console.log("[Background] (selected): " + StrCast(selected._backgroundColor));
            return selected._backgroundColor;
        } else {
            return "#FFFFFF";
        }
    }
    if (selected && selected.type === DocumentType.INK) selected.fillColor = color;
    if (selected) selected._backgroundColor = color;
    Doc.UserDoc()._fontColor = color;
});

// toggle: Set overlay status of selected document
Scripting.addGlobal(function toggleOverlay(checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
    if (checkResult && selected) {
        if (NumCast(selected.Document.z) === 1) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed");
});

/** TEXT
 *      setFont
 *      setFontSize
 *      toggleBold
 *      toggleUnderline
 *      toggleItalic
 *      setAlignment
 *      toggleBold
 *      toggleItalic
 *      toggleUnderline
 **/

// toggle: Set overlay status of selected document
Scripting.addGlobal(function setFont(font: string, checkResult?: boolean) {
    SelectionManager.Views().map(dv => dv.props.Document._fontFamily = font);
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    editorView?.state && RichTextMenu.Instance.setFontFamily(font, editorView);
    Doc.UserDoc()._fontFamily = font;
    return Doc.UserDoc()._fontFamily;
});

Scripting.addGlobal(function getActiveTextInfo(info: "family" | "size" | "color" | "highlight") {
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    const style = editorView?.state && RichTextMenu.Instance.getActiveFontStylesOnSelection();
    switch (info) {
        case "family": return style?.activeColors[0];
        case "size": return style?.activeSizes[0];
        case "color": return style?.activeColors[0];
        case "highlight": return style?.activeHighlights[0];
    }
})

Scripting.addGlobal(function setAlignment(align: "left" | "right" | "center", checkResult?: boolean) {
    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
    if (checkResult) {
        let active: string;
        if (editorView) {
            active = editorView?.state && RichTextMenu.Instance.getActiveAlignment();
        } else {
            active = StrCast(Doc.UserDoc().textAlign);
        }
        if (active === align) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    SelectionManager.Views().map(dv => dv.props.Document.textAlign = align);
    switch (align) {
        case "left":
            editorView?.state && RichTextMenu.Instance.alignLeft(editorView, editorView.dispatch);
            break;
        case "center":
            editorView?.state && RichTextMenu.Instance.alignCenter(editorView, editorView.dispatch);
            break;
        case "right":
            editorView?.state && RichTextMenu.Instance.alignRight(editorView, editorView.dispatch);
            break;
        default:
            break;
    }
    Doc.UserDoc().textAlign = align;
});

Scripting.addGlobal(function setBulletList(mapStyle: "bullet" | "decimal", checkResult?: boolean) {
    const editorView = RichTextMenu.Instance?.TextView?.EditorView;
    if (checkResult) {
        const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
        console.log(active, mapStyle);
        if (active === mapStyle) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    if (editorView) {
        const active = editorView?.state && RichTextMenu.Instance.getActiveListStyle();
        if (active === mapStyle) {
            console.log("set bullet list");
            editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: "" }));
        } else {
            editorView?.state && RichTextMenu.Instance.changeListType(editorView.state.schema.nodes.ordered_list.create({ mapStyle: mapStyle }));
        }
    }
});

// toggle: Set overlay status of selected document
Scripting.addGlobal(function setFontColor(color?: string, checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
    const editorView = RichTextMenu.Instance.TextView?.EditorView;

    if (checkResult) {
        if (selected) {
            console.log("[Font color] (selected): " + StrCast(selected.rootDoc._fontColor));
            return selected.rootDoc._fontColor;
        } else {
            console.log("[Font color] (global): " + StrCast(Doc.UserDoc()._fontColor));
            return Doc.UserDoc()._fontColor;
        }
    }

    if (selected) {
        selected.rootDoc._fontColor = color;
        if (color) {
            editorView?.state && RichTextMenu.Instance.setColor(color, editorView, editorView?.dispatch);
        }
    }
    Doc.UserDoc()._fontColor = color;
});

// toggle: Set overlay status of selected document
Scripting.addGlobal(function setFontHighlight(color?: string, checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
    const editorView = RichTextMenu.Instance.TextView?.EditorView;

    if (checkResult) {
        if (selected) {
            return selected.Document._fontHighlight;
        } else {
            return Doc.UserDoc()._fontHighlight;
        }
    }
    if (selected) {
        selected.rootDoc._fontColor = color;
        if (color) {
            editorView?.state && RichTextMenu.Instance.setHighlight(color, editorView, editorView?.dispatch);
        }
    }
    Doc.UserDoc()._fontHighlight = color;
});



// toggle: Set overlay status of selected document
Scripting.addGlobal(function setFontSize(size: string, checkResult?: boolean) {
    if (checkResult) {
        const size: number = parseInt(StrCast(Doc.UserDoc()._fontSize), 10);
        return size;
    }
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    editorView?.state && RichTextMenu.Instance.setFontSize(Number(size), editorView);
    Doc.UserDoc()._fontSize = size + "px";
});

Scripting.addGlobal(function toggleBold(checkResult?: boolean) {
    if (checkResult) {
        if (Doc.UserDoc().bold) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    if (editorView) {
        console.log("editorView");
        editorView?.state && RichTextMenu.Instance.toggleBold(editorView, true);
    }
    SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.bold = !dv.props.Document.bold);
    Doc.UserDoc().bold = !Doc.UserDoc().bold;
    return Doc.UserDoc().bold;
});

Scripting.addGlobal(function toggleUnderline(checkResult?: boolean) {
    if (checkResult) {
        if (Doc.UserDoc().underline) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    if (editorView) {
        console.log("editorView");
        editorView?.state && RichTextMenu.Instance.toggleUnderline(editorView, true);
    }
    SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.underline = !dv.props.Document.underline);
    Doc.UserDoc().underline = !Doc.UserDoc().underline;
    return Doc.UserDoc().underline;
});

Scripting.addGlobal(function toggleItalic(checkResult?: boolean) {
    if (checkResult) {
        if (Doc.UserDoc().italic) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    const editorView = RichTextMenu.Instance.TextView?.EditorView;
    if (editorView) {
        console.log("editorView");
        editorView?.state && RichTextMenu.Instance.toggleItalic(editorView, true);
    }
    SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.RTF).map(dv => dv.props.Document.italic = !dv.props.Document.italic);
    Doc.UserDoc().italic = !Doc.UserDoc().italic;
    return Doc.UserDoc().italic;
});




/** INK
 *      setActiveInkTool
 *      setStrokeWidth
 *      setStrokeColor
 **/

Scripting.addGlobal(function setActiveInkTool(tool: string, checkResult?: boolean) {
    if (checkResult) {
        if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    if (tool === "circle") {
        Doc.UserDoc().activeInkTool = "pen";
        GestureOverlay.Instance.InkShape = tool;
    } else if (tool === "square") {
        Doc.UserDoc().activeInkTool = "pen";
        GestureOverlay.Instance.InkShape = tool;
    } else if (tool === "line") {
        Doc.UserDoc().activeInkTool = "pen";
        GestureOverlay.Instance.InkShape = tool;
    } else if (tool) {
        if (Doc.UserDoc().activeInkTool === tool && GestureOverlay.Instance.InkShape === "" || GestureOverlay.Instance.InkShape === tool) {
            GestureOverlay.Instance.InkShape = "";
            Doc.UserDoc().activeInkTool = InkTool.None;
        } else {
            Doc.UserDoc().activeInkTool = tool;
        }
    } else {
        Doc.UserDoc().activeInkTool = InkTool.None;
    }
});

Scripting.addGlobal(function setStrokeWidth(width: number, checkResult?: boolean) {
    if (checkResult) {
        const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
        if (selected && selected.type === DocumentType.INK) {
            return Number(selected.strokeWidth);
        } else {
            const width: number = NumCast(Doc.UserDoc().activeInkWidth);
            return width;
        }
    }
    Doc.UserDoc().activeInkWidth = width;
    SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(width));
});

// toggle: Set overlay status of selected document
Scripting.addGlobal(function setStrokeColor(color?: string, checkResult?: boolean) {
    if (checkResult) {
        const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
        if (selected && selected.type === DocumentType.INK) {
            return selected.color;
        } else {
            const color: string = StrCast(Doc.UserDoc().activeInkColor);
            return color;
        }
    }
    SetActiveInkColor(StrCast(color));
    SelectionManager.Views().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.color = String(color));
});


/** WEB
 *      webSetURL
 **/
Scripting.addGlobal(function webSetURL(url: string, checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
    console.log("URL: ", url);
    if (checkResult && selected && selected.type === DocumentType.WEB) {
        return Cast(selected.data, WebField, null).url;
    }
    else if (selected && selected.type === DocumentType.WEB) {
        selected.data = url;
    }
});


/** Schema
 *      toggleSchemaPreview
 **/
Scripting.addGlobal(function toggleSchemaPreview(checkResult?: boolean) {
    const selected = SelectionManager.Views().length ? SelectionManager.Views()[0].rootDoc : undefined;
    if (checkResult && selected) {
        const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
        if (result) return Colors.MEDIUM_BLUE;
        else return "transparent";
    }
    else if (selected) {
        if (NumCast(selected.schemaPreviewWidth) > 0) {
            selected.schemaPreviewWidth = 200;
        } else {
            selected.schemaPreviewWidth = 0;
        }
    }
});