import { computeIsoscelesTriangleApexAngle } from "../../../core/math/computeIsoscelesTriangleApexAngle.js";
import dom from "../../DOM.js";
import SVG from "../../SVG.js";
import View from "../../View.js";
import { RadialText } from "./RadialText.js";

const PI2 = Math.PI * 2;

const elementPrototype = (function () {
    const svgElement = SVG.createElement("path");
    svgElement.setAttribute("fill", "rgba(255,0,0,0.5)");
    return svgElement;
})();

class RadialMenuElement extends View {
    /**
     *
     * @param {RadialMenuElementDefinition} description
     */
    constructor(description) {
        super();

        /**
         *
         * @type {RadialMenuElementDefinition}
         */
        this.description = description;

        const self = this;

        let dRoot = dom().addClass("ui-radial-menu-element");

        this.el = dRoot.el;

        if (description.cssClass !== null) {
            this.addClass(description.cssClass);
        }

        const elSvg = SVG.createElement("svg");
        const elArc = SVG.createElement("g");
        const elPath = elementPrototype.cloneNode(true);

        this.elPath = elPath;
        elSvg.appendChild(elArc);
        elArc.appendChild(elPath);

        elPath.classList.add("backdrop");
        elPath.setAttribute("fill", this.description.fill);

        const iconSize = description.iconSize;
        const outerRadius = description.outerRadius;


        dRoot.append(elSvg);

        if (description.autoSizeIcon === false) {
            description.iconView.size.set(iconSize, iconSize);
        }

        this.radialText = new RadialText({
                                             share: description.share,
                                             offset: description.offset,
                                             fill: description.nameFill,
                                             radius: outerRadius + description.nameRadiusOffset
                                         });

        this.radialText.setText(description.name);

        this.addChild(this.radialText);
        this.addChild(description.iconView);
    }

    /**
     *
     * @returns {number}
     */
    get iconSize() {
        return this.description.iconSize;
    }

    /**
     *
     * @param {number} v
     */
    set iconSize(v) {
        this.description.iconSize = v;
        this.updateIcon();
    }

    /**
     *
     * @returns {number}
     */
    get innerRadius() {
        return this.description.innerRadius;
    }

    /**
     *
     * @param {number} v
     */
    set innerRadius(v) {
        this.description.innerRadius = v;
        this.render();
    }

    /**
     *
     * @returns {number}
     */
    get outerRadius() {
        return this.description.outerRadius;
    }

    /**
     *
     * @param {number} v
     */
    set outerRadius(v) {
        this.description.outerRadius = v;
        this.render();
    }

    updateIcon() {

        const description = this.description;

        const vIcon = description.iconView;

        const outerRadius = this.outerRadius;
        const innerRadius = this.innerRadius;

        let iconSize;

        if (description.autoSizeIcon) {

            iconSize = (outerRadius - innerRadius) / Math.SQRT2;
            vIcon.size.set(iconSize, iconSize);

        } else {

            iconSize = Math.max(vIcon.size.x, vIcon.size.y);

        }

        const a0 = description.offset * PI2;
        const a1 = a0 + description.share * PI2;

        const aMid = (a1 + a0) / 2;

        const cm = Math.cos(aMid);
        const sm = Math.sin(aMid);

        const r = (innerRadius + outerRadius) / 2;

        const iconMidX = cm * r;
        const iconMidY = sm * r;

        const x = iconMidX - iconSize / 2;
        const y = iconMidY - iconSize / 2;


        vIcon.position.set(x, y);
    }

    render() {
        const description = this.description;

        const padding = description.padding;

        const padding_2 = padding / 2;

        //compute padding angle for inner and outer arcs
        const outerRadius = this.outerRadius;
        const innerRadius = this.innerRadius;

        const outerArcPadding = computeIsoscelesTriangleApexAngle(outerRadius, padding_2);
        const innerArcPadding = computeIsoscelesTriangleApexAngle(innerRadius, padding_2);

        //compute wedge bounds of the element
        const a0 = description.offset * PI2;
        const a1 = a0 + description.share * PI2;

        //compute inner and outer arcs for rendered element
        const innerStart = a0 + innerArcPadding;
        const innerEnd = a1 - innerArcPadding;

        const outerStart = a0 + outerArcPadding;
        const outerEnd = a1 - outerArcPadding;

        //draw arc
        this.elPath.setAttribute("d", SVG.svgArc2(innerRadius, outerRadius, innerStart, innerEnd, outerStart, outerEnd));

        this.radialText.radius = outerRadius + description.nameRadiusOffset;
        this.radialText.share = description.share;
        this.radialText.offset = description.offset;
        this.radialText.render();


        //update icon position
        this.updateIcon();
    }
}


export default RadialMenuElement;
