/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcssparser_p.h"

#include <qdebug.h>
#include <qicon.h>
#include <qcolor.h>
#include <qfont.h>
#include <qfileinfo.h>
#include <qfontmetrics.h>
#include <qbrush.h>
#include <qimagereader.h>

#include <algorithm>

#ifndef QT_NO_CSSPARSER

QT_BEGIN_NAMESPACE

#include "qcssscanner.cpp"

using namespace QCss;

struct QCssKnownValue
{
    const char name[28];
    quint64 id;
};

static const QCssKnownValue properties[NumProperties - 1] = {
    { "-qt-background-role", QtBackgroundRole },
    { "-qt-block-indent", QtBlockIndent },
    { "-qt-fg-texture-cachekey", QtForegroundTextureCacheKey },
    { "-qt-line-height-type", QtLineHeightType },
    { "-qt-list-indent", QtListIndent },
    { "-qt-list-number-prefix", QtListNumberPrefix },
    { "-qt-list-number-suffix", QtListNumberSuffix },
    { "-qt-paragraph-type", QtParagraphType },
    { "-qt-style-features", QtStyleFeatures },
    { "-qt-table-type", QtTableType },
    { "-qt-user-state", QtUserState },
    { "alternate-background-color", QtAlternateBackground },
    { "background", Background },
    { "background-attachment", BackgroundAttachment },
    { "background-clip", BackgroundClip },
    { "background-color", BackgroundColor },
    { "background-image", BackgroundImage },
    { "background-origin", BackgroundOrigin },
    { "background-position", BackgroundPosition },
    { "background-repeat", BackgroundRepeat },
    { "border", Border },
    { "border-bottom", BorderBottom },
    { "border-bottom-color", BorderBottomColor },
    { "border-bottom-left-radius", BorderBottomLeftRadius },
    { "border-bottom-right-radius", BorderBottomRightRadius },
    { "border-bottom-style", BorderBottomStyle },
    { "border-bottom-width", BorderBottomWidth },
    { "border-collapse", BorderCollapse },
    { "border-color", BorderColor },
    { "border-image", BorderImage },
    { "border-left", BorderLeft },
    { "border-left-color", BorderLeftColor },
    { "border-left-style", BorderLeftStyle },
    { "border-left-width", BorderLeftWidth },
    { "border-radius", BorderRadius },
    { "border-right", BorderRight },
    { "border-right-color", BorderRightColor },
    { "border-right-style", BorderRightStyle },
    { "border-right-width", BorderRightWidth },
    { "border-style", BorderStyles },
    { "border-top", BorderTop },
    { "border-top-color", BorderTopColor },
    { "border-top-left-radius", BorderTopLeftRadius },
    { "border-top-right-radius", BorderTopRightRadius },
    { "border-top-style", BorderTopStyle },
    { "border-top-width", BorderTopWidth },
    { "border-width", BorderWidth },
    { "bottom", Bottom },
    { "color", Color },
    { "float", Float },
    { "font", Font },
    { "font-family", FontFamily },
    { "font-kerning", FontKerning },
    { "font-size", FontSize },
    { "font-style", FontStyle },
    { "font-variant", FontVariant },
    { "font-weight", FontWeight },
    { "height", Height },
    { "image", QtImage },
    { "image-position", QtImageAlignment },
    { "left", Left },
    { "line-height", LineHeight },
    { "list-style", ListStyle },
    { "list-style-type", ListStyleType },
    { "margin" , Margin },
    { "margin-bottom", MarginBottom },
    { "margin-left", MarginLeft },
    { "margin-right", MarginRight },
    { "margin-top", MarginTop },
    { "max-height", MaximumHeight },
    { "max-width", MaximumWidth },
    { "min-height", MinimumHeight },
    { "min-width", MinimumWidth },
    { "outline", Outline },
    { "outline-bottom-left-radius", OutlineBottomLeftRadius },
    { "outline-bottom-right-radius", OutlineBottomRightRadius },
    { "outline-color", OutlineColor },
    { "outline-offset", OutlineOffset },
    { "outline-radius", OutlineRadius },
    { "outline-style", OutlineStyle },
    { "outline-top-left-radius", OutlineTopLeftRadius },
    { "outline-top-right-radius", OutlineTopRightRadius },
    { "outline-width", OutlineWidth },
    { "padding", Padding },
    { "padding-bottom", PaddingBottom },
    { "padding-left", PaddingLeft },
    { "padding-right", PaddingRight },
    { "padding-top", PaddingTop },
    { "page-break-after", PageBreakAfter },
    { "page-break-before", PageBreakBefore },
    { "position", Position },
    { "right", Right },
    { "selection-background-color", QtSelectionBackground },
    { "selection-color", QtSelectionForeground },
    { "spacing", QtSpacing },
    { "subcontrol-origin", QtOrigin },
    { "subcontrol-position", QtPosition },
    { "text-align", TextAlignment },
    { "text-decoration", TextDecoration },
    { "text-indent", TextIndent },
    { "text-transform", TextTransform },
    { "text-underline-style", TextUnderlineStyle },
    { "top", Top },
    { "vertical-align", VerticalAlignment },
    { "white-space", Whitespace },
    { "width", Width }
};

static const QCssKnownValue values[NumKnownValues - 1] = {
    { "active", Value_Active },
    { "alternate-base", Value_AlternateBase },
    { "always", Value_Always },
    { "auto", Value_Auto },
    { "base", Value_Base },
    { "bold", Value_Bold },
    { "bottom", Value_Bottom },
    { "bright-text", Value_BrightText },
    { "button", Value_Button },
    { "button-text", Value_ButtonText },
    { "center", Value_Center },
    { "circle", Value_Circle },
    { "dark", Value_Dark },
    { "dashed", Value_Dashed },
    { "decimal", Value_Decimal },
    { "disabled", Value_Disabled },
    { "disc", Value_Disc },
    { "dot-dash", Value_DotDash },
    { "dot-dot-dash", Value_DotDotDash },
    { "dotted", Value_Dotted },
    { "double", Value_Double },
    { "groove", Value_Groove },
    { "highlight", Value_Highlight },
    { "highlighted-text", Value_HighlightedText },
    { "inset", Value_Inset },
    { "italic", Value_Italic },
    { "large", Value_Large },
    { "left", Value_Left },
    { "light", Value_Light },
    { "line-through", Value_LineThrough },
    { "link", Value_Link },
    { "link-visited", Value_LinkVisited },
    { "lower-alpha", Value_LowerAlpha },
    { "lower-roman", Value_LowerRoman },
    { "lowercase", Value_Lowercase },
    { "medium", Value_Medium },
    { "mid", Value_Mid },
    { "middle", Value_Middle },
    { "midlight", Value_Midlight },
    { "native", Value_Native },
    { "none", Value_None },
    { "normal", Value_Normal },
    { "nowrap", Value_NoWrap },
    { "oblique", Value_Oblique },
    { "off", Value_Off },
    { "on", Value_On },
    { "outset", Value_Outset },
    { "overline", Value_Overline },
    { "pre", Value_Pre },
    { "pre-line", Value_PreLine },
    { "pre-wrap", Value_PreWrap },
    { "ridge", Value_Ridge },
    { "right", Value_Right },
    { "selected", Value_Selected },
    { "shadow", Value_Shadow },
    { "small" , Value_Small },
    { "small-caps", Value_SmallCaps },
    { "solid", Value_Solid },
    { "square", Value_Square },
    { "sub", Value_Sub },
    { "super", Value_Super },
    { "text", Value_Text },
    { "top", Value_Top },
    { "transparent", Value_Transparent },
    { "underline", Value_Underline },
    { "upper-alpha", Value_UpperAlpha },
    { "upper-roman", Value_UpperRoman },
    { "uppercase", Value_Uppercase },
    { "wave", Value_Wave },
    { "window", Value_Window },
    { "window-text", Value_WindowText },
    { "x-large", Value_XLarge },
    { "xx-large", Value_XXLarge }
};

//Map id to strings as they appears in the 'values' array above
static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 50, 55, 35, 26, 71, 72, 25, 43, 5, 64, 48,
    29, 59, 60, 27, 52, 62, 6, 10, 39, 56, 19, 13, 17, 18, 20, 21, 51, 24, 46, 68, 37, 3, 2, 40, 63, 16,
    11, 58, 14, 32, 65, 33, 66, 56, 67, 34, 70, 8, 28, 38, 12, 36, 61, 7, 9, 4, 69, 54, 22, 23, 30, 31,
    1, 15, 0, 53, 45, 44 };

QString Value::toString() const
{
    if (type == KnownIdentifier) {
        return QLatin1String(values[indexOfId[variant.toInt()]].name);
    } else {
        return variant.toString();
    }
}

static const QCssKnownValue pseudos[NumPseudos - 1] = {
    { "active", PseudoClass_Active },
    { "adjoins-item", PseudoClass_Item },
    { "alternate", PseudoClass_Alternate },
    { "bottom", PseudoClass_Bottom },
    { "checked", PseudoClass_Checked },
    { "closable", PseudoClass_Closable },
    { "closed", PseudoClass_Closed },
    { "default", PseudoClass_Default },
    { "disabled", PseudoClass_Disabled },
    { "edit-focus", PseudoClass_EditFocus },
    { "editable", PseudoClass_Editable },
    { "enabled", PseudoClass_Enabled },
    { "exclusive", PseudoClass_Exclusive },
    { "first", PseudoClass_First },
    { "flat", PseudoClass_Flat },
    { "floatable", PseudoClass_Floatable },
    { "focus", PseudoClass_Focus },
    { "has-children", PseudoClass_Children },
    { "has-siblings", PseudoClass_Sibling },
    { "horizontal", PseudoClass_Horizontal },
    { "hover", PseudoClass_Hover },
    { "indeterminate" , PseudoClass_Indeterminate },
    { "last", PseudoClass_Last },
    { "left", PseudoClass_Left },
    { "maximized", PseudoClass_Maximized },
    { "middle", PseudoClass_Middle },
    { "minimized", PseudoClass_Minimized },
    { "movable", PseudoClass_Movable },
    { "next-selected", PseudoClass_NextSelected },
    { "no-frame", PseudoClass_Frameless },
    { "non-exclusive", PseudoClass_NonExclusive },
    { "off", PseudoClass_Unchecked },
    { "on", PseudoClass_Checked },
    { "only-one", PseudoClass_OnlyOne },
    { "open", PseudoClass_Open },
    { "pressed", PseudoClass_Pressed },
    { "previous-selected", PseudoClass_PreviousSelected },
    { "read-only", PseudoClass_ReadOnly },
    { "right", PseudoClass_Right },
    { "selected", PseudoClass_Selected },
    { "top", PseudoClass_Top },
    { "unchecked" , PseudoClass_Unchecked },
    { "vertical", PseudoClass_Vertical },
    { "window", PseudoClass_Window }
};

static const QCssKnownValue origins[NumKnownOrigins - 1] = {
    { "border", Origin_Border },
    { "content", Origin_Content },
    { "margin", Origin_Margin }, // not in css
    { "padding", Origin_Padding }
};

static const QCssKnownValue repeats[NumKnownRepeats - 1] = {
    { "no-repeat", Repeat_None },
    { "repeat-x", Repeat_X },
    { "repeat-xy", Repeat_XY },
    { "repeat-y", Repeat_Y }
};

