/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef MatchResult_h
#define MatchResult_h

#include "core/css/RuleSet.h"
#include "core/css/SelectorChecker.h"
#include "wtf/MemoryObjectInfo.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"

namespace WebCore {

class StylePropertySet;
class StyleRule;

struct RuleRange {
    RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { }
    int& firstRuleIndex;
    int& lastRuleIndex;
};

struct MatchRanges {
    MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
    int firstUARule;
    int lastUARule;
    int firstAuthorRule;
    int lastAuthorRule;
    int firstUserRule;
    int lastUserRule;
    RuleRange UARuleRange() { return RuleRange(firstUARule, lastUARule); }
    RuleRange authorRuleRange() { return RuleRange(firstAuthorRule, lastAuthorRule); }
    RuleRange userRuleRange() { return RuleRange(firstUserRule, lastUserRule); }
};

struct MatchedProperties {
    MatchedProperties();
    ~MatchedProperties();
    void reportMemoryUsage(WTF::MemoryObjectInfo*) const;

    RefPtr<StylePropertySet> properties;
    union {
        struct {
            unsigned linkMatchType : 2;
            unsigned whitelistType : 2;
        };
        // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
        void* possiblyPaddedMember;
    };
};

struct MatchResult {
    MatchResult() : isCacheable(true) { }
    Vector<MatchedProperties, 64> matchedProperties;
    Vector<StyleRule*, 64> matchedRules;
    MatchRanges ranges;
    bool isCacheable;

    void addMatchedProperties(const StylePropertySet* properties, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone);
};

inline bool operator==(const MatchRanges& a, const MatchRanges& b)
{
    return a.firstUARule == b.firstUARule
        && a.lastUARule == b.lastUARule
        && a.firstAuthorRule == b.firstAuthorRule
        && a.lastAuthorRule == b.lastAuthorRule
        && a.firstUserRule == b.firstUserRule
        && a.lastUserRule == b.lastUserRule;
}

inline bool operator!=(const MatchRanges& a, const MatchRanges& b)
{
    return !(a == b);
}

inline bool operator==(const MatchedProperties& a, const MatchedProperties& b)
{
    return a.properties == b.properties && a.linkMatchType == b.linkMatchType;
}

inline bool operator!=(const MatchedProperties& a, const MatchedProperties& b)
{
    return !(a == b);
}

} // namespace WebCore

#endif // MatchResult_h
