/*
 * Copyright (C) 2015 Apple Inc. All rights reserved.
 * Copyright (C) 2016 Devin Rousso <webkit@devinrousso.com>. 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.InlineSwatch = class InlineSwatch extends WI.Object
{
    constructor(type, value, readOnly)
    {
        super();

        this._type = type;

        switch (this._type) {
        case WI.InlineSwatch.Type.Bezier:
        case WI.InlineSwatch.Type.Spring:
            this._swatchElement = WI.ImageUtilities.useSVGSymbol("Images/CubicBezier.svg");
            break;

        case WI.InlineSwatch.Type.BoxShadow:
            this._swatchElement = WI.ImageUtilities.useSVGSymbol("Images/BoxShadow.svg");
            break;

        case WI.InlineSwatch.Type.Variable:
            this._swatchElement = WI.ImageUtilities.useSVGSymbol("Images/CSSVariable.svg");
            break;

        default:
            this._swatchElement = document.createElement("span");
            break;
        }

        this._swatchElement.classList.add("inline-swatch", this._type.replace("inline-swatch-type-", ""));

        if (readOnly)
            this._swatchElement.classList.add("read-only");
        else {
            switch (this._type) {
            case WI.InlineSwatch.Type.Bezier:
                this._swatchElement.title = WI.UIString("Edit \u201Ccubic-bezier\u201D function");
                break;

            case WI.InlineSwatch.Type.BoxShadow:
                this._swatchElement.title = WI.UIString("Edit \u201Cbox-shadow\u201D");
                break;

            case WI.InlineSwatch.Type.Color:
                this._shiftClickColorEnabled = true;
                // Handled later by _updateSwatch.
                break;

            case WI.InlineSwatch.Type.Alignment:
                // Handled later by _updateSwatch.
                break;

            case WI.InlineSwatch.Type.Gradient:
                this._swatchElement.title = WI.UIString("Edit custom gradient");
                break;

            case WI.InlineSwatch.Type.Image:
                this._swatchElement.title = WI.UIString("View Image");
                break;

            case WI.InlineSwatch.Type.Spring:
                this._swatchElement.title = WI.UIString("Edit \u201Cspring\u201D function");
                break;

            case WI.InlineSwatch.Type.Variable:
                this._swatchElement.title = WI.UIString("Click to view variable value\nShift-click to replace variable with value");
                break;

            default:
                WI.reportInternalError(`Unknown InlineSwatch type "${type}"`);
                break;
            }

            this._swatchElement.addEventListener("click", this._swatchElementClicked.bind(this));
            if (this._type === WI.InlineSwatch.Type.Color)
                this._swatchElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this));
        }

        this._swatchInnerElement = this._swatchElement.createChild("span");

        this._value = value || this._fallbackValue();
        this._valueEditor = null;
        this._readOnly = readOnly;

        this._updateSwatch();
    }

    // Public

    get element()
    {
        return this._swatchElement;
    }

    get value()
    {
        if (typeof this._value === "function")
            return this._value();
        return this._value;
    }

    set value(value)
    {
        this._value = value;
        this._updateSwatch(true);
    }

    set shiftClickColorEnabled(value)
    {
        this._shiftClickColorEnabled = !!value;
        this._updateSwatch(true);
    }

    // Popover delegate

    didDismissPopover(popover)
    {
        if (!this._valueEditor)
            return;

        if (this._valueEditor.removeListeners)
            this._valueEditor.removeListeners();

        if (this._valueEditor instanceof WI.BezierEditor)
            this._valueEditor.removeEventListener(WI.BezierEditor.Event.BezierChanged, this._valueEditorValueDidChange, this);
        else if (this._valueEditor instanceof WI.BoxShadowEditor)
            this._valueEditor.removeEventListener(WI.BoxShadowEditor.Event.BoxShadowChanged, this._valueEditorValueDidChange, this);
        else if (this._valueEditor instanceof WI.ColorPicker)
            this._valueEditor.removeEventListener(WI.ColorPicker.Event.ColorChanged, this._valueEditorValueDidChange, this);
        else if (this._valueEditor instanceof WI.GradientEditor)
            this._valueEditor.removeEventListener(WI.GradientEditor.Event.GradientChanged, this._valueEditorValueDidChange, this);
        else if (this._valueEditor instanceof WI.SpringEditor)
            this._valueEditor.removeEventListener(WI.SpringEditor.Event.SpringChanged, this._valueEditorValueDidChange, this);
        else if (this._valueEditor instanceof WI.AlignmentEditor)
            this._valueEditor.removeEventListener(WI.AlignmentEditor.Event.ValueChanged, this._valueEditorValueDidChange, this);

        this._valueEditor = null;

        this.dispatchEventToListeners(WI.InlineSwatch.Event.Deactivated);
    }

    // Private

    _fallbackValue()
    {
        switch (this._type) {
        case WI.InlineSwatch.Type.Bezier:
            return WI.CubicBezier.fromString("linear");
        case WI.InlineSwatch.Type.BoxShadow:
            return WI.BoxShadow.fromString("none");
        case WI.InlineSwatch.Type.Color:
            return WI.Color.fromString("white");
        case WI.InlineSwatch.Type.Gradient:
            return WI.Gradient.fromString("linear-gradient(transparent, transparent)");
        case WI.InlineSwatch.Type.Spring:
            return WI.Spring.fromString("1 100 10 0");
        default:
            return null;
        }
    }

    _updateSwatch(dontFireEvents)
    {
        let value = this.value;

        switch (this._type) {
        case WI.InlineSwatch.Type.Color:
            if (this._allowChangingColorFormats())
                this._swatchElement.title = WI.UIString("Click to select a color\nShift-click to switch color formats");
            else
                this._swatchElement.title = WI.UIString("Click to select a color");
            // fallthrough

        case WI.InlineSwatch.Type.Gradient:
            this._swatchInnerElement.style.background = value ? value.toString() : null;
            break;

        case WI.InlineSwatch.Type.Image:
            this._swatchInnerElement.style.setProperty("background-image", `url(${value.src})`);
            break;

        case WI.InlineSwatch.Type.Alignment:
            this._swatchInnerElement.style.backgroundImage = `url(${WI.AlignmentEditor.glyphPath(value)})`;
            this._swatchInnerElement.classList.toggle("rotate-left", WI.AlignmentEditor.shouldRotateGlyph(value.type));
            break;
        }

        if (!dontFireEvents)
            this.dispatchEventToListeners(WI.InlineSwatch.Event.ValueChanged, {value});
    }

    _allowChangingColorFormats()
    {
        return this._shiftClickColorEnabled && !this._readOnly && !this.value.isOutsideSRGB();
    }

    _swatchElementClicked(event)
    {
        event.stop();

        let value = this.value;

        if (event.shiftKey && value) {
            if (this._type === WI.InlineSwatch.Type.Color) {
                if (!this._allowChangingColorFormats()) {
                    InspectorFrontendHost.beep();
                    return;
                }

                let nextFormat = value.nextFormat();
                console.assert(nextFormat);
                if (nextFormat) {
                    value.format = nextFormat;
                    this._updateSwatch();
                }
                return;
            }

            if (this._type === WI.InlineSwatch.Type.Variable) {
                // Force the swatch to replace the displayed text with the variable's value.
                this._swatchElement.remove();
                this._updateSwatch();
                return;
            }
        }

        if (this._valueEditor)
            return;

        if (!value)
            value = this._fallbackValue();

        let popover = new WI.Popover(this);

        popover.windowResizeHandler = () => {
            this._presentPopover(popover);
        };

        this._valueEditor = null;
        switch (this._type) {
        case WI.InlineSwatch.Type.Bezier:
            this._valueEditor = new WI.BezierEditor;
            this._valueEditor.addEventListener(WI.BezierEditor.Event.BezierChanged, this._valueEditorValueDidChange, this);
            break;

        case WI.InlineSwatch.Type.BoxShadow:
            this._valueEditor = new WI.BoxShadowEditor;
            this._valueEditor.addEventListener(WI.BoxShadowEditor.Event.BoxShadowChanged, this._valueEditorValueDidChange, this);
            break;

        case WI.InlineSwatch.Type.Color:
            this._valueEditor = new WI.ColorPicker;
            this._valueEditor.addEventListener(WI.ColorPicker.Event.ColorChanged, this._valueEditorValueDidChange, this);
            break;

        case WI.InlineSwatch.Type.Gradient:
            this._valueEditor = new WI.GradientEditor;
            this._valueEditor.addEventListener(WI.GradientEditor.Event.GradientChanged, this._valueEditorValueDidChange, this);
            this._valueEditor.addEventListener(WI.GradientEditor.Event.ColorPickerToggled, function(event) {
                this.update();
            }, popover);
            break;

        case WI.InlineSwatch.Type.Image:
            if (value.src) {
                this._valueEditor = {};
                this._valueEditor.element = document.createElement("img");
                this._valueEditor.element.src = value.src;
                this._valueEditor.element.classList.add("show-grid");
                this._valueEditor.element.style.setProperty("max-width", "50vw");
                this._valueEditor.element.style.setProperty("max-height", "50vh");
            }
            break;

        case WI.InlineSwatch.Type.Spring:
            this._valueEditor = new WI.SpringEditor;
            this._valueEditor.addEventListener(WI.SpringEditor.Event.SpringChanged, this._valueEditorValueDidChange, this);
            break;

        case WI.InlineSwatch.Type.Alignment:
            // FIXME: <https://webkit.org/b/233055> Web Inspector: Add a swatch for justify-content, justify-items, and justify-self
            this._valueEditor = new WI.AlignmentEditor;
            this._valueEditor.alignment = value;
            this._valueEditor.addEventListener(WI.AlignmentEditor.Event.ValueChanged, this._valueEditorValueDidChange, this);
            break;

        case WI.InlineSwatch.Type.Variable:
            this._valueEditor = {};

            this._valueEditor.element = document.createElement("div");
            this._valueEditor.element.classList.add("inline-swatch-variable-popover");

            this._valueEditor.codeMirror = WI.CodeMirrorEditor.create(this._valueEditor.element, {
                mode: "css",
                readOnly: true,
            });
            this._valueEditor.codeMirror.on("update", () => {
                popover.update();
            });
            break;
        }

        if (!this._valueEditor)
            return;

        popover.content = this._valueEditor.element;
        this._presentPopover(popover);

        this.dispatchEventToListeners(WI.InlineSwatch.Event.Activated);

        switch (this._type) {
        case WI.InlineSwatch.Type.Bezier:
            this._valueEditor.bezier = value;
            break;

        case WI.InlineSwatch.Type.BoxShadow:
            this._valueEditor.boxShadow = value;
            break;

        case WI.InlineSwatch.Type.Color:
            this._valueEditor.color = value;
            this._valueEditor.focus();
            break;

        case WI.InlineSwatch.Type.Gradient:
            this._valueEditor.gradient = value;
            break;

        case WI.InlineSwatch.Type.Spring:
            this._valueEditor.spring = value;
            break;

        case WI.InlineSwatch.Type.Variable: {
            let codeMirror = this._valueEditor.codeMirror;
            codeMirror.setValue(value);

            const range = null;
            function optionsForType(type) {
                return {
                    allowedTokens: /\btag\b/,
                    callback(marker, valueObject, valueString) {
                        let swatch = new WI.InlineSwatch(type, valueObject, true);
                        codeMirror.setUniqueBookmark({line: 0, ch: 0}, swatch.element);
                    }
                };
            }
            createCodeMirrorColorTextMarkers(codeMirror, range, optionsForType(WI.InlineSwatch.Type.Color));
            createCodeMirrorGradientTextMarkers(codeMirror, range, optionsForType(WI.InlineSwatch.Type.Gradient));
            createCodeMirrorCubicBezierTextMarkers(codeMirror, range, optionsForType(WI.InlineSwatch.Type.Bezier));
            createCodeMirrorSpringTextMarkers(codeMirror, range, optionsForType(WI.InlineSwatch.Type.Spring));
            break;
        }
        }
    }

    _valueEditorValueDidChange(event)
    {
        switch (this._type) {
        case WI.InlineSwatch.Type.BoxShadow:
            this._value = event.data.boxShadow;
            break;

        case WI.InlineSwatch.Type.Bezier:
            this._value = event.data.bezier;
            break;

        case WI.InlineSwatch.Type.Color:
            this._value = event.data.color;
            break;

        case WI.InlineSwatch.Type.Gradient:
            this._value = event.data.gradient;
            break;

        case WI.InlineSwatch.Type.Spring:
            this._value = event.data.spring;
            break;

        case WI.InlineSwatch.Type.Alignment:
            this._value = event.data.alignment;
            break;
        }

        this._updateSwatch();
    }

    _presentPopover(popover)
    {
        let bounds = WI.Rect.rectFromClientRect(this._swatchElement.getBoundingClientRect());
        popover.present(bounds.pad(2), [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_Y, WI.RectEdge.MIN_X]);
    }

    _handleContextMenuEvent(event)
    {
        let value = this.value;
        if (!value)
            return;

        let contextMenu = WI.ContextMenu.createFromEvent(event);
        let isColorOutsideSRGB = value.isOutsideSRGB();

        if (!isColorOutsideSRGB) {
            if (value.isKeyword() && value.format !== WI.Color.Format.Keyword) {
                contextMenu.appendItem(WI.UIString("Format: Keyword"), () => {
                    value.format = WI.Color.Format.Keyword;
                    this._updateSwatch();
                });
            }

            let hexInfo = this._getNextValidHEXFormat();
            if (hexInfo) {
                contextMenu.appendItem(hexInfo.title, () => {
                    value.format = hexInfo.format;
                    this._updateSwatch();
                });
            }

            if (value.simple && value.format !== WI.Color.Format.HSL) {
                contextMenu.appendItem(WI.UIString("Format: HSL"), () => {
                    value.format = WI.Color.Format.HSL;
                    this._updateSwatch();
                });
            } else if (value.format !== WI.Color.Format.HSLA) {
                contextMenu.appendItem(WI.UIString("Format: HSLA"), () => {
                    value.format = WI.Color.Format.HSLA;
                    this._updateSwatch();
                });
            }

            if (value.simple && value.format !== WI.Color.Format.RGB) {
                contextMenu.appendItem(WI.UIString("Format: RGB"), () => {
                    value.format = WI.Color.Format.RGB;
                    this._updateSwatch();
                });
            } else if (value.format !== WI.Color.Format.RGBA) {
                contextMenu.appendItem(WI.UIString("Format: RGBA"), () => {
                    value.format = WI.Color.Format.RGBA;
                    this._updateSwatch();
                });
            }

            if (value.format !== WI.Color.Format.ColorFunction) {
                contextMenu.appendItem(WI.UIString("Format: Color Function"), () => {
                    value.format = WI.Color.Format.ColorFunction;
                    this._updateSwatch();
                });
            }

            contextMenu.appendSeparator();
        }

        if (value.gamut !== WI.Color.Gamut.DisplayP3) {
            contextMenu.appendItem(WI.UIString("Convert to Display-P3"), () => {
                value.gamut = WI.Color.Gamut.DisplayP3;
                this._updateSwatch();
            });
        }

        if (value.gamut !== WI.Color.Gamut.SRGB) {
            let label = isColorOutsideSRGB ? WI.UIString("Clamp to sRGB") : WI.UIString("Convert to sRGB");
            contextMenu.appendItem(label, () => {
                value.gamut = WI.Color.Gamut.SRGB;
                this._updateSwatch();
            });
        }
    }

    _getNextValidHEXFormat()
    {
        if (this._type !== WI.InlineSwatch.Type.Color)
            return false;

        let value = this.value;

        function hexMatchesCurrentColor(hexInfo) {
            let nextIsSimple = hexInfo.format === WI.Color.Format.ShortHEX || hexInfo.format === WI.Color.Format.HEX;
            if (nextIsSimple && !value.simple)
                return false;

            let nextIsShort = hexInfo.format === WI.Color.Format.ShortHEX || hexInfo.format === WI.Color.Format.ShortHEXAlpha;
            if (nextIsShort && !value.canBeSerializedAsShortHEX())
                return false;

            return true;
        }

        const hexFormats = [
            {
                format: WI.Color.Format.ShortHEX,
                title: WI.UIString("Format: Short Hex")
            },
            {
                format: WI.Color.Format.ShortHEXAlpha,
                title: WI.UIString("Format: Short Hex with Alpha")
            },
            {
                format: WI.Color.Format.HEX,
                title: WI.UIString("Format: Hex")
            },
            {
                format: WI.Color.Format.HEXAlpha,
                title: WI.UIString("Format: Hex with Alpha")
            }
        ];

        let currentColorIsHEX = hexFormats.some((info) => info.format === value.format);

        for (let i = 0; i < hexFormats.length; ++i) {
            if (currentColorIsHEX && value.format !== hexFormats[i].format)
                continue;

            for (let j = ~~currentColorIsHEX; j < hexFormats.length; ++j) {
                let nextIndex = (i + j) % hexFormats.length;
                if (hexMatchesCurrentColor(hexFormats[nextIndex]))
                    return hexFormats[nextIndex];
            }
            return null;
        }
        return hexFormats[0];
    }
};

WI.InlineSwatch.Type = {
    Color: "inline-swatch-type-color",
    Gradient: "inline-swatch-type-gradient",
    Bezier: "inline-swatch-type-bezier",
    BoxShadow: "inline-swatch-type-box-shadow",
    Spring: "inline-swatch-type-spring",
    Variable: "inline-swatch-type-variable",
    Image: "inline-swatch-type-image",
    Alignment: "inline-swatch-type-alignment",
};

WI.InlineSwatch.Event = {
    ValueChanged: "inline-swatch-value-changed",
    Activated: "inline-swatch-activated",
    Deactivated: "inline-swatch-deactivated",
};