static const QCssKnownValue tileModes[NumKnownTileModes - 1] = {
    { "repeat", TileMode_Repeat },
    { "round", TileMode_Round },
    { "stretch", TileMode_Stretch },
};

static const QCssKnownValue positions[NumKnownPositionModes - 1] = {
    { "absolute", PositionMode_Absolute },
    { "fixed", PositionMode_Fixed },
    { "relative", PositionMode_Relative },
    { "static", PositionMode_Static }
};

static const QCssKnownValue attachments[NumKnownAttachments - 1] = {
    { "fixed", Attachment_Fixed },
    { "scroll", Attachment_Scroll }
};

static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = {
    { "background-color", StyleFeature_BackgroundColor },
    { "background-gradient", StyleFeature_BackgroundGradient },
    { "none", StyleFeature_None }
};

static bool operator<(const QString &name, const QCssKnownValue &prop)
{
    return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0;
}

static bool operator<(const QCssKnownValue &prop, const QString &name)
{
    return QString::compare(QLatin1String(prop.name), name, Qt::CaseInsensitive) < 0;
}

static quint64 findKnownValue(const QString &name, const QCssKnownValue *start, int numValues)
{
    const QCssKnownValue *end = &start[numValues - 1];
    const QCssKnownValue *prop = std::lower_bound(start, end, name);
    if ((prop == end) || (name < *prop))
        return 0;
    return prop->id;
}

static inline bool isInheritable(Property propertyId)
{
    switch (propertyId) {
    case Font:
    case FontKerning:
    case FontFamily:
    case FontSize:
    case FontStyle:
    case FontWeight:
    case TextIndent:
    case Whitespace:
    case ListStyleType:
    case ListStyle:
    case TextAlignment:
    case FontVariant:
    case TextTransform:
    case LineHeight:
        return true;
    default:
        break;
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////////
// Value Extractor
ValueExtractor::ValueExtractor(const QVector<Declaration> &decls, const QPalette &pal)
: declarations(decls), adjustment(0), fontExtracted(false), pal(pal)
{
}

LengthData ValueExtractor::lengthValue(const Value& v)
{
    const QString str = v.variant.toString();
    QStringRef s(&str);
    LengthData data;
    data.unit = LengthData::None;
    if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive))
        data.unit = LengthData::Px;
    else if (s.endsWith(QLatin1String("ex"), Qt::CaseInsensitive))
        data.unit = LengthData::Ex;
    else if (s.endsWith(QLatin1String("em"), Qt::CaseInsensitive))
        data.unit = LengthData::Em;

    if (data.unit != LengthData::None)
        s.chop(2);

    data.number = s.toDouble();
    return data;
}

static int lengthValueFromData(const LengthData& data, const QFont& f)
{
    if (data.unit == LengthData::Ex)
        return qRound(QFontMetrics(f).xHeight() * data.number);
    else if (data.unit == LengthData::Em)
        return qRound(QFontMetrics(f).height() * data.number);
    return qRound(data.number);
}

int ValueExtractor::lengthValue(const Declaration &decl)
{
    if (decl.d->parsed.isValid())
        return  lengthValueFromData(qvariant_cast<LengthData>(decl.d->parsed), f);
    if (decl.d->values.count() < 1)
        return 0;
    LengthData data = lengthValue(decl.d->values.at(0));
    decl.d->parsed = QVariant::fromValue<LengthData>(data);
    return lengthValueFromData(data,f);
}

void ValueExtractor::lengthValues(const Declaration &decl, int *m)
{
    if (decl.d->parsed.isValid()) {
        QList<QVariant> v = decl.d->parsed.toList();
        Q_ASSERT(v.size() == 4);
        for (int i = 0; i < 4; i++)
            m[i] = lengthValueFromData(qvariant_cast<LengthData>(v.at(i)), f);
        return;
    }

    LengthData datas[4];
    int i;
    for (i = 0; i < qMin(decl.d->values.count(), 4); i++)
        datas[i] = lengthValue(decl.d->values[i]);

    if (i == 0) {
        LengthData zero = {0.0, LengthData::None};
        datas[0] = datas[1] = datas[2] = datas[3] = zero;
    } else if (i == 1) {
        datas[3] = datas[2] = datas[1] = datas[0];
    } else if (i == 2) {
        datas[2] = datas[0];
        datas[3] = datas[1];
    } else if (i == 3) {
        datas[3] = datas[1];
    }

    QList<QVariant> v;
    v.reserve(4);
    for (i = 0; i < 4; i++) {
        v += QVariant::fromValue<LengthData>(datas[i]);
        m[i] = lengthValueFromData(datas[i], f);
    }
    decl.d->parsed = v;
}

bool ValueExtractor::extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh)
{
    extractFont();
    bool hit = false;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case Width: *w = lengthValue(decl); break;
        case Height: *h = lengthValue(decl); break;
        case MinimumWidth: *minw = lengthValue(decl); break;
        case MinimumHeight: *minh = lengthValue(decl); break;
        case MaximumWidth: *maxw = lengthValue(decl); break;
        case MaximumHeight: *maxh = lengthValue(decl); break;
        default: continue;
        }
        hit = true;
    }

    return hit;
}

bool ValueExtractor::extractPosition(int *left, int *top, int *right, int *bottom, QCss::Origin *origin,
                                     Qt::Alignment *position, QCss::PositionMode *mode, Qt::Alignment *textAlignment)
{
    extractFont();
    bool hit = false;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case Left: *left = lengthValue(decl); break;
        case Top: *top = lengthValue(decl); break;
        case Right: *right = lengthValue(decl); break;
        case Bottom: *bottom = lengthValue(decl); break;
        case QtOrigin: *origin = decl.originValue(); break;
        case QtPosition: *position = decl.alignmentValue(); break;
        case TextAlignment: *textAlignment = decl.alignmentValue(); break;
        case Position: *mode = decl.positionValue(); break;
        default: continue;
        }
        hit = true;
    }

    return hit;
}

bool ValueExtractor::extractBox(int *margins, int *paddings, int *spacing)
{
    extractFont();
    bool hit = false;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case PaddingLeft: paddings[LeftEdge] = lengthValue(decl); break;
        case PaddingRight: paddings[RightEdge] = lengthValue(decl); break;
        case PaddingTop: paddings[TopEdge] = lengthValue(decl); break;
        case PaddingBottom: paddings[BottomEdge] = lengthValue(decl); break;
        case Padding: lengthValues(decl, paddings); break;

        case MarginLeft: margins[LeftEdge] = lengthValue(decl); break;
        case MarginRight: margins[RightEdge] = lengthValue(decl); break;
        case MarginTop: margins[TopEdge] = lengthValue(decl); break;
        case MarginBottom: margins[BottomEdge] = lengthValue(decl); break;
        case Margin: lengthValues(decl, margins); break;
        case QtSpacing: if (spacing) *spacing = lengthValue(decl); break;

        default: continue;
        }
        hit = true;
    }

    return hit;
}

int ValueExtractor::extractStyleFeatures()
{
    int features = StyleFeature_None;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        if (decl.d->propertyId == QtStyleFeatures)
            features = decl.styleFeaturesValue();
    }
    return features;
}

QSize ValueExtractor::sizeValue(const Declaration &decl)
{
    if (decl.d->parsed.isValid()) {
        QList<QVariant> v = decl.d->parsed.toList();
        return QSize(lengthValueFromData(qvariant_cast<LengthData>(v.at(0)), f),
                     lengthValueFromData(qvariant_cast<LengthData>(v.at(1)), f));
    }

    LengthData x[2] = { {0, LengthData::None }, {0, LengthData::None} };
    if (decl.d->values.count() > 0)
        x[0] = lengthValue(decl.d->values.at(0));
    if (decl.d->values.count() > 1)
        x[1] = lengthValue(decl.d->values.at(1));
    else
        x[1] = x[0];
    QList<QVariant> v;
    v << QVariant::fromValue<LengthData>(x[0]) << QVariant::fromValue<LengthData>(x[1]);
    decl.d->parsed = v;
    return QSize(lengthValueFromData(x[0], f), lengthValueFromData(x[1], f));
}

void ValueExtractor::sizeValues(const Declaration &decl, QSize *radii)
{
    radii[0] = sizeValue(decl);
    for (int i = 1; i < 4; i++)
        radii[i] = radii[0];
}

bool ValueExtractor::extractBorder(int *borders, QBrush *colors, BorderStyle *styles,
                                   QSize *radii)
{
    extractFont();
    bool hit = false;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case BorderLeftWidth: borders[LeftEdge] = lengthValue(decl); break;
        case BorderRightWidth: borders[RightEdge] = lengthValue(decl); break;
        case BorderTopWidth: borders[TopEdge] = lengthValue(decl); break;
        case BorderBottomWidth: borders[BottomEdge] = lengthValue(decl); break;
        case BorderWidth: lengthValues(decl, borders); break;

        case BorderLeftColor: colors[LeftEdge] = decl.brushValue(pal); break;
        case BorderRightColor: colors[RightEdge] = decl.brushValue(pal); break;
        case BorderTopColor: colors[TopEdge] = decl.brushValue(pal); break;
        case BorderBottomColor: colors[BottomEdge] = decl.brushValue(pal); break;
        case BorderColor: decl.brushValues(colors, pal); break;

        case BorderTopStyle: styles[TopEdge] = decl.styleValue(); break;
        case BorderBottomStyle: styles[BottomEdge] = decl.styleValue(); break;
        case BorderLeftStyle: styles[LeftEdge] = decl.styleValue(); break;
        case BorderRightStyle: styles[RightEdge] = decl.styleValue(); break;
        case BorderStyles:  decl.styleValues(styles); break;

        case BorderTopLeftRadius: radii[0] = sizeValue(decl); break;
        case BorderTopRightRadius: radii[1] = sizeValue(decl); break;
        case BorderBottomLeftRadius: radii[2] = sizeValue(decl); break;
        case BorderBottomRightRadius: radii[3] = sizeValue(decl); break;
        case BorderRadius: sizeValues(decl, radii); break;

        case BorderLeft:
            borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
            break;
        case BorderTop:
            borderValue(decl, &borders[TopEdge], &styles[TopEdge], &colors[TopEdge]);
            break;
        case BorderRight:
            borderValue(decl, &borders[RightEdge], &styles[RightEdge], &colors[RightEdge]);
            break;
        case BorderBottom:
            borderValue(decl, &borders[BottomEdge], &styles[BottomEdge], &colors[BottomEdge]);
            break;
        case Border:
            borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
            borders[TopEdge] = borders[RightEdge] = borders[BottomEdge] = borders[LeftEdge];
            styles[TopEdge] = styles[RightEdge] = styles[BottomEdge] = styles[LeftEdge];
            colors[TopEdge] = colors[RightEdge] = colors[BottomEdge] = colors[LeftEdge];
            break;

        default: continue;
        }
        hit = true;
    }

    return hit;
}

