/*
 * 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;

        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"
};
