/*
 * Copyright (C) 2013 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.CSSRule = class CSSRule extends WI.Object
{
    constructor(nodeStyles, ownerStyleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings)
    {
        super();

        console.assert(nodeStyles);
        this._nodeStyles = nodeStyles;

        this._ownerStyleSheet = ownerStyleSheet || null;
        this._id = id || null;
        this._type = type || null;
        this._initialState = null;

        this.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings, true);
    }

    // Public

    get ownerStyleSheet() { return this._ownerStyleSheet; }
    get id() { return this._id; }
    get type() { return this._type; }
    get initialState() { return this._initialState; }
    get sourceCodeLocation() { return this._sourceCodeLocation; }
    get selectors() { return this._selectors; }
    get matchedSelectorIndices() { return this._matchedSelectorIndices; }
    get style() { return this._style; }
    get groupings() { return this._groupings; }

    get editable()
    {
        return !!this._id && (this._type === WI.CSSStyleSheet.Type.Author || this._type === WI.CSSStyleSheet.Type.Inspector);
    }

    get selectorText()
    {
        return this._selectorText;
    }

    set selectorText(selectorText)
    {
        console.assert(this.editable);
        if (!this.editable)
            return;

        if (this._selectorText === selectorText) {
            this._selectorResolved(true);
            return;
        }

        this._nodeStyles.changeRuleSelector(this, selectorText).then(this._selectorResolved.bind(this), this._selectorRejected.bind(this));
    }

    update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings)
    {
        sourceCodeLocation = sourceCodeLocation || null;
        selectorText = selectorText || "";
        selectors = selectors || [];
        matchedSelectorIndices = matchedSelectorIndices || [];
        style = style || null;
        groupings = groupings || [];

        if (this._style)
            this._style.ownerRule = null;

        this._sourceCodeLocation = sourceCodeLocation;
        this._selectorText = selectorText;
        this._selectors = selectors;
        this._matchedSelectorIndices = matchedSelectorIndices;
        this._style = style;
        this._groupings = groupings;

        if (this._style)
            this._style.ownerRule = this;
    }

    isEqualTo(rule)
    {
        if (!rule)
            return false;

        return Object.shallowEqual(this._id, rule.id);
    }

    // Protected

    get nodeStyles()
    {
        return this._nodeStyles;
    }

    // Private

    _selectorRejected(error)
    {
        this.dispatchEventToListeners(WI.CSSRule.Event.SelectorChanged, {valid: !error});
    }

    _selectorResolved(rulePayload)
    {
        if (rulePayload) {
            let selectorText = rulePayload.selectorList.text;
            if (selectorText !== this._selectorText) {
                let selectors = WI.DOMNodeStyles.parseSelectorListPayload(rulePayload.selectorList);

                let sourceCodeLocation = null;
                let sourceRange = rulePayload.selectorList.range;
                if (sourceRange) {
                    sourceCodeLocation = WI.DOMNodeStyles.createSourceCodeLocation(rulePayload.sourceURL, {
                        line: sourceRange.startLine,
                        column: sourceRange.startColumn,
                        documentNode: this._nodeStyles.node.ownerDocument,
                    });
                }

                if (this._ownerStyleSheet) {
                    if (!sourceCodeLocation && this._ownerStyleSheet.isInspectorStyleSheet())
                        sourceCodeLocation = this._ownerStyleSheet.createSourceCodeLocation(sourceRange.startLine, sourceRange.startColumn);

                    sourceCodeLocation = this._ownerStyleSheet.offsetSourceCodeLocation(sourceCodeLocation);
                }

                this.update(sourceCodeLocation, selectorText, selectors, [], this._style, this._groupings);
            }
        }

        this.dispatchEventToListeners(WI.CSSRule.Event.SelectorChanged, {valid: !!rulePayload});
    }
};

WI.CSSRule.Event = {
    SelectorChanged: "css-rule-invalid-selector"
};