bool ValueExtractor::extractOutline(int *borders, QBrush *colors, BorderStyle *styles,
                                   QSize *radii, int *offsets)
{
    extractFont();
    bool hit = false;
    for (int i = 0; i < declarations.count(); i++) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case OutlineWidth: lengthValues(decl, borders); break;
        case OutlineColor: decl.brushValues(colors, pal); break;
        case OutlineStyle:  decl.styleValues(styles); break;

        case OutlineTopLeftRadius: radii[0] = sizeValue(decl); break;
        case OutlineTopRightRadius: radii[1] = sizeValue(decl); break;
        case OutlineBottomLeftRadius: radii[2] = sizeValue(decl); break;
        case OutlineBottomRightRadius: radii[3] = sizeValue(decl); break;
        case OutlineRadius: sizeValues(decl, radii); break;
        case OutlineOffset: lengthValues(decl, offsets); break;

        case Outline:
            borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
            borders[TopEdge] = borders[RightEdge] = borders[BottomEdge] = borders[LeftEdge];
            styles[TopEdge] = styles[RightEdge] = styles[BottomEdge] = styles[LeftEdge];
            colors[TopEdge] = colors[RightEdge] = colors[BottomEdge] = colors[LeftEdge];
            break;

        default: continue;
        }
        hit = true;
    }

    return hit;
}

static Qt::Alignment parseAlignment(const QCss::Value *values, int count)
{
    Qt::Alignment a[2] = { 0, 0 };
    for (int i = 0; i < qMin(2, count); i++) {
        if (values[i].type != Value::KnownIdentifier)
            break;
        switch (values[i].variant.toInt()) {
        case Value_Left: a[i] = Qt::AlignLeft; break;
        case Value_Right: a[i] = Qt::AlignRight; break;
        case Value_Top: a[i] = Qt::AlignTop; break;
        case Value_Bottom: a[i] = Qt::AlignBottom; break;
        case Value_Center: a[i] = Qt::AlignCenter; break;
        default: break;
        }
    }

    if (a[0] == Qt::AlignCenter && a[1] != 0 && a[1] != Qt::AlignCenter)
        a[0] = (a[1] == Qt::AlignLeft || a[1] == Qt::AlignRight) ? Qt::AlignVCenter : Qt::AlignHCenter;
    if ((a[1] == 0 || a[1] == Qt::AlignCenter) && a[0] != Qt::AlignCenter)
        a[1] = (a[0] == Qt::AlignLeft || a[0] == Qt::AlignRight) ? Qt::AlignVCenter : Qt::AlignHCenter;
    return a[0] | a[1];
}

static ColorData parseColorValue(QCss::Value v)
{
    if (v.type == Value::Identifier || v.type == Value::String) {
        v.variant.convert(QVariant::Color);
        v.type = Value::Color;
    }

    if (v.type == Value::Color)
        return qvariant_cast<QColor>(v.variant);

    if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_Transparent)
        return QColor(Qt::transparent);

    if (v.type != Value::Function)
        return ColorData();

    QStringList lst = v.variant.toStringList();
    if (lst.count() != 2)
        return ColorData();

    const QString &identifier = lst.at(0);
    if ((identifier.compare(QLatin1String("palette"), Qt::CaseInsensitive)) == 0) {
        int role = findKnownValue(lst.at(1).trimmed(), values, NumKnownValues);
        if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
            return (QPalette::ColorRole)(role-Value_FirstColorRole);

        return ColorData();
    }

    const bool rgb = identifier.startsWith(QLatin1String("rgb"));
    const bool hsv = !rgb && identifier.startsWith(QLatin1String("hsv"));
    const bool hsl = !rgb && !hsv && identifier.startsWith(QLatin1String("hsl"));

    if (!rgb && !hsv && !hsl)
        return ColorData();

    const bool hasAlpha = identifier.size() == 4 && identifier.at(3) == QLatin1Char('a');
    if (identifier.size() > 3 && !hasAlpha)
        return ColorData();

    Parser p(lst.at(1));
    if (!p.testExpr())
        return ColorData();

    QVector<QCss::Value> colorDigits;
    if (!p.parseExpr(&colorDigits))
        return ColorData();
    const int tokenCount = colorDigits.count();

    for (int i = 0; i < qMin(tokenCount, 7); i += 2) {
        if (colorDigits.at(i).type == Value::Percentage) {
            const qreal maxRange = (rgb || i != 0) ? 255. : 359.;
            colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (maxRange / 100.);
            colorDigits[i].type = Value::Number;
        } else if (colorDigits.at(i).type != Value::Number) {
            return ColorData();
        }
    }


    if (tokenCount < 5)
        return ColorData();

    // ### Qt6: replace this with a check and return invalid color when token count does not match
    if (hasAlpha && tokenCount != 7)
        qWarning("QCssParser::parseColorValue: Specified color with alpha value but no alpha given: '%s'", qPrintable(lst.join(QLatin1Char(' '))));
    if (!hasAlpha && tokenCount != 5)
        qWarning("QCssParser::parseColorValue: Specified color without alpha value but alpha given: '%s'", qPrintable(lst.join(QLatin1Char(' '))));

    int v1 = colorDigits.at(0).variant.toInt();
    int v2 = colorDigits.at(2).variant.toInt();
    int v3 = colorDigits.at(4).variant.toInt();
    int alpha = 255;
    if (tokenCount == 7) {
        int alphaValue = colorDigits.at(6).variant.toInt();
        if (alphaValue <= 1)
            alpha = colorDigits.at(6).variant.toReal() * 255.;
        else
            alpha = alphaValue;
    }

    if (rgb)
        return QColor::fromRgb(v1, v2, v3, alpha);
    if (hsv)
        return QColor::fromHsv(v1, v2, v3, alpha);
    return QColor::fromHsl(v1, v2, v3, alpha);
}

static QColor colorFromData(const ColorData& c, const QPalette &pal)
{
    if (c.type == ColorData::Color) {
        return c.color;
    } else if (c.type == ColorData::Role) {
        return pal.color(c.role);
    }
    return QColor();
}

static BrushData parseBrushValue(const QCss::Value &v, const QPalette &pal)
{
    ColorData c = parseColorValue(v);
    if (c.type == ColorData::Color) {
        return QBrush(c.color);
    } else if (c.type == ColorData::Role) {
        return c.role;
    }

    if (v.type != Value::Function)
        return BrushData();

    QStringList lst = v.variant.toStringList();
    if (lst.count() != 2)
        return BrushData();

    QStringList gradFuncs;
    gradFuncs << QLatin1String("qlineargradient") << QLatin1String("qradialgradient") << QLatin1String("qconicalgradient") << QLatin1String("qgradient");
    int gradType = -1;

    if ((gradType = gradFuncs.indexOf(lst.at(0).toLower())) == -1)
        return BrushData();

    QHash<QString, qreal> vars;
    QVector<QGradientStop> stops;

    int spread = -1;
    QStringList spreads;
    spreads << QLatin1String("pad") << QLatin1String("reflect") << QLatin1String("repeat");

    bool dependsOnThePalette = false;
    Parser parser(lst.at(1));
    while (parser.hasNext()) {
        parser.skipSpace();
        if (!parser.test(IDENT))
            return BrushData();
        QString attr = parser.lexem();
        parser.skipSpace();
        if (!parser.test(COLON))
            return BrushData();
        parser.skipSpace();
        if (attr.compare(QLatin1String("stop"), Qt::CaseInsensitive) == 0) {
            QCss::Value stop, color;
            parser.next();
            if (!parser.parseTerm(&stop)) return BrushData();
            parser.skipSpace();
            parser.next();
            if (!parser.parseTerm(&color)) return BrushData();
            ColorData cd = parseColorValue(color);
            if(cd.type == ColorData::Role)
                dependsOnThePalette = true;
            stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal)));
        } else {
            parser.next();
            QCss::Value value;
            (void)parser.parseTerm(&value);
            if (attr.compare(QLatin1String("spread"), Qt::CaseInsensitive) == 0) {
                spread = spreads.indexOf(value.variant.toString());
            } else {
                vars[attr] = value.variant.toReal();
            }
        }
        parser.skipSpace();
        (void)parser.test(COMMA);
    }

    if (gradType == 0) {
        QLinearGradient lg(vars.value(QLatin1String("x1")), vars.value(QLatin1String("y1")),
                           vars.value(QLatin1String("x2")), vars.value(QLatin1String("y2")));
        lg.setCoordinateMode(QGradient::ObjectBoundingMode);
        lg.setStops(stops);
        if (spread != -1)
            lg.setSpread(QGradient::Spread(spread));
        BrushData bd = QBrush(lg);
        if (dependsOnThePalette)
            bd.type = BrushData::DependsOnThePalette;
        return bd;
    }

    if (gradType == 1) {
        QRadialGradient rg(vars.value(QLatin1String("cx")), vars.value(QLatin1String("cy")),
                           vars.value(QLatin1String("radius")), vars.value(QLatin1String("fx")),
                           vars.value(QLatin1String("fy")));
        rg.setCoordinateMode(QGradient::ObjectBoundingMode);
        rg.setStops(stops);
        if (spread != -1)
            rg.setSpread(QGradient::Spread(spread));
        BrushData bd = QBrush(rg);
        if (dependsOnThePalette)
            bd.type = BrushData::DependsOnThePalette;
        return bd;
    }

    if (gradType == 2) {
        QConicalGradient cg(vars.value(QLatin1String("cx")), vars.value(QLatin1String("cy")),
                            vars.value(QLatin1String("angle")));
        cg.setCoordinateMode(QGradient::ObjectBoundingMode);
        cg.setStops(stops);
        if (spread != -1)
            cg.setSpread(QGradient::Spread(spread));
        BrushData bd = QBrush(cg);
        if (dependsOnThePalette)
            bd.type = BrushData::DependsOnThePalette;
        return bd;
    }

    return BrushData();
}

static QBrush brushFromData(const BrushData& c, const QPalette &pal)
{
    if (c.type == BrushData::Role) {
        return pal.color(c.role);
    } else {
        return c.brush;
    }
}

static BorderStyle parseStyleValue(const QCss::Value &v)
{
    if (v.type == Value::KnownIdentifier) {
        switch (v.variant.toInt()) {
        case Value_None:
            return BorderStyle_None;
        case Value_Dotted:
            return BorderStyle_Dotted;
        case Value_Dashed:
            return BorderStyle_Dashed;
        case Value_Solid:
            return BorderStyle_Solid;
        case Value_Double:
            return BorderStyle_Double;
        case Value_DotDash:
            return BorderStyle_DotDash;
        case Value_DotDotDash:
            return BorderStyle_DotDotDash;
        case Value_Groove:
            return BorderStyle_Groove;
        case Value_Ridge:
            return BorderStyle_Ridge;
        case Value_Inset:
            return BorderStyle_Inset;
        case Value_Outset:
            return BorderStyle_Outset;
        case Value_Native:
            return BorderStyle_Native;
        default:
            break;
        }
    }

    return BorderStyle_Unknown;
}

