import React = require("react");
import AntimodeMenu from "../../AntimodeMenu";
import { observer } from "mobx-react";
import { observable, action, computed } from "mobx";
import "./InkOptionsMenu.scss";
import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke";
import { Scripting } from "../../../util/Scripting";
import { InkTool } from "../../../../fields/InkField";
import { ColorState } from "react-color";
import { Utils } from "../../../../Utils";
import GestureOverlay from "../../GestureOverlay";
import { Doc } from "../../../../fields/Doc";
import { SelectionManager } from "../../../util/SelectionManager";
import { DocumentView } from "../../../views/nodes/DocumentView";
import { Document } from "../../../../fields/documentSchemas";
import { DocumentType } from "../../../documents/DocumentTypes";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, faArrowRight, faArrowsAltH, faMinus, faCircle, faExclamationTriangle, faSquare, faLongArrowAltRight, faPenFancy, faCaretSquareRight, faAngleDoubleRight, } from "@fortawesome/free-solid-svg-icons";
import { Cast, StrCast, BoolCast } from "../../../../fields/Types";
import FormatShapePane from "./FormatShapePane";

library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, faLongArrowAltRight, faArrowsAltH, faMinus, faCircle, faSquare, faSquare, faPenFancy, faAngleDoubleRight,);



@observer
export default class InkOptionsMenu extends AntimodeMenu {
    static Instance: InkOptionsMenu;

