/*
 * Copyright (C) 2017 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.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationSection extends WI.View
{
    constructor(delegate, style)
    {
        console.assert(style instanceof WI.CSSStyleDeclaration, style);

        let element = document.createElement("section");
        element.classList.add("spreadsheet-css-declaration");

        super(element);

        this._delegate = delegate || null;
        this._style = style;
        this._propertiesEditor = null;
        this._selectorElements = [];
        this._groupingElements = [];
        this._filterText = null;
        this._shouldFocusSelectorElement = false;
        this._wasEditing = false;

        this._isMousePressed = false;
        this._mouseDownIndex = NaN;
        this._mouseDownPoint = null;
        this._boundHandleWindowMouseMove = null;
    }

    // Public

    get style() { return this._style; }

    get editable()
    {
        return this._style.editable;
    }

    initialLayout()
    {
        super.initialLayout();

        let iconClassName = null;
        switch (this._style.type) {
        case WI.CSSStyleDeclaration.Type.Rule:
            console.assert(this._style.ownerRule);
            if (this._style.inherited) {
                iconClassName = "inherited-style-rule-icon";
                break;
            }

            switch (this._style.ownerRule.type) {
            case WI.CSSStyleSheet.Type.Author:
                iconClassName = "author-style-rule-icon";
                break;
            case WI.CSSStyleSheet.Type.User:
                iconClassName = "user-style-rule-icon";
                break;
            case WI.CSSStyleSheet.Type.UserAgent:
                iconClassName = "user-agent-style-rule-icon";
                break;
            case WI.CSSStyleSheet.Type.Inspector:
                iconClassName = "inspector-style-rule-icon";
                break;
            }
            break;
        case WI.CSSStyleDeclaration.Type.Inline:
        case WI.CSSStyleDeclaration.Type.Attribute:
            if (this._style.inherited)
                iconClassName = "inherited-element-style-rule-icon";
            else
                iconClassName = WI.DOMTreeElementPathComponent.DOMElementIconStyleClassName;
            break;
        }
        console.assert(iconClassName);
        this._element.classList.add("has-icon", iconClassName);

        let groupings = this._style.groupings.filter((grouping) => grouping.text !== "all");
        if (groupings.length) {
            let groupingsElement = this.element.appendChild(document.createElement("div"));
            groupingsElement.classList.add("header-groupings");

            let currentGroupingType = null;
            let groupingTypeElement = null;
            this._groupingElements = groupings.map((grouping) => {
                if (grouping.type !== currentGroupingType) {
                    groupingTypeElement = groupingsElement.appendChild(document.createElement("div"));
                    groupingTypeElement.classList.add("grouping");
                    groupingTypeElement.textContent = grouping.prefix + " ";
                    currentGroupingType = grouping.type;
                } else
                    groupingTypeElement.append(", ");

                let span = groupingTypeElement.appendChild(document.createElement("span"));
                span.textContent = grouping.text;
                return span;
            });
        }

        this._headerElement = this._element.appendChild(document.createElement("div"));
        this._headerElement.classList.add("header");

        this._styleOriginView = new WI.StyleOriginView();
        this._headerElement.append(this._styleOriginView.element);

        this._selectorElement = document.createElement("span");
        this._selectorElement.classList.add("selector");
        this._selectorElement.addEventListener("mouseenter", this._highlightNodesWithSelector.bind(this));
        this._selectorElement.addEventListener("mouseleave", this._hideDOMNodeHighlight.bind(this));
        this._headerElement.append(this._selectorElement);

        this._openBrace = document.createElement("span");
        this._openBrace.classList.add("open-brace");
        this._openBrace.textContent = " {";
        this._headerElement.append(this._openBrace);

        if (this._style.selectorEditable) {
            this._selectorTextField = new WI.SpreadsheetSelectorField(this, this._selectorElement);
            this._selectorTextField.addEventListener(WI.SpreadsheetSelectorField.Event.StartedEditing, (event) => {
                this._headerElement.classList.add("editing-selector");
            });
            this._selectorTextField.addEventListener(WI.SpreadsheetSelectorField.Event.StoppedEditing, (event) => {
                this._headerElement.classList.remove("editing-selector");
            });

            this._selectorElement.tabIndex = 0;
        }

        this._propertiesEditor = new WI.SpreadsheetCSSStyleDeclarationEditor(this, this._style);
        this._propertiesEditor.element.classList.add("properties");
        this._propertiesEditor.addEventListener(WI.SpreadsheetCSSStyleDeclarationEditor.Event.FilterApplied, this._handleEditorFilterApplied, this);

        this._closeBrace = document.createElement("span");
        this._closeBrace.classList.add("close-brace");
        this._closeBrace.textContent = "}";


        this.addSubview(this._propertiesEditor);
        this._propertiesEditor.needsLayout();
        this._element.append(this._closeBrace);

        if (!this._style.editable)
            this._element.classList.add("locked");
        else if (!this._style.ownerRule)
            this._element.classList.add("selector-locked");

        this.element.addEventListener("mousedown", this._handleMouseDown.bind(this));

        if (this._style.editable) {
            this.element.addEventListener("click", this._handleClick.bind(this));

            new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "S", this._save.bind(this), this._element);
            new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "S", this._save.bind(this), this._element);
        }
    }

    layout()
    {
        super.layout();

        this._styleOriginView.update(this._style);
        this._renderSelector();

        if (this._shouldFocusSelectorElement)
            this.startEditingRuleSelector();
    }

    hidden()
    {
        this._propertiesEditor.hidden();
    }

    startEditingRuleSelector()
    {
        if (!this._selectorElement) {
            this._shouldFocusSelectorElement = true;
            return;
        }

        this._shouldFocusSelectorElement = false;

        if (this._style.selectorEditable)
            this._selectorTextField.startEditing();
        else
            this._propertiesEditor.startEditingFirstProperty();
    }

    highlightProperty(property)
    {
        // When navigating from the Computed panel to the Styles panel, the latter
        // could be empty. Layout all properties so they can be highlighted.
        if (!this.didInitialLayout)
            this.updateLayout();

        if (this._propertiesEditor.highlightProperty(property)) {
            this._element.scrollIntoView();
            return true;
        }

        return false;
    }

    // SpreadsheetSelectorField delegate

    spreadsheetSelectorFieldDidCommit(changed)
    {
        let selectorText = this._selectorElement.textContent.trim();
        if (selectorText && changed) {
            this.dispatchEventToListeners(WI.SpreadsheetCSSStyleDeclarationSection.Event.SelectorWillChange);
            this._style.ownerRule.setSelectorText(selectorText).finally(this._renderSelector.bind(this));
        } else
            this._discardSelectorChange();
    }

    spreadsheetSelectorFieldWillNavigate(direction)
    {
        console.assert(direction);
        if (direction === "forward")
            this._propertiesEditor.startEditingFirstProperty();
        else if (direction === "backward") {
            if (this._delegate.spreadsheetCSSStyleDeclarationSectionStartEditingAdjacentRule) {
                const delta = -1;
                this._delegate.spreadsheetCSSStyleDeclarationSectionStartEditingAdjacentRule(this, delta);
            } else
                this._propertiesEditor.startEditingLastProperty();
        }
    }

    spreadsheetSelectorFieldDidDiscard()
    {
        this._discardSelectorChange();
    }

    // SpreadsheetCSSStyleDeclarationEditor delegate

    spreadsheetCSSStyleDeclarationEditorStartEditingRuleSelector()
    {
        this.startEditingRuleSelector();
    }

    spreadsheetCSSStyleDeclarationEditorStartEditingAdjacentRule(propertiesEditor, delta)
    {
        if (!this._delegate)
            return;

        if (this._delegate.spreadsheetCSSStyleDeclarationSectionStartEditingAdjacentRule)
            this._delegate.spreadsheetCSSStyleDeclarationSectionStartEditingAdjacentRule(this, delta);
    }

    spreadsheetCSSStyleDeclarationEditorPropertyBlur(event, property)
    {
        if (!this._isMousePressed)
            this._propertiesEditor.deselectProperties();
    }

    spreadsheetCSSStyleDeclarationEditorPropertyMouseEnter(event, property)
    {
        if (this._isMousePressed) {
            let index = parseInt(property.element.dataset.propertyIndex);
            this._propertiesEditor.selectProperties(this._mouseDownIndex, index);
        }
    }

    spreadsheetCSSStyleDeclarationEditorSelectProperty(property)
    {
        if (this._delegate && this._delegate.spreadsheetCSSStyleDeclarationSectionSelectProperty)
            this._delegate.spreadsheetCSSStyleDeclarationSectionSelectProperty(property);
    }

    applyFilter(filterText)
    {
        this._filterText = filterText;

        if (!this.didInitialLayout)
            return;

        this._element.classList.remove(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);

        this._propertiesEditor.applyFilter(this._filterText);
    }

    // Private

    _discardSelectorChange()
    {
        // Re-render selector for syntax highlighting.
        this._renderSelector();
    }

    _renderSelector()
    {
        this._selectorElement.removeChildren();
        this._selectorElements = [];

        let appendSelector = (selector, matched) => {
            console.assert(selector instanceof WI.CSSSelector);

            let selectorElement = this._selectorElement.appendChild(document.createElement("span"));
            selectorElement.textContent = selector.text;

            if (matched)
                selectorElement.classList.add(WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);

            if (selector.specificity) {
                let specificity = selector.specificity.map((number) => number.toLocaleString());
                let tooltip = WI.UIString("Specificity: (%d, %d, %d)").format(...specificity);
                if (selector.dynamic) {
                    tooltip += "\n";
                    if (this._style.inherited)
                        tooltip += WI.UIString("Dynamically calculated for the parent element");
                    else
                        tooltip += WI.UIString("Dynamically calculated for the selected element");
                }
                selectorElement.title = tooltip;
            } else if (selector.dynamic) {
                let tooltip = WI.UIString("Specificity: No value for selected element");
                tooltip += "\n";
                tooltip += WI.UIString("Dynamically calculated for the selected element and did not match");
                selectorElement.title = tooltip;
            }

            this._selectorElements.push(selectorElement);
        };

        let appendSelectorTextKnownToMatch = (selectorText) => {
            let selectorElement = this._selectorElement.appendChild(document.createElement("span"));
            selectorElement.textContent = selectorText;
            selectorElement.classList.add(WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
        };

        if (!this._iconElement) {
            this._iconElement = document.createElement("img");
            this._iconElement.classList.add("icon");
            WI.addMouseDownContextMenuHandlers(this._iconElement, this._populateIconElementContextMenu.bind(this));
        }
        this._selectorElement.appendChild(this._iconElement);

        switch (this._style.type) {
        case WI.CSSStyleDeclaration.Type.Rule:
            console.assert(this._style.ownerRule);

            var hasMatchingPseudoSelector = false;

            var selectors = this._style.ownerRule.selectors;
            if (selectors.length) {
                for (let i = 0; i < selectors.length; ++i) {
                    let matched = this._style.ownerRule.matchedSelectorIndices.includes(i);
                    if (matched && selectors[i].isPseudoSelector())
                        hasMatchingPseudoSelector = true;

                    appendSelector(selectors[i], matched);
                    if (i < selectors.length - 1)
                        this._selectorElement.append(", ");
                }
            } else
                appendSelectorTextKnownToMatch(this._style.ownerRule.selectorText);

            this._element.classList.toggle("pseudo-selector", hasMatchingPseudoSelector);
            break;

        case WI.CSSStyleDeclaration.Type.Inline: {
            this._selectorElement.classList.add("style-attribute");
            let wrapper = this._selectorElement.appendChild(document.createElement("span"));
            wrapper.textContent = WI.UIString("Style Attribute", "CSS properties defined via HTML style attribute");
            break;
        }

        case WI.CSSStyleDeclaration.Type.Attribute:
            appendSelectorTextKnownToMatch(this._style.node.displayName);
            break;
        }

        if (this._filterText)
            this.applyFilter(this._filterText);
    }

    _save(event)
    {
        event.stop();

        if (this._style.type !== WI.CSSStyleDeclaration.Type.Rule) {
            // FIXME: Can't save CSS inside <style></style> <https://webkit.org/b/150357>
            InspectorFrontendHost.beep();
            return;
        }

        console.assert(this._style.ownerRule instanceof WI.CSSRule);
        console.assert(this._style.ownerRule.sourceCodeLocation instanceof WI.SourceCodeLocation);

        let sourceCode = this._style.ownerRule.sourceCodeLocation.sourceCode;
        if (sourceCode.type !== WI.Resource.Type.StyleSheet) {
            // FIXME: Can't save CSS inside style="" <https://webkit.org/b/150357>
            InspectorFrontendHost.beep();
            return;
        }

        let url;
        if (sourceCode.urlComponents.scheme === "data") {
            let mainResource = WI.networkManager.mainFrame.mainResource;
            if (mainResource.urlComponents.lastPathComponent.endsWith(".html"))
                url = mainResource.url.replace(/\.html$/, "-data.css");
            else {
                let pathDirectory = mainResource.url.slice(0, -mainResource.urlComponents.lastPathComponent.length);
                url = pathDirectory + "data.css";
            }
        } else
            url = sourceCode.url;

        const saveAs = event.shiftKey;
        WI.FileUtilities.save({url: url, content: sourceCode.content}, saveAs);
    }

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

        this._wasEditing = this._propertiesEditor.editing || document.activeElement === this._selectorElement;

        let propertyElement = event.target.closest(".property");
        if (!propertyElement)
            return;

        this._isMousePressed = true;

        // Disable text selection on mousemove.
        event.preventDefault();

        // Canceling mousedown event prevents blur event from firing on the previously focused element.
        if (this._wasEditing && document.activeElement)
            document.activeElement.blur();

        // Prevent name/value fields from editing when properties selected.
        window.addEventListener("click", this._handleWindowClick.bind(this), {capture: true, once: true});

        let propertyIndex = parseInt(propertyElement.dataset.propertyIndex);
        if (event.shiftKey && this._propertiesEditor.hasSelectedProperties())
            this._propertiesEditor.extendSelectedProperties(propertyIndex);
        else {
            this._propertiesEditor.deselectProperties();
            this._mouseDownPoint = WI.Point.fromEvent(event);
            if (!this._boundHandleWindowMouseMove)
                this._boundHandleWindowMouseMove = this._handleWindowMouseMove.bind(this);
            window.addEventListener("mousemove", this._boundHandleWindowMouseMove);
        }

        if (propertyElement.parentNode) {
            this._mouseDownIndex = propertyIndex;
            this._element.classList.add("selecting");
        } else
            this._stopSelection();
    }

    _populateIconElementContextMenu(contextMenu)
    {
        contextMenu.appendItem(WI.UIString("Copy Rule"), () => {
            InspectorFrontendHost.copyText(this._style.generateCSSRuleString());
        });

        if (this._style.editable && this._style.properties.length) {
            let shouldDisable = this._style.properties.some((property) => property.enabled);
            contextMenu.appendItem(shouldDisable ? WI.UIString("Disable Rule") : WI.UIString("Enable Rule"), () => {
                for (let property of this._style.properties)
                    property.commentOut(shouldDisable);
            });
        }

        if (!this._style.inherited) {
            let generateSelector = () => {
                if (this._style.type === WI.CSSStyleDeclaration.Type.Attribute)
                    return this._style.node.displayName;
                return this._style.selectorText;
            };

            let createNewRule = (selector, text) => {
                if (this._delegate && this._delegate.spreadsheetCSSStyleDeclarationSectionAddNewRule)
                    this._delegate.spreadsheetCSSStyleDeclarationSectionAddNewRule(this, selector, text);
                else
                    this._style.nodeStyles.addRule(selector, text);
            };

            contextMenu.appendSeparator();

            contextMenu.appendItem(WI.UIString("Duplicate Selector"), () => {
                createNewRule(generateSelector());
            });

            if (!WI.CSSManager.PseudoElementNames.some((className) => this._style.selectorText.includes(":" + className))) {
                let addPseudoRule = (pseudoSelector, text) => {
                    let selector = null;
                    if (this._style.ownerRule)
                        selector = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoSelector).join(", ");
                    else
                        selector = generateSelector() + pseudoSelector;
                    createNewRule(selector, text);
                };

                if (WI.CSSManager.ForceablePseudoClasses.every((className) => !this._style.selectorText.includes(":" + className))) {
                    contextMenu.appendSeparator();

                     for (let pseudoClass of WI.CSSManager.ForceablePseudoClasses) {
                        if (pseudoClass === "visited" && this._style.node.nodeName() !== "A")
                            continue;

                        let pseudoClassSelector = ":" + pseudoClass;
                        contextMenu.appendItem(WI.UIString("Add %s Rule").format(pseudoClassSelector), () => {
                            this._style.node.setPseudoClassEnabled(pseudoClass, true);
                            addPseudoRule(pseudoClassSelector);
                        });
                    }
                }

                if (this._style.type === WI.CSSStyleDeclaration.Type.Rule) {
                    contextMenu.appendSeparator();

                    for (let pseudoElement of WI.CSSManager.PseudoElementNames) {
                        let pseudoElementSelector = "::" + pseudoElement;
                        contextMenu.appendItem(WI.UIString("Create %s Rule").format(pseudoElementSelector), () => {
                            addPseudoRule(pseudoElementSelector, "content: \"\";");
                        });
                    }
                }
            }
        }

        if (this._style.ownerRule && this._style.ownerRule.sourceCodeLocation) {
            contextMenu.appendSeparator();

            let label = null;
            let sourceCode = this._style.ownerRule.sourceCodeLocation.displaySourceCode;
            if (sourceCode instanceof WI.CSSStyleSheet || (sourceCode instanceof WI.Resource && sourceCode.type === WI.Resource.Type.StyleSheet))
                label = WI.UIString("Reveal in Style Sheet");
            else
                label = WI.UIString("Reveal in Sources Tab");
            contextMenu.appendItem(label, () => {
                WI.showSourceCodeLocation(this._style.ownerRule.sourceCodeLocation, {
                    ignoreNetworkTab: true,
                    ignoreSearchTab: true,
                });
            });
        }
    }

    _handleWindowClick(event)
    {
        if (this._propertiesEditor.hasSelectedProperties()) {
            // Don't start editing name/value if there's selection.
            event.stop();
        }
        this._stopSelection();
    }

    _handleWindowMouseMove(event)
    {
        console.assert(this._mouseDownPoint);

        if (this._mouseDownPoint.distance(WI.Point.fromEvent(event)) < 8)
            return;

        if (!this._propertiesEditor.hasSelectedProperties()) {
            console.assert(!isNaN(this._mouseDownIndex));
            this._propertiesEditor.selectProperties(this._mouseDownIndex, this._mouseDownIndex);
        }

        window.removeEventListener("mousemove", this._boundHandleWindowMouseMove);
        this._mouseDownPoint = null;
    }

    _handleClick(event)
    {
        this._stopSelection();

        if (this._wasEditing || this._propertiesEditor.hasSelectedProperties())
            return;

        if (window.getSelection().type === "Range")
            return;

        event.stop();

        if (event.target.classList.contains(WI.SpreadsheetStyleProperty.StyleClassName)) {
            let propertyIndex = parseInt(event.target.dataset.propertyIndex);
            this._propertiesEditor.addBlankProperty(propertyIndex + 1);
            return;
        }

        if (event.target === this._headerElement || event.target === this._openBrace) {
            this._propertiesEditor.addBlankProperty(0);
            return;
        }

        if (event.target === this._element || event.target === this._closeBrace) {
            const appendAfterLast = -1;
            this._propertiesEditor.addBlankProperty(appendAfterLast);
        }
    }

    _stopSelection()
    {
        this._isMousePressed = false;
        this._mouseDownIndex = NaN;
        this._element.classList.remove("selecting");

        // "copy" and "cut" events won't fire on SpreadsheetCSSStyleDeclarationEditor unless it has text selected.
        // Placing a text caret inside of a property has no visible effects but it allows the events to fire.
        this._propertiesEditor.placeTextCaretInFocusedProperty();

        window.removeEventListener("mousemove", this._boundHandleWindowMouseMove);
        this._mouseDownPoint = null;
    }

    _highlightNodesWithSelector()
    {
        let node = this._style.node;

        if (!this._style.ownerRule) {
            WI.domManager.highlightDOMNode(node.id);
            return;
        }

        let selectorText = this._selectorElement.textContent.trim();
        if (node.frame)
            WI.domManager.highlightSelector(selectorText, node.frame.id);
        else
            WI.domManager.highlightSelector(selectorText);
    }

    _hideDOMNodeHighlight()
    {
        WI.domManager.hideDOMNodeHighlight();
    }

    _handleEditorFilterApplied(event)
    {
        let matchesGrouping = false;
        for (let groupingElement of this._groupingElements) {
            groupingElement.classList.remove(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);

            if (groupingElement.textContent.includes(this._filterText)) {
                groupingElement.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
                matchesGrouping = true;
            }
        }

        let matchesSelector = false;
        for (let selectorElement of this._selectorElements) {
            selectorElement.classList.remove(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);

            if (selectorElement.textContent.includes(this._filterText)) {
                selectorElement.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
                matchesSelector = true;
            }
        }

        let matches = event.data.matches || matchesGrouping || matchesSelector;
        if (!matches)
            this._element.classList.add(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);

        this.dispatchEventToListeners(WI.SpreadsheetCSSStyleDeclarationSection.Event.FilterApplied, {matches});
    }
};

WI.SpreadsheetCSSStyleDeclarationSection.Event = {
    FilterApplied: "spreadsheet-css-style-declaration-section-filter-applied",
    SelectorWillChange: "spreadsheet-css-style-declaration-section-selector-will-change",
};

WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName = "matched";