void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::BorderStyle *style, QBrush *color)
{
    if (decl.d->parsed.isValid()) {
        BorderData data = qvariant_cast<BorderData>(decl.d->parsed);
        *width = lengthValueFromData(data.width, f);
        *style = data.style;
        *color = data.color.type != BrushData::Invalid ? brushFromData(data.color, pal) : QBrush(QColor());
        return;
    }

    *width = 0;
    *style = BorderStyle_None;
    *color = QColor();

    if (decl.d->values.isEmpty())
        return;

    BorderData data;
    data.width.number = 0;
    data.width.unit = LengthData::None;
    data.style = BorderStyle_None;

    int i = 0;
    if (decl.d->values.at(i).type == Value::Length || decl.d->values.at(i).type == Value::Number) {
        data.width = lengthValue(decl.d->values.at(i));
        *width = lengthValueFromData(data.width, f);
        if (++i >= decl.d->values.count()) {
            decl.d->parsed = QVariant::fromValue<BorderData>(data);
            return;
        }
    }

    data.style = parseStyleValue(decl.d->values.at(i));
    if (data.style != BorderStyle_Unknown) {
        *style = data.style;
        if (++i >= decl.d->values.count()) {
            decl.d->parsed = QVariant::fromValue<BorderData>(data);
            return;
        }
    } else {
        data.style = BorderStyle_None;
    }

     data.color = parseBrushValue(decl.d->values.at(i), pal);
     *color = brushFromData(data.color, pal);
     if (data.color.type != BrushData::DependsOnThePalette)
         decl.d->parsed = QVariant::fromValue<BorderData>(data);
}

static void parseShorthandBackgroundProperty(const QVector<QCss::Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal)
{
    *brush = BrushData();
    *image = QString();
    *repeat = Repeat_XY;
    *alignment = Qt::AlignTop | Qt::AlignLeft;

    for (int i = 0; i < values.count(); ++i) {
        const QCss::Value &v = values.at(i);
        if (v.type == Value::Uri) {
            *image = v.variant.toString();
            continue;
        } else if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_None) {
            *image = QString();
            continue;
        } else if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_Transparent) {
            *brush = QBrush(Qt::transparent);
        }

        Repeat repeatAttempt = static_cast<Repeat>(findKnownValue(v.variant.toString(),
                                                   repeats, NumKnownRepeats));
        if (repeatAttempt != Repeat_Unknown) {
            *repeat = repeatAttempt;
            continue;
        }

        if (v.type == Value::KnownIdentifier) {
            const int start = i;
            int count = 1;
            if (i < values.count() - 1
                && values.at(i + 1).type == Value::KnownIdentifier) {
                ++i;
                ++count;
            }
            Qt::Alignment a = parseAlignment(values.constData() + start, count);
            if (int(a) != 0) {
                *alignment = a;
                continue;
            }
            i -= count - 1;
        }

        *brush = parseBrushValue(v, pal);
    }
}

bool ValueExtractor::extractBackground(QBrush *brush, QString *image, Repeat *repeat,
                                       Qt::Alignment *alignment, Origin *origin, Attachment *attachment,
                                       Origin *clip)
{
    bool hit = false;
    for (int i = 0; i < declarations.count(); ++i) {
        const Declaration &decl = declarations.at(i);
        if (decl.d->values.isEmpty())
            continue;
        const QCss::Value &val = decl.d->values.at(0);
        switch (decl.d->propertyId) {
            case BackgroundColor:
                    *brush = decl.brushValue();
                break;
            case BackgroundImage:
                if (val.type == Value::Uri)
                    *image = val.variant.toString();
                break;
            case BackgroundRepeat:
                if (decl.d->parsed.isValid()) {
                    *repeat = static_cast<Repeat>(decl.d->parsed.toInt());
                } else {
                    *repeat = static_cast<Repeat>(findKnownValue(val.variant.toString(),
                                                  repeats, NumKnownRepeats));
                    decl.d->parsed = *repeat;
                }
                break;
            case BackgroundPosition:
                *alignment = decl.alignmentValue();
                break;
            case BackgroundOrigin:
                *origin = decl.originValue();
                break;
            case BackgroundClip:
                *clip = decl.originValue();
                break;
            case Background:
                if (decl.d->parsed.isValid()) {
                    BackgroundData data = qvariant_cast<BackgroundData>(decl.d->parsed);
                    *brush = brushFromData(data.brush, pal);
                    *image = data.image;
                    *repeat = data.repeat;
                    *alignment = data.alignment;
                } else {
                    BrushData brushData;
                    parseShorthandBackgroundProperty(decl.d->values, &brushData, image, repeat, alignment, pal);
                    *brush = brushFromData(brushData, pal);
                    if (brushData.type != BrushData::DependsOnThePalette) {
                        BackgroundData data = { brushData, *image, *repeat, *alignment };
                        decl.d->parsed = QVariant::fromValue<BackgroundData>(data);
                    }
                }
                break;
            case BackgroundAttachment:
                *attachment = decl.attachmentValue();
                break;
            default: continue;
        }
        hit = true;
    }
    return hit;
}

static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAdjustment)
{
    if (value.type == Value::KnownIdentifier) {
        bool valid = true;
        switch (value.variant.toInt()) {
            case Value_Small: *fontSizeAdjustment = -1; break;
            case Value_Medium: *fontSizeAdjustment = 0; break;
            case Value_Large: *fontSizeAdjustment = 1; break;
            case Value_XLarge: *fontSizeAdjustment = 2; break;
            case Value_XXLarge: *fontSizeAdjustment = 3; break;
            default: valid = false; break;
        }
        return valid;
    }
    if (value.type != Value::Length)
        return false;

    bool valid = false;
    QString s = value.variant.toString();
    if (s.endsWith(QLatin1String("pt"), Qt::CaseInsensitive)) {
        s.chop(2);
        value.variant = s;
        if (value.variant.convert((QVariant::Type)qMetaTypeId<qreal>())) {
            font->setPointSizeF(value.variant.toReal());
            valid = true;
        }
    } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) {
        s.chop(2);
        value.variant = s;
        if (value.variant.convert(QVariant::Int)) {
            font->setPixelSize(value.variant.toInt());
            valid = true;
        }
    }
    return valid;
}

static bool setFontStyleFromValue(const QCss::Value &value, QFont *font)
{
    if (value.type != Value::KnownIdentifier)
        return false ;
    switch (value.variant.toInt()) {
        case Value_Normal: font->setStyle(QFont::StyleNormal); return true;
        case Value_Italic: font->setStyle(QFont::StyleItalic); return true;
        case Value_Oblique: font->setStyle(QFont::StyleOblique); return true;
        default: break;
    }
    return false;
}

static bool setFontKerningFromValue(const QCss::Value &value, QFont *font)
{
    if (value.type != Value::KnownIdentifier)
        return false ;
    switch (value.variant.toInt()) {
        case Value_Normal: font->setKerning(true); return true;
        case Value_None: font->setKerning(false); return true;
        case Value_Auto: return true;
        default: break;
    }
    return false;
}

static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
{
    if (value.type == Value::KnownIdentifier) {
        switch (value.variant.toInt()) {
            case Value_Normal: font->setWeight(QFont::Normal); return true;
            case Value_Bold: font->setWeight(QFont::Bold); return true;
            default: break;
        }
        return false;
    }
    if (value.type != Value::Number)
        return false;
    font->setWeight(qMin(value.variant.toInt() / 8, 99));
    return true;
}

/** \internal
 * parse the font family from the values (starting from index \a start)
 * and set it the \a font
 * The function returns \c true if a family was extracted.
 */
static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *font, int start = 0)
{
    QString family;
    QStringList families;
    bool shouldAddSpace = false;
    for (int i = start; i < values.count(); ++i) {
        const QCss::Value &v = values.at(i);
        if (v.type == Value::TermOperatorComma) {
            families << family;
            family.clear();
            shouldAddSpace = false;
            continue;
        }
        const QString str = v.variant.toString();
        if (str.isEmpty())
            break;
        if (shouldAddSpace)
            family += QLatin1Char(' ');
        family += str;
        shouldAddSpace = true;
    }
    if (!family.isEmpty())
        families << family;
    if (families.isEmpty())
        return false;
    font->setFamily(families.at(0));
    font->setFamilies(families);
    return true;
}

static void setTextDecorationFromValues(const QVector<QCss::Value> &values, QFont *font)
{
    for (int i = 0; i < values.count(); ++i) {
        if (values.at(i).type != Value::KnownIdentifier)
            continue;
        switch (values.at(i).variant.toInt()) {
            case Value_Underline: font->setUnderline(true); break;
            case Value_Overline: font->setOverline(true); break;
            case Value_LineThrough: font->setStrikeOut(true); break;
            case Value_None:
                font->setUnderline(false);
                font->setOverline(false);
                font->setStrikeOut(false);
                break;
            default: break;
        }
    }
}

static void parseShorthandFontProperty(const QVector<QCss::Value> &values, QFont *font, int *fontSizeAdjustment)
{
    font->setStyle(QFont::StyleNormal);
    font->setWeight(QFont::Normal);
    *fontSizeAdjustment = -255;

    int i = 0;
    while (i < values.count()) {
        if (setFontStyleFromValue(values.at(i), font)
            || setFontWeightFromValue(values.at(i), font))
            ++i;
        else
            break;
    }

    if (i < values.count()) {
        setFontSizeFromValue(values.at(i), font, fontSizeAdjustment);
        ++i;
    }

    if (i < values.count()) {
        setFontFamilyFromValues(values, font, i);
    }
}

static void setFontVariantFromValue(const QCss::Value &value, QFont *font)
{
    if (value.type == Value::KnownIdentifier) {
        switch (value.variant.toInt()) {
            case Value_Normal: font->setCapitalization(QFont::MixedCase); break;
            case Value_SmallCaps: font->setCapitalization(QFont::SmallCaps); break;
            default: break;
        }
    }
}

static void setTextTransformFromValue(const QCss::Value &value, QFont *font)
{
    if (value.type == Value::KnownIdentifier) {
        switch (value.variant.toInt()) {
            case Value_None: font->setCapitalization(QFont::MixedCase); break;
            case Value_Uppercase: font->setCapitalization(QFont::AllUppercase); break;
            case Value_Lowercase: font->setCapitalization(QFont::AllLowercase); break;
            default: break;
        }
    }
}

bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment)
{
    if (fontExtracted) {
        *font = f;
        *fontSizeAdjustment = adjustment;
        return fontExtracted == 1;
    }

    bool hit = false;
    for (int i = 0; i < declarations.count(); ++i) {
        const Declaration &decl = declarations.at(i);
        if (decl.d->values.isEmpty())
            continue;
        const QCss::Value &val = decl.d->values.at(0);
        switch (decl.d->propertyId) {
            case FontSize: setFontSizeFromValue(val, font, fontSizeAdjustment); break;
            case FontStyle: setFontStyleFromValue(val, font); break;
            case FontWeight: setFontWeightFromValue(val, font); break;
            case FontFamily: setFontFamilyFromValues(decl.d->values, font); break;
            case FontKerning: setFontKerningFromValue(val, font); break;
            case TextDecoration: setTextDecorationFromValues(decl.d->values, font); break;
            case Font: parseShorthandFontProperty(decl.d->values, font, fontSizeAdjustment); break;
            case FontVariant: setFontVariantFromValue(val, font); break;
            case TextTransform: setTextTransformFromValue(val, font); break;
            default: continue;
        }
        hit = true;
    }

    f = *font;
    adjustment = *fontSizeAdjustment;
    fontExtracted = hit ? 1 : 2;
    return hit;
}

