/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.BoxShadowEditor = class BoxShadowEditor extends WI.Object
{
    constructor()
    {
        super();

        this._element = document.createElement("div");
        this._element.classList.add("box-shadow-editor");

        let tableElement = this._element.appendChild(document.createElement("table"));

        function createInputRow(identifier, label) {
            let id = `box-shadow-editor-${identifier}-input`;

            let rowElement = tableElement.appendChild(document.createElement("tr"));
            rowElement.className = identifier;

            let headerElement = rowElement.appendChild(document.createElement("th"));

            let labelElement = headerElement.appendChild(document.createElement("label"));
            labelElement.setAttribute("for", id);
            labelElement.textContent = label;

            let dataElement = rowElement.appendChild(document.createElement("td"));

            let inputElement = dataElement.appendChild(document.createElement("input"));
            inputElement.id = id;
            return {rowElement, inputElement};
        }

        function createSlider(rowElement, min, max) {
            let dataElement = rowElement.appendChild(document.createElement("td"));

            let rangeElement = dataElement.appendChild(document.createElement("input"));
            rangeElement.type = "range";
            rangeElement.min = min;
            rangeElement.max = max;
            return rangeElement;
        }

        let offsetXRow = createInputRow("offset-x", WI.UIString("Offset X", "Offset X @ Box Shadow Editor", "Input label for the x-axis of the offset of a CSS box shadow"));

        this._offsetXInput = offsetXRow.inputElement;
        this._offsetXInput.type = "text"
        this._offsetXInput.addEventListener("input", this._handleOffsetXInputInput.bind(this));
        this._offsetXInput.addEventListener("keydown", this._handleOffsetXInputKeyDown.bind(this));

        let offsetSliderDataElement = offsetXRow.rowElement.appendChild(document.createElement("td"));
        offsetSliderDataElement.setAttribute("rowspan", 3);

        this._offsetSliderKnobRadius = 5; // keep in sync with `.box-shadow-editor > table > tr > td > svg circle`
        this._offsetSliderAreaSize = 100;

        const offsetSliderContainerSize = this._offsetSliderAreaSize + (this._offsetSliderKnobRadius * 2);

        this._offsetSliderSVG = offsetSliderDataElement.appendChild(createSVGElement("svg"));
        this._offsetSliderSVG.setAttribute("tabindex", 0);
        this._offsetSliderSVG.setAttribute("width", offsetSliderContainerSize);
        this._offsetSliderSVG.setAttribute("height", offsetSliderContainerSize);
        this._offsetSliderSVG.addEventListener("mousedown", this);
        this._offsetSliderSVG.addEventListener("keydown", this);

        this._offsetSliderSVGMouseDownPoint = null;

        let offsetSliderGroup = this._offsetSliderSVG.appendChild(createSVGElement("g"));
        offsetSliderGroup.setAttribute("transform", `translate(${this._offsetSliderKnobRadius}, ${this._offsetSliderKnobRadius})`);

        let offsetSliderXAxisLine = offsetSliderGroup.appendChild(createSVGElement("line"));
        offsetSliderXAxisLine.classList.add("axis");
        offsetSliderXAxisLine.setAttribute("x1", this._offsetSliderAreaSize / 2);
        offsetSliderXAxisLine.setAttribute("y1", 0);
        offsetSliderXAxisLine.setAttribute("x2", this._offsetSliderAreaSize / 2);
        offsetSliderXAxisLine.setAttribute("y2", this._offsetSliderAreaSize);

        let offsetSliderYAxisLine = offsetSliderGroup.appendChild(createSVGElement("line"));
        offsetSliderYAxisLine.classList.add("axis");
        offsetSliderYAxisLine.setAttribute("x1", 0);
        offsetSliderYAxisLine.setAttribute("y1", this._offsetSliderAreaSize / 2);
        offsetSliderYAxisLine.setAttribute("x2", this._offsetSliderAreaSize);
        offsetSliderYAxisLine.setAttribute("y2", this._offsetSliderAreaSize / 2);

        this._offsetSliderLine = offsetSliderGroup.appendChild(createSVGElement("line"));
        this._offsetSliderLine.setAttribute("x1", this._offsetSliderAreaSize / 2);
        this._offsetSliderLine.setAttribute("y1", this._offsetSliderAreaSize / 2);

        this._offsetSliderKnob = offsetSliderGroup.appendChild(createSVGElement("circle"));

        let offsetYRow = createInputRow("offset-y", WI.UIString("Offset Y", "Offset Y @ Box Shadow Editor", "Input label for the y-axis of the offset of a CSS box shadow"));

        this._offsetYInput = offsetYRow.inputElement;
        this._offsetYInput.type = "text"
        this._offsetYInput.addEventListener("input", this._handleOffsetYInputInput.bind(this));
        this._offsetYInput.addEventListener("keydown", this._handleOffsetYInputKeyDown.bind(this));

        let insetRow = createInputRow("inset", WI.UIString("Inset", "Inset @ Box Shadow Editor", "Checkbox label for the inset of a CSS box shadow."));

        this._insetCheckbox = insetRow.inputElement;
        this._insetCheckbox.type = "checkbox";
        this._insetCheckbox.addEventListener("change", this._handleInsetCheckboxChange.bind(this));

        let blurRadiusRow = createInputRow("blur-radius", WI.UIString("Blur", "Blur @ Box Shadow Editor", "Input label for the blur radius of a CSS box shadow"));

        this._blurRadiusInput = blurRadiusRow.inputElement;
        this._blurRadiusInput.type = "text"
        this._blurRadiusInput.addEventListener("input", this._handleBlurRadiusInputInput.bind(this));
        this._blurRadiusInput.addEventListener("keydown", this._handleBlurRadiusInputKeyDown.bind(this));
        this._blurRadiusInput.min = 0;

        this._blurRadiusSlider = createSlider(blurRadiusRow.rowElement, 0, 100);
        this._blurRadiusSlider.addEventListener("input", this._handleBlurRadiusSliderInput.bind(this));

        let spreadRadiusRow = createInputRow("spread-radius", WI.UIString("Spread", "Spread @ Box Shadow Editor", "Input label for the spread radius of a CSS box shadow"));

        this._spreadRadiusInput = spreadRadiusRow.inputElement;
        this._spreadRadiusInput.type = "text"
        this._spreadRadiusInput.addEventListener("input", this._handleSpreadRadiusInputInput.bind(this));
        this._spreadRadiusInput.addEventListener("keydown", this._handleSpreadRadiusInputKeyDown.bind(this));

        this._spreadRadiusSlider = createSlider(spreadRadiusRow.rowElement, -50, 50);
        this._spreadRadiusSlider.addEventListener("input", this._handleSpreadRadiusSliderInput.bind(this));

        this._colorPicker = new WI.ColorPicker;
        this._colorPicker.addEventListener(WI.ColorPicker.Event.ColorChanged, this._handleColorChanged, this);
        this._element.appendChild(this._colorPicker.element);

        this.boxShadow = new WI.BoxShadow;

        WI.addWindowKeydownListener(this);
    }

    // Public

    get element() { return this._element; }

    get boxShadow()
    {
        return this._boxShadow;
    }

    set boxShadow(boxShadow)
    {
        console.assert(boxShadow instanceof WI.BoxShadow);

        this._boxShadow = boxShadow;

        let offsetX = this._boxShadow?.offsetX || {value: 0, unit: ""};
        let offsetY = this._boxShadow?.offsetY || {value: 0, unit: ""};
        this._offsetXInput.value = offsetX.value + offsetX.unit;
        this._offsetYInput.value = offsetY.value + offsetY.unit;

        let offsetSliderCenter = this._offsetSliderAreaSize / 2;
        let offsetSliderX = Number.constrain(offsetX.value + offsetSliderCenter, 0, this._offsetSliderAreaSize);
        let offsetSliderY = Number.constrain(offsetY.value + offsetSliderCenter, 0, this._offsetSliderAreaSize);

        this._offsetSliderLine.setAttribute("x2", offsetSliderX);
        this._offsetSliderKnob.setAttribute("cx", offsetSliderX);

        this._offsetSliderLine.setAttribute("y2", offsetSliderY);
        this._offsetSliderKnob.setAttribute("cy", offsetSliderY);

        let blurRadius = this._boxShadow?.blurRadius || {value: 0, unit: ""};
        this._blurRadiusInput.value = blurRadius.value + blurRadius.unit;
        this._blurRadiusSlider.value = blurRadius.value;

        let spreadRadius = this._boxShadow?.spreadRadius || {value: 0, unit: ""};
        this._spreadRadiusInput.value = spreadRadius.value + spreadRadius.unit;
        this._spreadRadiusSlider.value = spreadRadius.value;

        let inset = this._boxShadow?.inset || false;
        this._insetCheckbox.checked = inset;

        let color = this._boxShadow?.color || WI.Color.fromString("transparent");
        this._colorPicker.color = color;
    }

    // Protected

    handleEvent(event)
    {
        switch (event.type) {
        case "keydown":
            console.assert(event.target === this._offsetSliderSVG);
            this._handleOffsetSliderSVGKeyDown(event);
            return;

        case "mousedown":
            console.assert(event.target === this._offsetSliderSVG);
            this._handleOffsetSliderSVGMouseDown(event);
            return;

        case "mousemove":
            this._handleWindowMouseMove(event);
            return;

        case "mouseup":
            this._handleWindowMouseUp(event);
            return;
        }

        console.assert();
    }

    // Private

    _updateBoxShadow({offsetX, offsetY, blurRadius, spreadRadius, inset, color})
    {
        let change = false;

        if (!offsetX)
            offsetX = this._boxShadow.offsetX;
        else if (!Object.shallowEqual(offsetX, this._boxShadow.offsetX))
            change = true;

        if (!offsetY)
            offsetY = this._boxShadow.offsetY;
        else if (!Object.shallowEqual(offsetY, this._boxShadow.offsetY))
            change = true;

        if (!blurRadius)
            blurRadius = this._boxShadow.blurRadius;
        else if (!Object.shallowEqual(blurRadius, this._boxShadow.blurRadius))
            change = true;

        if (!spreadRadius)
            spreadRadius = this._boxShadow.spreadRadius;
        else if (!Object.shallowEqual(spreadRadius, this._boxShadow.spreadRadius))
            change = true;

        if (inset === undefined)
            inset = this._boxShadow.inset;
        else if (inset !== this._boxShadow.inset)
            change = true;

        if (!color)
            color = this._boxShadow.color;
        else if (color.toString() !== this._boxShadow.color?.toString())
            change = true;

        if (!change)
            return;

        this.boxShadow = new WI.BoxShadow(offsetX, offsetY, blurRadius, spreadRadius, inset, color);

        this.dispatchEventToListeners(WI.BoxShadowEditor.Event.BoxShadowChanged, {boxShadow: this._boxShadow});
    }

    _updateBoxShadowOffsetFromSliderMouseEvent(event, saveMouseDownPoint)
    {
        let point = WI.Point.fromEventInElement(event, this._offsetSliderSVG);
        point.x = Number.constrain(point.x - this._offsetSliderKnobRadius, 0, this._offsetSliderAreaSize);
        point.y = Number.constrain(point.y - this._offsetSliderKnobRadius, 0, this._offsetSliderAreaSize);

        if (saveMouseDownPoint)
            this._offsetSliderSVGMouseDownPoint = point;

        if (event.shiftKey && this._offsetSliderSVGMouseDownPoint) {
            if (Math.abs(this._offsetSliderSVGMouseDownPoint.x - point.x) > Math.abs(this._offsetSliderSVGMouseDownPoint.y - point.y))
                point.y = this._offsetSliderSVGMouseDownPoint.y;
            else
                point.x = this._offsetSliderSVGMouseDownPoint.x;
        }

        let offsetSliderCenter = this._offsetSliderAreaSize / 2;

        this._updateBoxShadow({
            offsetX: {
                value: point.x - offsetSliderCenter,
                unit: this._boxShadow.offsetX.unit,
            },
            offsetY: {
                value: point.y - offsetSliderCenter,
                unit: this._boxShadow.offsetY.unit,
            },
        });
    }

    _determineShiftForEvent(event)
    {
        let shift = 0;
        if (event.key === "ArrowUp")
            shift = 1;
        else if (event.key === "ArrowDown")
            shift = -1;

        if (!shift)
            return NaN;

        if (event.metaKey)
            shift *= 100;
        else if (event.shiftKey)
            shift *= 10;
        else if (event.altKey)
            shift /= 10;

        event.preventDefault();

        return shift;
    }

    _handleOffsetSliderSVGKeyDown(event) {
        let shiftX = 0;
        let shiftY = 0;

        switch (event.keyCode) {
        case WI.KeyboardShortcut.Key.Up.keyCode:
            shiftY = -1;
            break;

        case WI.KeyboardShortcut.Key.Right.keyCode:
            shiftX = 1;
            break;

        case WI.KeyboardShortcut.Key.Down.keyCode:
            shiftY = 1;
            break;

        case WI.KeyboardShortcut.Key.Left.keyCode:
            shiftX = -1;
            break;
        }

        if (!shiftX && !shiftY)
            return false;

        let multiplier = 1;

        if (event.shiftKey)
            multiplier = 10;
        else if (event.altKey)
            multiplier = 0.1;

        shiftX *= multiplier;
        shiftY *= multiplier;

        let offsetValueLimit = this._offsetSliderAreaSize / 2;

        this._updateBoxShadow({
            offsetX: {
                value: Number.constrain(this._boxShadow.offsetX.value + shiftX, -1 * offsetValueLimit, offsetValueLimit).maxDecimals(1),
                unit: this._boxShadow.offsetX.unit,
            },
            offsetY: {
                value: Number.constrain(this._boxShadow.offsetY.value + shiftY, -1 * offsetValueLimit, offsetValueLimit).maxDecimals(1),
                unit: this._boxShadow.offsetY.unit,
            },
        });

    }

    _handleOffsetSliderSVGMouseDown(event)
    {
        if (event.button !== 0)
            return;

        event.stop();

        this._offsetSliderSVG.focus();

        window.addEventListener("mousemove", this, true);
        window.addEventListener("mouseup", this, true);

        this._updateBoxShadowOffsetFromSliderMouseEvent(event, true);
    }

    _handleWindowMouseMove(event)
    {
        this._updateBoxShadowOffsetFromSliderMouseEvent(event);
    }

    _handleWindowMouseUp(event)
    {
        this._offsetSliderSVGMouseDownPoint = null;

        window.removeEventListener("mousemove", this, true);
        window.removeEventListener("mouseup", this, true);
    }

    _handleOffsetXInputInput(event)
    {
        this._updateBoxShadow({
            offsetX: WI.BoxShadow.parseNumberComponent(this._offsetXInput.value),
        });
    }

    _handleOffsetXInputKeyDown(event)
    {
        let shift = this._determineShiftForEvent(event);
        if (isNaN(shift))
            return;

        this._updateBoxShadow({
            offsetX: {
                value: (this._boxShadow.offsetX.value + shift).maxDecimals(1),
                unit: this._boxShadow.offsetX.unit,
            },
        });
    }

    _handleOffsetYInputInput(event)
    {
        this._updateBoxShadow({
            offsetY: WI.BoxShadow.parseNumberComponent(this._offsetYInput.value),
        });
    }

    _handleOffsetYInputKeyDown(event)
    {
        let shift = this._determineShiftForEvent(event);
        if (isNaN(shift))
            return;

        this._updateBoxShadow({
            offsetY: {
                value: (this._boxShadow.offsetY.value + shift).maxDecimals(1),
                unit: this._boxShadow.offsetY.unit,
            },
        });
    }

    _handleBlurRadiusInputInput(event)
    {
        this._updateBoxShadow({
            blurRadius: WI.BoxShadow.parseNumberComponent(this._blurRadiusInput.value),
        });
    }

    _handleBlurRadiusInputKeyDown(event)
    {
        let shift = this._determineShiftForEvent(event);
        if (isNaN(shift))
            return;

        this._updateBoxShadow({
            blurRadius: {
                value: (this._boxShadow.blurRadius.value + shift).maxDecimals(1),
                unit: this._boxShadow.blurRadius.unit,
            }
        });
    }

    _handleBlurRadiusSliderInput(event)
    {
        this._updateBoxShadow({
            blurRadius: {
                value: this._blurRadiusSlider.valueAsNumber,
                unit: this._boxShadow.blurRadius.unit,
            }
        });
    }

    _handleSpreadRadiusInputInput(event)
    {
        this._updateBoxShadow({
            spreadRadius: WI.BoxShadow.parseNumberComponent(this._spreadRadiusInput.value),
        });
    }

    _handleSpreadRadiusInputKeyDown(event)
    {
        let shift = this._determineShiftForEvent(event);
        if (isNaN(shift))
            return;

        this._updateBoxShadow({
            spreadRadius: {
                value: (this._boxShadow.spreadRadius.value + shift).maxDecimals(1),
                unit: this._boxShadow.spreadRadius.unit,
            }
        });
    }

    _handleSpreadRadiusSliderInput(event)
    {
        this._updateBoxShadow({
            spreadRadius: {
                value: this._spreadRadiusSlider.valueAsNumber,
                unit: this._boxShadow.spreadRadius.unit,
            }
        });
    }

    _handleInsetCheckboxChange(event)
    {
        this._updateBoxShadow({
            inset: !!this._insetCheckbox.checked,
        });
    }

    _handleColorChanged(event)
    {
        this._updateBoxShadow({
            color: this._colorPicker.color,
        });
    }
};

WI.BoxShadowEditor.Event = {
    BoxShadowChanged: "box-shadow-editor-box-shadow-changed"
};