    private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""];
    private _width = ["1", "5", "10", "100"];
    private _dotsize = [10, 20, 30, 40];
    private _draw = ["∿", "⎯", "→", "↔︎", "ロ", "O"];
    private _head = ["", "", "", "arrow", "", ""];
    private _end = ["", "", "arrow", "arrow", "", ""];
    private _shape = ["", "line", "line", "line", "rectangle", "circle"];
    private _title = ["pen", "line", "line with arrow", "line with double arrows", "square", "circle",];
    private _faName = ["pen-fancy", "minus", "long-arrow-alt-right", "arrows-alt-h", "square", "circle"];

    @observable _shapesNum = this._shape.length;
    @observable _selected = this._shapesNum;

    @observable private collapsed: boolean = false;
    @observable _double = "";

    @observable _colorBtn = false;
    @observable _widthBtn = false;
    @observable _fillBtn = false;
    // @observable _arrowBtn = false;
    // @observable _dashBtn = false;
    // @observable _shapeBtn = false;



    constructor(props: Readonly<{}>) {
        super(props);
        InkOptionsMenu.Instance = this;
        this._canFade = false; // don't let the inking menu fade away
        this.Pinned = BoolCast(Doc.UserDoc()["menuInkOptions-pinned"]);

    }

    @action
    toggleMenuPin = (e: React.MouseEvent) => {
        Doc.UserDoc()["menuInkOptions-pinned"] = this.Pinned = !this.Pinned;
        if (!this.Pinned) {
            // this.fadeOut(true);
        }
    }

    @action
    protected toggleCollapse = (e: React.MouseEvent) => {
        this.collapsed = !this.collapsed;
        setTimeout(() => {
            const x = Math.min(this._left, window.innerWidth - InkOptionsMenu.Instance.width);
            InkOptionsMenu.Instance.jumpTo(x, this._top, true);
        }, 0);
    }




    getColors = () => {
        return this._palette;
    }

    // @action
    // changeArrow = (arrowStart: string, arrowEnd: string) => {
    //     SetActiveArrowStart(arrowStart);
    //     SetActiveArrowEnd(arrowEnd);
    // }

    @action
    changeColor = (color: string, type: string) => {
        const col: ColorState = {
            hex: color, hsl: { a: 0, h: 0, s: 0, l: 0, source: "" }, hsv: { a: 0, h: 0, s: 0, v: 0, source: "" },
            rgb: { a: 0, r: 0, b: 0, g: 0, source: "" }, oldHue: 0, source: "",
        };
        if (type === "color") {
            SetActiveInkColor(Utils.colorString(col));
        } else if (type === "fill") {
            SetActiveFillColor(Utils.colorString(col));
        }
    }

    @action
    editProperties = (value: any, field: string) => {
        SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
            const doc = Document(element.rootDoc);
            if (doc.type === DocumentType.INK) {
                switch (field) {
                    case "width":
                        doc.strokeWidth = Number(value);
                        break;
                    case "color":
                        doc.color = String(value);
                        break;
                    case "fill":
                        doc.fillColor = String(value);
                        break;
                    case "bezier":
                        // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300;
                        break;
                    case "dash":
                        doc.strokeDash = Number(value);
                    default:
                        break;
                }
            }
        }));
    }


    @action
    changeBezier = (e: React.PointerEvent): void => {
        SetActiveBezierApprox(!ActiveInkBezierApprox() ? "300" : "");
        this.editProperties(0, "bezier");
    }
    @action
    changeDash = (e: React.PointerEvent): void => {
        SetActiveDash(ActiveDash() === "0" ? "2" : "0");
        this.editProperties(ActiveDash(), "strokeDash");
    }

    @computed get drawButtons() {
        const drawButtons = <div className="btn-draw" key="draw">
            {this._draw.map((icon, i) => {
                return <button
                    className="antimodeMenu-button"
                    key={icon}
                    title={this._title[i]}
                    onPointerDown={action(() => {
                        this._double = "";

                        if (this._selected !== i) {
                            this._selected = i;
                            Doc.SetSelectedTool(InkTool.Pen);
                            SetActiveArrowStart(this._head[i]);
                            SetActiveArrowEnd(this._end[i]);
                            SetActiveBezierApprox("300");

                            GestureOverlay.Instance.InkShape = this._shape[i];
                        } else {
                            this._selected = this._shapesNum;
                            Doc.SetSelectedTool(InkTool.None);
                            SetActiveArrowStart("");
                            SetActiveArrowEnd("");
                            GestureOverlay.Instance.InkShape = "";
                            SetActiveBezierApprox("0");

                        }
                        console.log(this._selected);

                    })}
                    onDoubleClick={action(() => {
                        console.log("double");
                        this._double = this._draw[i];
                        if (this._selected !== i) {
                            this._selected = i;
                            Doc.SetSelectedTool(InkTool.Pen);
                            SetActiveArrowStart(this._head[i]);
                            SetActiveArrowEnd(this._end[i]);
                            SetActiveBezierApprox("300");

                            GestureOverlay.Instance.InkShape = this._shape[i];
                        } else {
                            this._selected = this._shapesNum;
                            Doc.SetSelectedTool(InkTool.None);
                            SetActiveArrowStart("");
                            SetActiveArrowEnd("");
                            GestureOverlay.Instance.InkShape = "";
                            SetActiveBezierApprox("0");

                        }



                    })}
                    style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}>
                    <FontAwesomeIcon icon={this._faName[i] as IconProp} size="sm" />

                </button>;
            })}</div>;
        return drawButtons;
    }


    @computed get widthPicker() {
        var widthPicker = <button
            className="antimodeMenu-button"
            key="width"
            title="change width"
            onPointerDown={action(e => this._widthBtn = !this._widthBtn)}
            style={{ backgroundColor: this._widthBtn ? "121212" : "" }}>
            <FontAwesomeIcon icon="bars" size="lg" />
        </button>;
        if (this._widthBtn) {
            widthPicker = <div className="btn2-group" key="width">
                {widthPicker}
                {this._width.map((wid, i) => {
                    return <button
                        className="antimodeMenu-button"
                        key={wid}
                        onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })}
                        style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001, fontSize: this._dotsize[i], padding: 0, textAlign: "center" }}>
                        •
                    </button>;
                })}
            </div>;
        }
        return widthPicker;
    }



    @computed get colorPicker() {
        var colorPicker = <button
            className="antimodeMenu-button"
            key="color"
            title="Change Ink Color"
            onPointerDown={action(e => this._colorBtn = !this._colorBtn)}
            style={{ backgroundColor: this._colorBtn ? "121212" : "" }}>
            <FontAwesomeIcon icon="pen-nib" size="lg" />
            <div className="color-previewI" style={{ backgroundColor: ActiveInkColor() ?? "121212" }}></div>

        </button>;
        if (this._colorBtn) {
            colorPicker = <div className="btn-group" key="color">
                {colorPicker}
                {this._palette.map(color => {
                    return <button
                        className="antimodeMenu-button"
                        key={color}
                        onPointerDown={action(() => { this.changeColor(color, "color"); this._colorBtn = false; this.editProperties(color, "color"); })}
                        style={{ backgroundColor: this._colorBtn ? "121212" : "", zIndex: 1001 }}>
                        {/* <FontAwesomeIcon icon="pen-nib" size="lg" /> */}
                        <div className="color-previewII" style={{ backgroundColor: color }}></div>
                    </button>;
                })}
            </div>;
        }
        return colorPicker;
    }
    @computed get formatPane() {
        return <button className="antimodeMenu-button" key="format"
            title="toggle foramatting pane"
            onPointerDown={action(e => FormatShapePane.Instance.Pinned = !FormatShapePane.Instance.Pinned)}
            style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
            <FontAwesomeIcon icon="angle-double-right" size="lg" />
        </button>;
    }

    @computed get fillPicker() {
        var fillPicker = <button
            className="antimodeMenu-button"
            key="fill"
            title="Change Fill Color"
            onPointerDown={action(e => this._fillBtn = !this._fillBtn)}
            style={{ backgroundColor: this._fillBtn ? "121212" : "" }}>
            <FontAwesomeIcon icon="fill-drip" size="lg" />
            <div className="color-previewI" style={{ backgroundColor: ActiveFillColor() ?? "121212" }}></div>
        </button>;
        if (this._fillBtn) {
            fillPicker = <div className="btn-group" key="fill" >
                {fillPicker}
                {this._palette.map(color => {
                    return <button
                        className="antimodeMenu-button"
                        key={color}
                        onPointerDown={action(() => { this.changeColor(color, "fill"); this._fillBtn = false; this.editProperties(color, "fill"); })}
                        style={{ backgroundColor: this._fillBtn ? "121212" : "", zIndex: 1001 }}>
                        <div className="color-previewII" style={{ backgroundColor: color }}></div>
                    </button>;
                })}

            </div>;
        }
        return fillPicker;
    }


    @computed get bezierButton() {
        return <button
            className="antimodeMenu-button"
            title="Bezier changer"
            key="bezier"
            onPointerDown={e => this.changeBezier(e)}
            style={{ backgroundColor: ActiveInkBezierApprox() ? "121212" : "" }}>
            <FontAwesomeIcon icon="bezier-curve" size="lg" />

        </button>;
    }

    @computed get dashButton() {
        return <button
            className="antimodeMenu-button"
            title="dash changer"
            key="dash"
            onPointerDown={e => this.changeDash(e)}
            style={{ backgroundColor: ActiveDash() !== "0" ? "121212" : "" }}>
            <FontAwesomeIcon icon="ellipsis-h" size="lg" />

        </button>;
    }

    render() {
        const buttons = [

            this.drawButtons,
            this.widthPicker,
            this.colorPicker,
            this.fillPicker,


            this.formatPane,

            <button className="antimodeMenu-button" key="pin menu" title="Pin menu" onClick={this.toggleMenuPin} style={{ backgroundColor: this.Pinned ? "#121212" : "", display: this.collapsed ? "none" : undefined }}>
                <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} />
            </button>
        ];

        // return this.getElement(buttons);
        return this.getElement(buttons);
    }
}
Scripting.addGlobal(function activatePen(penBtn: any) {
    if (penBtn) {
        InkOptionsMenu.Instance.jumpTo(300, 300);
        InkOptionsMenu.Instance.Pinned = true;
    } else {
        InkOptionsMenu.Instance.Pinned = false;
        InkOptionsMenu.Instance.fadeOut(true);
    }
});