bool ValueExtractor::extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg)
{
    bool hit = false;
    for (int i = 0; i < declarations.count(); ++i) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case Color: *fg = decl.brushValue(pal); break;
        case QtSelectionForeground: *sfg = decl.brushValue(pal); break;
        case QtSelectionBackground: *sbg = decl.brushValue(pal); break;
        case QtAlternateBackground: *abg = decl.brushValue(pal); break;
        default: continue;
        }
        hit = true;
    }
    return hit;
}

void ValueExtractor::extractFont()
{
    if (fontExtracted)
        return;
    int dummy = -255;
    extractFont(&f, &dummy);
}

bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
{
    bool hit = false;
    for (int i = 0; i < declarations.count(); ++i) {
        const Declaration &decl = declarations.at(i);
        switch (decl.d->propertyId) {
        case QtImage:
            *icon = decl.iconValue();
            if (decl.d->values.count() > 0 && decl.d->values.at(0).type == Value::Uri) {
                // try to pull just the size from the image...
                QImageReader imageReader(decl.d->values.at(0).variant.toString());
                if ((*size = imageReader.size()).isNull()) {
                    // but we'll have to load the whole image if the
                    // format doesn't support just reading the size
                    *size = imageReader.read().size();
                }
            }
            break;
        case QtImageAlignment: *a = decl.alignmentValue();  break;
        default: continue;
        }
        hit = true;
    }
    return hit;
}

///////////////////////////////////////////////////////////////////////////////
// Declaration
QColor Declaration::colorValue(const QPalette &pal) const
{
    if (d->values.count() != 1)
        return QColor();

    if (d->parsed.isValid()) {
        if (d->parsed.type() == QVariant::Color)
            return qvariant_cast<QColor>(d->parsed);
        if (d->parsed.type() == QVariant::Int)
            return pal.color((QPalette::ColorRole)(d->parsed.toInt()));
    }

    ColorData color = parseColorValue(d->values.at(0));
    if(color.type == ColorData::Role) {
        d->parsed = QVariant::fromValue<int>(color.role);
        return pal.color((QPalette::ColorRole)(color.role));
    } else {
        d->parsed = QVariant::fromValue<QColor>(color.color);
        return color.color;
    }
}

QBrush Declaration::brushValue(const QPalette &pal) const
{
    if (d->values.count() != 1)
        return QBrush();

    if (d->parsed.isValid()) {
        if (d->parsed.type() == QVariant::Brush)
            return qvariant_cast<QBrush>(d->parsed);
        if (d->parsed.type() == QVariant::Int)
            return pal.color((QPalette::ColorRole)(d->parsed.toInt()));
    }

    BrushData data = parseBrushValue(d->values.at(0), pal);

    if(data.type == BrushData::Role) {
        d->parsed = QVariant::fromValue<int>(data.role);
        return pal.color((QPalette::ColorRole)(data.role));
    } else {
        if (data.type != BrushData::DependsOnThePalette)
            d->parsed = QVariant::fromValue<QBrush>(data.brush);
        return data.brush;
    }
}

void Declaration::brushValues(QBrush *c, const QPalette &pal) const
{
    int needParse = 0x1f; // bits 0..3 say if we should parse the corresponding value.
                          // the bit 4 say we need to update d->parsed
    int i = 0;
    if (d->parsed.isValid()) {
        needParse = 0;
        QList<QVariant> v = d->parsed.toList();
        for (i = 0; i < qMin(v.count(), 4); i++) {
            if (v.at(i).type() == QVariant::Brush) {
                c[i] = qvariant_cast<QBrush>(v.at(i));
            } else if (v.at(i).type() == QVariant::Int) {
                c[i] = pal.color((QPalette::ColorRole)(v.at(i).toInt()));
            } else {
                needParse |= (1<<i);
            }
        }
    }
    if (needParse != 0) {
        QList<QVariant> v;
        for (i = 0; i < qMin(d->values.count(), 4); i++) {
            if (!(needParse & (1<<i)))
                continue;
            BrushData data = parseBrushValue(d->values.at(i), pal);
            if(data.type == BrushData::Role) {
                v += QVariant::fromValue<int>(data.role);
                c[i] = pal.color((QPalette::ColorRole)(data.role));
            } else {
                if (data.type != BrushData::DependsOnThePalette) {
                    v += QVariant::fromValue<QBrush>(data.brush);
                } else {
                    v += QVariant();
                }
                c[i] = data.brush;
            }
        }
        if (needParse & 0x10)
            d->parsed = v;
    }
    if (i == 0) c[0] = c[1] = c[2] = c[3] = QBrush();
    else if (i == 1) c[3] = c[2] = c[1] = c[0];
    else if (i == 2) c[2] = c[0], c[3] = c[1];
    else if (i == 3) c[3] = c[1];
}

bool Declaration::realValue(qreal *real, const char *unit) const
{
    if (d->values.count() != 1)
        return false;
    const Value &v = d->values.at(0);
    if (unit && v.type != Value::Length)
        return false;
    const QString str = v.variant.toString();
    QStringRef s(&str);
    if (unit) {
        const QLatin1String unitStr(unit);
        if (!s.endsWith(unitStr, Qt::CaseInsensitive))
            return false;
        s.chop(unitStr.size());
    }
    bool ok = false;
    qreal val = s.toDouble(&ok);
    if (ok)
        *real = val;
    return ok;
}

static bool intValueHelper(const QCss::Value &v, int *i, const char *unit)
{
    if (unit && v.type != Value::Length)
        return false;
    const QString str = v.variant.toString();
    QStringRef s(&str);
    if (unit) {
        const QLatin1String unitStr(unit);
        if (!s.endsWith(unitStr, Qt::CaseInsensitive))
            return false;
        s.chop(unitStr.size());
    }
    bool ok = false;
    int val = s.toInt(&ok);
    if (ok)
        *i = val;
    return ok;
}

bool Declaration::intValue(int *i, const char *unit) const
{
    if (d->values.count() != 1)
        return false;
    return intValueHelper(d->values.at(0), i, unit);
}

QSize Declaration::sizeValue() const
{
    if (d->parsed.isValid())
        return qvariant_cast<QSize>(d->parsed);

    int x[2] = { 0, 0 };
    if (d->values.count() > 0)
        intValueHelper(d->values.at(0), &x[0], "px");
    if (d->values.count() > 1)
        intValueHelper(d->values.at(1), &x[1], "px");
    else
        x[1] = x[0];
    QSize size(x[0], x[1]);
    d->parsed = QVariant::fromValue<QSize>(size);
    return size;
}

QRect Declaration::rectValue() const
{
    if (d->values.count() != 1)
        return QRect();

    if (d->parsed.isValid())
        return qvariant_cast<QRect>(d->parsed);

    const QCss::Value &v = d->values.at(0);
    if (v.type != Value::Function)
        return QRect();
    const QStringList func = v.variant.toStringList();
    if (func.count() != 2 || func.at(0).compare(QLatin1String("rect")) != 0)
        return QRect();
    const auto args = func[1].splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
    if (args.count() != 4)
        return QRect();
    QRect rect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt());
    d->parsed = QVariant::fromValue<QRect>(rect);
    return rect;
}

void Declaration::colorValues(QColor *c, const QPalette &pal) const
{
    int i;
    if (d->parsed.isValid()) {
        QList<QVariant> v = d->parsed.toList();
        for (i = 0; i < qMin(d->values.count(), 4); i++) {
            if (v.at(i).type() == QVariant::Color) {
                c[i] = qvariant_cast<QColor>(v.at(i));
            } else {
                c[i] = pal.color((QPalette::ColorRole)(v.at(i).toInt()));
            }
        }
    } else {
        QList<QVariant> v;
        for (i = 0; i < qMin(d->values.count(), 4); i++) {
            ColorData color = parseColorValue(d->values.at(i));
            if(color.type == ColorData::Role) {
                v += QVariant::fromValue<int>(color.role);
                c[i] = pal.color((QPalette::ColorRole)(color.role));
            } else {
                v += QVariant::fromValue<QColor>(color.color);
                c[i] = color.color;
            }
        }
        d->parsed = v;
    }

    if (i == 0) c[0] = c[1] = c[2] = c[3] = QColor();
    else if (i == 1) c[3] = c[2] = c[1] = c[0];
    else if (i == 2) c[2] = c[0], c[3] = c[1];
    else if (i == 3) c[3] = c[1];
}

BorderStyle Declaration::styleValue() const
{
    if (d->values.count() != 1)
        return BorderStyle_None;
    return parseStyleValue(d->values.at(0));
}

void Declaration::styleValues(BorderStyle *s) const
{
    int i;
    for (i = 0; i < qMin(d->values.count(), 4); i++)
        s[i] = parseStyleValue(d->values.at(i));
    if (i == 0) s[0] = s[1] = s[2] = s[3] = BorderStyle_None;
    else if (i == 1) s[3] = s[2] = s[1] = s[0];
    else if (i == 2) s[2] = s[0], s[3] = s[1];
    else if (i == 3) s[3] = s[1];
}

Repeat Declaration::repeatValue() const
{
    if (d->parsed.isValid())
        return static_cast<Repeat>(d->parsed.toInt());
    if (d->values.count() != 1)
        return Repeat_Unknown;
    int v = findKnownValue(d->values.at(0).variant.toString(),
                   repeats, NumKnownRepeats);
    d->parsed = v;
    return static_cast<Repeat>(v);
}

Origin Declaration::originValue() const
{
    if (d->parsed.isValid())
        return static_cast<Origin>(d->parsed.toInt());
    if (d->values.count() != 1)
        return Origin_Unknown;
    int v = findKnownValue(d->values.at(0).variant.toString(),
                               origins, NumKnownOrigins);
    d->parsed = v;
    return static_cast<Origin>(v);
}

PositionMode Declaration::positionValue() const
{
    if (d->parsed.isValid())
        return static_cast<PositionMode>(d->parsed.toInt());
    if (d->values.count() != 1)
        return PositionMode_Unknown;
    int v = findKnownValue(d->values.at(0).variant.toString(),
                           positions, NumKnownPositionModes);
    d->parsed = v;
    return static_cast<PositionMode>(v);
}

Attachment Declaration::attachmentValue() const
{
    if (d->parsed.isValid())
        return static_cast<Attachment>(d->parsed.toInt());
    if (d->values.count() != 1)
        return Attachment_Unknown;
    int v = findKnownValue(d->values.at(0).variant.toString(),
                           attachments, NumKnownAttachments);
    d->parsed = v;
    return static_cast<Attachment>(v);
}

int Declaration::styleFeaturesValue() const
{
    Q_ASSERT(d->propertyId == QtStyleFeatures);
    if (d->parsed.isValid())
        return d->parsed.toInt();
    int features = StyleFeature_None;
    for (int i = 0; i < d->values.count(); i++) {
        features |= static_cast<int>(findKnownValue(d->values.value(i).variant.toString(),
                                     styleFeatures, NumKnownStyleFeatures));
    }
    d->parsed = features;
    return features;
}

QString Declaration::uriValue() const
{
    if (d->values.isEmpty() || d->values.at(0).type != Value::Uri)
        return QString();
    return d->values.at(0).variant.toString();
}

Qt::Alignment Declaration::alignmentValue() const
{
    if (d->parsed.isValid())
        return Qt::Alignment(d->parsed.toInt());
    if (d->values.isEmpty() || d->values.count() > 2)
        return Qt::AlignLeft | Qt::AlignTop;

    Qt::Alignment v = parseAlignment(d->values.constData(), d->values.count());
    d->parsed = int(v);
    return v;
}

void Declaration::borderImageValue(QString *image, int *cuts,
                                   TileMode *h, TileMode *v) const
{
    const DeclarationData *d = this->d.data(); // make it const and shadow d
    *image = uriValue();
    for (int i = 0; i < 4; i++)
        cuts[i] = -1;
    *h = *v = TileMode_Stretch;

    if (d->values.count() < 2)
        return;

    if (d->values.at(1).type == Value::Number) { // cuts!
        int i;
        for (i = 0; i < qMin(d->values.count()-1, 4); i++) {
            const Value& v = d->values.at(i+1);
            if (v.type != Value::Number)
                break;
            cuts[i] = v.variant.toString().toInt();
        }
        if (i == 0) cuts[0] = cuts[1] = cuts[2] = cuts[3] = 0;
        else if (i == 1) cuts[3] = cuts[2] = cuts[1] = cuts[0];
        else if (i == 2) cuts[2] = cuts[0], cuts[3] = cuts[1];
        else if (i == 3) cuts[3] = cuts[1];
    }

    if (d->values.last().type == Value::Identifier) {
        *v = static_cast<TileMode>(findKnownValue(d->values.last().variant.toString(),
                                      tileModes, NumKnownTileModes));
    }
    if (d->values[d->values.count() - 2].type == Value::Identifier) {
        *h = static_cast<TileMode>
                (findKnownValue(d->values[d->values.count()-2].variant.toString(),
                                        tileModes, NumKnownTileModes));
    } else
        *h = *v;
}

bool Declaration::borderCollapseValue() const
{
    if (d->values.count() != 1)
        return false;
    else
        return d->values.at(0).toString() == QLatin1String("collapse");
}

QIcon Declaration::iconValue() const
{
    if (d->parsed.isValid())
        return qvariant_cast<QIcon>(d->parsed);

    QIcon icon;
    for (int i = 0; i < d->values.count();) {
        const Value &value = d->values.at(i++);
        if (value.type != Value::Uri)
            break;
        QString uri = value.variant.toString();
        QIcon::Mode mode = QIcon::Normal;
        QIcon::State state = QIcon::Off;
        for (int j = 0; j < 2; j++) {
            if (i != d->values.count() && d->values.at(i).type == Value::KnownIdentifier) {
                switch (d->values.at(i).variant.toInt()) {
                case Value_Disabled: mode = QIcon::Disabled; break;
                case Value_Active: mode = QIcon::Active; break;
                case Value_Selected: mode = QIcon::Selected; break;
                case Value_Normal: mode = QIcon::Normal; break;
                case Value_On: state = QIcon::On; break;
                case Value_Off: state = QIcon::Off; break;
                default: break;
                }
                ++i;
            } else {
                break;
            }
        }

        // QIcon is soo broken
        if (icon.isNull())
            icon = QIcon(uri);
        else
            icon.addPixmap(uri, mode, state);

        if (i == d->values.count())
            break;

        if (d->values.at(i).type == Value::TermOperatorComma)
            i++;
    }

    d->parsed = QVariant::fromValue<QIcon>(icon);
    return icon;
}

///////////////////////////////////////////////////////////////////////////////
// Selector
int Selector::specificity() const
{
    int val = 0;
    for (int i = 0; i < basicSelectors.count(); ++i) {
        const BasicSelector &sel = basicSelectors.at(i);
        if (!sel.elementName.isEmpty())
            val += 1;

        val += (sel.pseudos.count() + sel.attributeSelectors.count()) * 0x10;
        val += sel.ids.count() * 0x100;
    }
    return val;
}

QString Selector::pseudoElement() const
{
    const BasicSelector& bs = basicSelectors.last();
    if (!bs.pseudos.isEmpty() && bs.pseudos.at(0).type == PseudoClass_Unknown)
        return bs.pseudos.at(0).name;
    return QString();
}

quint64 Selector::pseudoClass(quint64 *negated) const
{
    const BasicSelector& bs = basicSelectors.last();
    if (bs.pseudos.isEmpty())
        return PseudoClass_Unspecified;
    quint64 pc = PseudoClass_Unknown;
    for (int i = !pseudoElement().isEmpty(); i < bs.pseudos.count(); i++) {
        const Pseudo &pseudo = bs.pseudos.at(i);
        if (pseudo.type == PseudoClass_Unknown)
            return PseudoClass_Unknown;
        if (!pseudo.negated)
            pc |= pseudo.type;
        else if (negated)
            *negated |= pseudo.type;
    }
    return pc;
}

///////////////////////////////////////////////////////////////////////////////
// StyleSheet
void StyleSheet::buildIndexes(Qt::CaseSensitivity nameCaseSensitivity)
{
    QVector<StyleRule> universals;
    for (int i = 0; i < styleRules.count(); ++i) {
        const StyleRule &rule = styleRules.at(i);
        QVector<Selector> universalsSelectors;
        for (int j = 0; j < rule.selectors.count(); ++j) {
            const Selector& selector = rule.selectors.at(j);

            if (selector.basicSelectors.isEmpty())
                continue;

            if (selector.basicSelectors.at(0).relationToNext == BasicSelector::NoRelation) {
                if (selector.basicSelectors.count() != 1)
                    continue;
            } else if (selector.basicSelectors.count() <= 1) {
                continue;
            }

            const BasicSelector &sel = selector.basicSelectors.at(selector.basicSelectors.count() - 1);

            if (!sel.ids.isEmpty()) {
                StyleRule nr;
                nr.selectors += selector;
                nr.declarations = rule.declarations;
                nr.order = i;
                idIndex.insert(sel.ids.at(0), nr);
            } else if (!sel.elementName.isEmpty()) {
                StyleRule nr;
                nr.selectors += selector;
                nr.declarations = rule.declarations;
                nr.order = i;
                QString name = sel.elementName;
                if (nameCaseSensitivity == Qt::CaseInsensitive)
                    name = std::move(name).toLower();
                nameIndex.insert(name, nr);
            } else {
                universalsSelectors += selector;
            }
        }
        if (!universalsSelectors.isEmpty()) {
            StyleRule nr;
            nr.selectors = universalsSelectors;
            nr.declarations = rule.declarations;
            nr.order = i;
            universals << nr;
        }
    }
    styleRules = universals;
}

///////////////////////////////////////////////////////////////////////////////
// StyleSelector
StyleSelector::~StyleSelector()
{
}

bool StyleSelector::nodeNameEquals(NodePtr node, const QString& nodeName) const
{
    return nodeNames(node).contains(nodeName, nameCaseSensitivity);
}

QStringList StyleSelector::nodeIds(NodePtr node) const
{
    return QStringList(attribute(node, QLatin1String("id")));
}

bool StyleSelector::selectorMatches(const Selector &selector, NodePtr node)
{
    if (selector.basicSelectors.isEmpty())
        return false;

    if (selector.basicSelectors.at(0).relationToNext == BasicSelector::NoRelation) {
        if (selector.basicSelectors.count() != 1)
            return false;
        return basicSelectorMatches(selector.basicSelectors.at(0), node);
    }
    if (selector.basicSelectors.count() <= 1)
        return false;

    int i = selector.basicSelectors.count() - 1;
    node = duplicateNode(node);
    bool match = true;

    BasicSelector sel = selector.basicSelectors.at(i);
    do {
        match = basicSelectorMatches(sel, node);
        if (!match) {
            if (i == selector.basicSelectors.count() - 1) // first element must always match!
                break;
            if (sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor &&
                sel.relationToNext != BasicSelector::MatchNextSelectorIfIndirectAdjecent)
                break;
        }

        if (match || (sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor &&
                      sel.relationToNext != BasicSelector::MatchNextSelectorIfIndirectAdjecent))
            --i;

        if (i < 0)
            break;

        sel = selector.basicSelectors.at(i);
        if (sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor
            || sel.relationToNext == BasicSelector::MatchNextSelectorIfParent) {

            NodePtr nextParent = parentNode(node);
            freeNode(node);
            node = nextParent;
        } else if (sel.relationToNext == BasicSelector::MatchNextSelectorIfDirectAdjecent
                  || sel.relationToNext == BasicSelector::MatchNextSelectorIfIndirectAdjecent) {
            NodePtr previousSibling = previousSiblingNode(node);
            freeNode(node);
            node = previousSibling;
        }
        if (isNullNode(node)) {
            match = false;
            break;
        }
   } while (i >= 0 && (match || sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor
                             || sel.relationToNext == BasicSelector::MatchNextSelectorIfIndirectAdjecent));

    freeNode(node);

    return match;
}

bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node)
{
    if (!sel.attributeSelectors.isEmpty()) {
        if (!hasAttributes(node))
            return false;

        for (int i = 0; i < sel.attributeSelectors.count(); ++i) {
            const QCss::AttributeSelector &a = sel.attributeSelectors.at(i);

            const QString attrValue = attribute(node, a.name);
            if (attrValue.isNull())
                return false;

            switch (a.valueMatchCriterium) {
            case QCss::AttributeSelector::NoMatch:
                break;
            case QCss::AttributeSelector::MatchEqual:
                if (attrValue != a.value)
                    return false;
                break;
            case QCss::AttributeSelector::MatchIncludes: {
                const auto lst = attrValue.splitRef(QLatin1Char(' '));
                if (!lst.contains(QStringRef(&a.value)))
                    return false;
                break;
            }
            case QCss::AttributeSelector::MatchDashMatch: {
                const QString dashPrefix = a.value + QLatin1Char('-');
                if (attrValue != a.value && !attrValue.startsWith(dashPrefix))
                    return false;
                break;
            }
            case QCss::AttributeSelector::MatchBeginsWith:
                if (!attrValue.startsWith(a.value))
                    return false;
                break;
            case QCss::AttributeSelector::MatchEndsWith:
                if (!attrValue.endsWith(a.value))
                    return false;
                break;
            case QCss::AttributeSelector::MatchContains:
                if (!attrValue.contains(a.value))
                    return false;
                break;
            }
        }
    }

    if (!sel.elementName.isEmpty()
        && !nodeNameEquals(node, sel.elementName))
            return false;

    if (!sel.ids.isEmpty()
        && sel.ids != nodeIds(node))
            return false;

    return true;
}

void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOrigin origin,
                               int depth, QMultiMap<uint, StyleRule> *weightedRules)
{
    for (int j = 0; j < rule.selectors.count(); ++j) {
        const Selector& selector = rule.selectors.at(j);
        if (selectorMatches(selector, node)) {
            uint weight = rule.order
                        + selector.specificity() *0x100
                        + (uint(origin) + depth)*0x100000;
            StyleRule newRule = rule;
            if(rule.selectors.count() > 1) {
                newRule.selectors.resize(1);
                newRule.selectors[0] = selector;
            }
            //We might have rules with the same weight if they came from a rule with several selectors
            weightedRules->insert(weight, newRule);
        }
    }
}

// Returns style rules that are in ascending order of specificity
// Each of the StyleRule returned will contain exactly one Selector
QVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
{
    QVector<StyleRule> rules;
    if (styleSheets.isEmpty())
        return rules;

    QMultiMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below

    //prune using indexed stylesheet
    for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) {
        const StyleSheet &styleSheet = styleSheets.at(sheetIdx);
        for (int i = 0; i < styleSheet.styleRules.count(); ++i) {
            matchRule(node, styleSheet.styleRules.at(i), styleSheet.origin, styleSheet.depth, &weightedRules);
        }

        if (!styleSheet.idIndex.isEmpty()) {
            QStringList ids = nodeIds(node);
            for (int i = 0; i < ids.count(); i++) {
                const QString &key = ids.at(i);
                QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.idIndex.constFind(key);
                while (it != styleSheet.idIndex.constEnd() && it.key() == key) {
                    matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
                    ++it;
                }
            }
        }
        if (!styleSheet.nameIndex.isEmpty()) {
            QStringList names = nodeNames(node);
            for (int i = 0; i < names.count(); i++) {
                QString name = names.at(i);
                if (nameCaseSensitivity == Qt::CaseInsensitive)
                    name = std::move(name).toLower();
                QMultiHash<QString, StyleRule>::const_iterator it = styleSheet.nameIndex.constFind(name);
                while (it != styleSheet.nameIndex.constEnd() && it.key() == name) {
                    matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
                    ++it;
                }
            }
        }
        if (!medium.isEmpty()) {
            for (int i = 0; i < styleSheet.mediaRules.count(); ++i) {
                if (styleSheet.mediaRules.at(i).media.contains(medium, Qt::CaseInsensitive)) {
                    for (int j = 0; j < styleSheet.mediaRules.at(i).styleRules.count(); ++j) {
                        matchRule(node, styleSheet.mediaRules.at(i).styleRules.at(j), styleSheet.origin,
                               styleSheet.depth, &weightedRules);
                    }
                }
            }
        }
    }

    rules.reserve(weightedRules.count());
    QMap<uint, StyleRule>::const_iterator it = weightedRules.constBegin();
    for ( ; it != weightedRules.constEnd() ; ++it)
        rules += *it;

    return rules;
}

// for qtexthtmlparser which requires just the declarations with Enabled state
// and without pseudo elements
QVector<Declaration> StyleSelector::declarationsForNode(NodePtr node, const char *extraPseudo)
{
    QVector<Declaration> decls;
    QVector<StyleRule> rules = styleRulesForNode(node);
    for (int i = 0; i < rules.count(); i++) {
        const Selector& selector = rules.at(i).selectors.at(0);
        const QString pseudoElement = selector.pseudoElement();

        if (extraPseudo && pseudoElement == QLatin1String(extraPseudo)) {
            decls += rules.at(i).declarations;
            continue;
        }

        if (!pseudoElement.isEmpty()) // skip rules with pseudo elements
            continue;
        quint64 pseudoClass = selector.pseudoClass();
        if (pseudoClass == PseudoClass_Enabled || pseudoClass == PseudoClass_Unspecified)
            decls += rules.at(i).declarations;
    }
    return decls;
}

static inline bool isHexDigit(const char c)
{
    return (c >= '0' && c <= '9')
           || (c >= 'a' && c <= 'f')
           || (c >= 'A' && c <= 'F')
           ;
}

QString Scanner::preprocess(const QString &input, bool *hasEscapeSequences)
{
    QString output = input;

    if (hasEscapeSequences)
        *hasEscapeSequences = false;

    int i = 0;
    while (i < output.size()) {
        if (output.at(i) == QLatin1Char('\\')) {

            ++i;
            // test for unicode hex escape
            int hexCount = 0;
            const int hexStart = i;
            while (i < output.size()
                   && isHexDigit(output.at(i).toLatin1())
                   && hexCount < 7) {
                ++hexCount;
                ++i;
            }
            if (hexCount == 0) {
                if (hasEscapeSequences)
                    *hasEscapeSequences = true;
                continue;
            }

            hexCount = qMin(hexCount, 6);
            bool ok = false;
            ushort code = output.midRef(hexStart, hexCount).toUShort(&ok, 16);
            if (ok) {
                output.replace(hexStart - 1, hexCount + 1, QChar(code));
                i = hexStart;
            } else {
                i = hexStart;
            }
        } else {
            ++i;
        }
    }
    return output;
}

int QCssScanner_Generated::handleCommentStart()
{
    while (pos < input.size() - 1) {
        if (input.at(pos) == QLatin1Char('*')
            && input.at(pos + 1) == QLatin1Char('/')) {
            pos += 2;
            break;
        }
        ++pos;
    }
    return S;
}

void Scanner::scan(const QString &preprocessedInput, QVector<Symbol> *symbols)
{
    QCssScanner_Generated scanner(preprocessedInput);
    Symbol sym;
    int tok = scanner.lex();
    while (tok != -1) {
        sym.token = static_cast<QCss::TokenType>(tok);
        sym.text = scanner.input;
        sym.start = scanner.lexemStart;
        sym.len = scanner.lexemLength;
        symbols->append(sym);
        tok = scanner.lex();
    }
}

QString Symbol::lexem() const
{
    QString result;
    if (len > 0)
        result.reserve(len);
    for (int i = 0; i < len; ++i) {
        if (text.at(start + i) == QLatin1Char('\\') && i < len - 1)
            ++i;
        result += text.at(start + i);
    }
    return result;
}

Parser::Parser(const QString &css, bool isFile)
{
    init(css, isFile);
}

Parser::Parser()
{
    index = 0;
    errorIndex = -1;
    hasEscapeSequences = false;
}

void Parser::init(const QString &css, bool isFile)
{
    QString styleSheet = css;
    if (isFile) {
        QFile file(css);
        if (file.open(QFile::ReadOnly)) {
            sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/');
            QTextStream stream(&file);
            styleSheet = stream.readAll();
        } else {
            qWarning() << "QCss::Parser - Failed to load file " << css;
            styleSheet.clear();
        }
    } else {
        sourcePath.clear();
    }

    hasEscapeSequences = false;
    symbols.clear();
    symbols.reserve(8);
    Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
    index = 0;
    errorIndex = -1;
}

bool Parser::parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity)
{
    if (testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("charset"))) {
        while (test(S) || test(CDO) || test(CDC)) {}
        if (!next(STRING)) return false;
        if (!next(SEMICOLON)) return false;
    }

    while (test(S) || test(CDO) || test(CDC)) {}

    while (testImport()) {
        ImportRule rule;
        if (!parseImport(&rule)) return false;
        styleSheet->importRules.append(rule);
        while (test(S) || test(CDO) || test(CDC)) {}
    }

    do {
        if (testMedia()) {
            MediaRule rule;
            if (!parseMedia(&rule)) return false;
            styleSheet->mediaRules.append(rule);
        } else if (testPage()) {
            PageRule rule;
            if (!parsePage(&rule)) return false;
            styleSheet->pageRules.append(rule);
        } else if (testRuleset()) {
            StyleRule rule;
            if (!parseRuleset(&rule)) return false;
            styleSheet->styleRules.append(rule);
        } else if (test(ATKEYWORD_SYM)) {
            if (!until(RBRACE)) return false;
        } else if (hasNext()) {
            return false;
        }
        while (test(S) || test(CDO) || test(CDC)) {}
    } while (hasNext());
    styleSheet->buildIndexes(nameCaseSensitivity);
    return true;
}

Symbol Parser::errorSymbol()
{
    if (errorIndex == -1) return Symbol();
    return symbols.at(errorIndex);
}

static inline void removeOptionalQuotes(QString *str)
{
    if (!str->startsWith(QLatin1Char('\''))
        && !str->startsWith(QLatin1Char('\"')))
        return;
    str->remove(0, 1);
    str->chop(1);
}

bool Parser::parseImport(ImportRule *importRule)
{
    skipSpace();

    if (test(STRING)) {
        importRule->href = lexem();
    } else {
        if (!testAndParseUri(&importRule->href)) return false;
    }
    removeOptionalQuotes(&importRule->href);

    skipSpace();

    if (testMedium()) {
        if (!parseMedium(&importRule->media)) return false;

        while (test(COMMA)) {
            skipSpace();
            if (!parseNextMedium(&importRule->media)) return false;
        }
    }

    if (!next(SEMICOLON)) return false;

    skipSpace();
    return true;
}

bool Parser::parseMedia(MediaRule *mediaRule)
{
    do {
        skipSpace();
        if (!parseNextMedium(&mediaRule->media)) return false;
    } while (test(COMMA));

    if (!next(LBRACE)) return false;
    skipSpace();

    while (testRuleset()) {
        StyleRule rule;
        if (!parseRuleset(&rule)) return false;
        mediaRule->styleRules.append(rule);
    }

    if (!next(RBRACE)) return false;
    skipSpace();
    return true;
}

bool Parser::parseMedium(QStringList *media)
{
    media->append(lexem());
    skipSpace();
    return true;
}

bool Parser::parsePage(PageRule *pageRule)
{
    skipSpace();

    if (testPseudoPage())
        if (!parsePseudoPage(&pageRule->selector)) return false;

    skipSpace();
    if (!next(LBRACE)) return false;

    do {
        skipSpace();
        Declaration decl;
        if (!parseNextDeclaration(&decl)) return false;
        if (!decl.isEmpty())
            pageRule->declarations.append(decl);
    } while (test(SEMICOLON));

    if (!next(RBRACE)) return false;
    skipSpace();
    return true;
}

bool Parser::parsePseudoPage(QString *selector)
{
    if (!next(IDENT)) return false;
    *selector = lexem();
    return true;
}

bool Parser::parseNextOperator(Value *value)
{
    if (!hasNext()) return true;
    switch (next()) {
        case SLASH: value->type = Value::TermOperatorSlash; skipSpace(); break;
        case COMMA: value->type = Value::TermOperatorComma; skipSpace(); break;
        default: prev(); break;
    }
    return true;
}

bool Parser::parseCombinator(BasicSelector::Relation *relation)
{
    *relation = BasicSelector::NoRelation;
    if (lookup() == S) {
        *relation = BasicSelector::MatchNextSelectorIfAncestor;
        skipSpace();
    } else {
        prev();
    }
    if (test(PLUS)) {
        *relation = BasicSelector::MatchNextSelectorIfDirectAdjecent;
    } else if (test(GREATER)) {
        *relation = BasicSelector::MatchNextSelectorIfParent;
    } else if (test(TILDE)) {
        *relation = BasicSelector::MatchNextSelectorIfIndirectAdjecent;
    }
    skipSpace();
    return true;
}

bool Parser::parseProperty(Declaration *decl)
{
    decl->d->property = lexem();
    decl->d->propertyId = static_cast<Property>(findKnownValue(decl->d->property, properties, NumProperties));
    decl->d->inheritable = isInheritable(decl->d->propertyId);
    skipSpace();
    return true;
}

bool Parser::parseRuleset(StyleRule *styleRule)
{
    Selector sel;
    if (!parseSelector(&sel)) return false;
    styleRule->selectors.append(sel);

    while (test(COMMA)) {
        skipSpace();
        Selector sel;
        if (!parseNextSelector(&sel)) return false;
        styleRule->selectors.append(sel);
    }

    skipSpace();
    if (!next(LBRACE)) return false;
    const int declarationStart = index;

    do {
        skipSpace();
        Declaration decl;
        const int rewind = index;
        if (!parseNextDeclaration(&decl)) {
            index = rewind;
            const bool foundSemicolon = until(SEMICOLON);
            const int semicolonIndex = index;

            index = declarationStart;
            const bool foundRBrace = until(RBRACE);

            if (foundSemicolon && semicolonIndex < index) {
                decl = Declaration();
                index = semicolonIndex - 1;
            } else {
                skipSpace();
                return foundRBrace;
            }
        }
        if (!decl.isEmpty())
            styleRule->declarations.append(decl);
    } while (test(SEMICOLON));

    if (!next(RBRACE)) return false;
    skipSpace();
    return true;
}

bool Parser::parseSelector(Selector *sel)
{
    BasicSelector basicSel;
    if (!parseSimpleSelector(&basicSel)) return false;
    while (testCombinator()) {
        if (!parseCombinator(&basicSel.relationToNext)) return false;

        if (!testSimpleSelector()) break;
        sel->basicSelectors.append(basicSel);

        basicSel = BasicSelector();
        if (!parseSimpleSelector(&basicSel)) return false;
    }
    sel->basicSelectors.append(basicSel);
    return true;
}

bool Parser::parseSimpleSelector(BasicSelector *basicSel)
{
    int minCount = 0;
    if (lookupElementName()) {
        if (!parseElementName(&basicSel->elementName)) return false;
    } else {
        prev();
        minCount = 1;
    }
    bool onceMore;
    int count = 0;
    do {
        onceMore = false;
        if (test(HASH)) {
            QString theid = lexem();
            // chop off leading #
            theid.remove(0, 1);
            basicSel->ids.append(theid);
            onceMore = true;
        } else if (testClass()) {
            onceMore = true;
            AttributeSelector a;
            a.name = QLatin1String("class");
            a.valueMatchCriterium = AttributeSelector::MatchIncludes;
            if (!parseClass(&a.value)) return false;
            basicSel->attributeSelectors.append(a);
        } else if (testAttrib()) {
            onceMore = true;
            AttributeSelector a;
            if (!parseAttrib(&a)) return false;
            basicSel->attributeSelectors.append(a);
        } else if (testPseudo()) {
            onceMore = true;
            Pseudo ps;
            if (!parsePseudo(&ps)) return false;
            basicSel->pseudos.append(ps);
        }
        if (onceMore) ++count;
    } while (onceMore);
    return count >= minCount;
}

bool Parser::parseClass(QString *name)
{
    if (!next(IDENT)) return false;
    *name = lexem();
    return true;
}

bool Parser::parseElementName(QString *name)
{
    switch (lookup()) {
        case STAR: name->clear(); break;
        case IDENT: *name = lexem(); break;
        default: return false;
    }
    return true;
}

bool Parser::parseAttrib(AttributeSelector *attr)
{
    skipSpace();
    if (!next(IDENT)) return false;
    attr->name = lexem();
    skipSpace();

    if (test(EQUAL)) {
        attr->valueMatchCriterium = AttributeSelector::MatchEqual;
    } else if (test(INCLUDES)) {
        attr->valueMatchCriterium = AttributeSelector::MatchIncludes;
    } else if (test(DASHMATCH)) {
        attr->valueMatchCriterium = AttributeSelector::MatchDashMatch;
    } else if (test(BEGINSWITH)) {
        attr->valueMatchCriterium = AttributeSelector::MatchBeginsWith;
    } else if (test(ENDSWITH)) {
        attr->valueMatchCriterium = AttributeSelector::MatchEndsWith;
    } else if (test(CONTAINS)) {
        attr->valueMatchCriterium = AttributeSelector::MatchContains;
    } else {
        return next(RBRACKET);
    }

    skipSpace();

    if (!test(IDENT) && !test(STRING)) return false;
    attr->value = unquotedLexem();

    skipSpace();
    return next(RBRACKET);
}

bool Parser::parsePseudo(Pseudo *pseudo)
{
    (void)test(COLON);
    pseudo->negated = test(EXCLAMATION_SYM);
    if (test(IDENT)) {
        pseudo->name = lexem();
        pseudo->type = static_cast<quint64>(findKnownValue(pseudo->name, pseudos, NumPseudos));
        return true;
    }
    if (!next(FUNCTION)) return false;
    pseudo->function = lexem();
    // chop off trailing parenthesis
    pseudo->function.chop(1);
    skipSpace();
    if (!test(IDENT)) return false;
    pseudo->name = lexem();
    skipSpace();
    return next(RPAREN);
}

bool Parser::parseNextDeclaration(Declaration *decl)
{
    if (!testProperty())
        return true; // not an error!
    if (!parseProperty(decl)) return false;
    if (!next(COLON)) return false;
    skipSpace();
    if (!parseNextExpr(&decl->d->values)) return false;
    if (testPrio())
        if (!parsePrio(decl)) return false;
    return true;
}

bool Parser::testPrio()
{
    const int rewind = index;
    if (!test(EXCLAMATION_SYM)) return false;
    skipSpace();
    if (!test(IDENT)) {
        index = rewind;
        return false;
    }
    if (lexem().compare(QLatin1String("important"), Qt::CaseInsensitive) != 0) {
        index = rewind;
        return false;
    }
    return true;
}

bool Parser::parsePrio(Declaration *declaration)
{
    declaration->d->important = true;
    skipSpace();
    return true;
}

bool Parser::parseExpr(QVector<Value> *values)
{
    Value val;
    if (!parseTerm(&val)) return false;
    values->append(val);
    bool onceMore;
    do {
        onceMore = false;
        val = Value();
        if (!parseNextOperator(&val)) return false;
        if (val.type != QCss::Value::Unknown)
            values->append(val);
        if (testTerm()) {
            onceMore = true;
            val = Value();
            if (!parseTerm(&val)) return false;
            values->append(val);
        }
    } while (onceMore);
    return true;
}

bool Parser::testTerm()
{
    return test(PLUS) || test(MINUS)
           || test(NUMBER)
           || test(PERCENTAGE)
           || test(LENGTH)
           || test(STRING)
           || test(IDENT)
           || testHexColor()
           || testFunction();
}

bool Parser::parseTerm(Value *value)
{
    QString str = lexem();
    bool haveUnary = false;
    if (lookup() == PLUS || lookup() == MINUS) {
        haveUnary = true;
        if (!hasNext()) return false;
        next();
        str += lexem();
    }

    value->variant = str;
    value->type = QCss::Value::String;
    switch (lookup()) {
        case NUMBER:
            value->type = Value::Number;
            value->variant.convert(QVariant::Double);
            break;
        case PERCENTAGE:
            value->type = Value::Percentage;
            str.chop(1); // strip off %
            value->variant = str;
            break;
        case LENGTH:
            value->type = Value::Length;
            break;

        case STRING:
            if (haveUnary) return false;
            value->type = Value::String;
            str.chop(1);
            str.remove(0, 1);
            value->variant = str;
            break;
        case IDENT: {
            if (haveUnary) return false;
            value->type = Value::Identifier;
            const int theid = findKnownValue(str, values, NumKnownValues);
            if (theid != 0) {
                value->type = Value::KnownIdentifier;
                value->variant = theid;
            }
            break;
        }
        default: {
            if (haveUnary) return false;
            prev();
            if (testHexColor()) {
                QColor col;
                if (!parseHexColor(&col)) return false;
                value->type = Value::Color;
                value->variant = col;
            } else if (testFunction()) {
                QString name, args;
                if (!parseFunction(&name, &args)) return false;
                if (name == QLatin1String("url")) {
                    value->type = Value::Uri;
                    removeOptionalQuotes(&args);
                    if (QFileInfo(args).isRelative() && !sourcePath.isEmpty()) {
                        args.prepend(sourcePath);
                    }
                    value->variant = args;
                } else {
                    value->type = Value::Function;
                    value->variant = QStringList() << name << args;
                }
            } else {
                return recordError();
            }
            return true;
        }
    }
    skipSpace();
    return true;
}

bool Parser::parseFunction(QString *name, QString *args)
{
    *name = lexem();
    name->chop(1);
    // until(RPAREN) needs FUNCTION token at index-1 to work properly
    int start = index;
    skipSpace();
    std::swap(start, index);
    if (!until(RPAREN)) return false;
    for (int i = start; i < index - 1; ++i)
        args->append(symbols.at(i).lexem());
    /*
    if (!nextExpr(&arguments)) return false;
    if (!next(RPAREN)) return false;
    */
    skipSpace();
    return true;
}

bool Parser::parseHexColor(QColor *col)
{
    col->setNamedColor(lexem());
    if (!col->isValid()) {
        qWarning("QCssParser::parseHexColor: Unknown color name '%s'",lexem().toLatin1().constData());
        return false;
    }
    skipSpace();
    return true;
}

bool Parser::testAndParseUri(QString *uri)
{
    const int rewind = index;
    if (!testFunction()) return false;

    QString name, args;
    if (!parseFunction(&name, &args)) {
        index = rewind;
        return false;
    }
    if (name.compare(QLatin1String("url"), Qt::CaseInsensitive) != 0) {
        index = rewind;
        return false;
    }
    *uri = args;
    removeOptionalQuotes(uri);
    return true;
}

bool Parser::testSimpleSelector()
{
    return testElementName()
           || (test(HASH))
           || testClass()
           || testAttrib()
           || testPseudo();
}

bool Parser::next(QCss::TokenType t)
{
    if (hasNext() && next() == t)
        return true;
    return recordError();
}

bool Parser::test(QCss::TokenType t)
{
    if (index >= symbols.count())
        return false;
    if (symbols.at(index).token == t) {
        ++index;
        return true;
    }
    return false;
}

QString Parser::unquotedLexem() const
{
    QString s = lexem();
    if (lookup() == STRING) {
        s.chop(1);
        s.remove(0, 1);
    }
    return s;
}

QString Parser::lexemUntil(QCss::TokenType t)
{
    QString lexem;
    while (hasNext() && next() != t)
        lexem += symbol().lexem();
    return lexem;
}

bool Parser::until(QCss::TokenType target, QCss::TokenType target2)
{
    int braceCount = 0;
    int brackCount = 0;
    int parenCount = 0;
    if (index) {
        switch(symbols.at(index-1).token) {
        case LBRACE: ++braceCount; break;
        case LBRACKET: ++brackCount; break;
        case FUNCTION:
        case LPAREN: ++parenCount; break;
        default: ;
        }
    }
    while (index < symbols.size()) {
        QCss::TokenType t = symbols.at(index++).token;
        switch (t) {
        case LBRACE: ++braceCount; break;
        case RBRACE: --braceCount; break;
        case LBRACKET: ++brackCount; break;
        case RBRACKET: --brackCount; break;
        case FUNCTION:
        case LPAREN: ++parenCount; break;
        case RPAREN: --parenCount; break;
        default: break;
        }
        if ((t == target || (target2 != NONE && t == target2))
            && braceCount <= 0
            && brackCount <= 0
            && parenCount <= 0)
            return true;

        if (braceCount < 0 || brackCount < 0 || parenCount < 0) {
            --index;
            break;
        }
    }
    return false;
}

bool Parser::testTokenAndEndsWith(QCss::TokenType t, QLatin1String str)
{
    if (!test(t)) return false;
    if (!lexem().endsWith(str, Qt::CaseInsensitive)) {
        prev();
        return false;
    }
    return true;
}

QT_END_NAMESPACE
#endif // QT_NO_CSSPARSER
