/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickstyle.h"
#include "qquickstyle_p.h"

#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
#include <QtCore/qdebug.h>
#include <QtCore/qsettings.h>
#include <QtCore/qfileselector.h>
#include <QtCore/qlibraryinfo.h>
#include <QtCore/qmetaobject.h>
#include <QtGui/qcolor.h>
#include <QtGui/qfont.h>
#include <QtGui/qpalette.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlfile.h>

#include <functional>

QT_BEGIN_NAMESPACE

/*!
    \class QQuickStyle
    \brief The QQuickStyle class allows configuring the application style.
    \inmodule QtQuickControls2
    \since 5.7

    QQuickStyle provides API for querying and configuring the application
    \l {Styling Qt Quick Controls}{styles} of Qt Quick Controls.

    \code
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQuickStyle>

    int main(int argc, char *argv[])
    {
        QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);

        QQuickStyle::setStyle("Material");

        QQmlApplicationEngine engine;
        engine.load(QUrl("qrc:/main.qml"));

        return app.exec();
    }
    \endcode

    \note The style must be configured \b before loading QML that imports
    Qt Quick Controls. It is not possible to change the style after the QML
    types have been registered.

    The style can also be specified as a path to a custom style, such as
    \c ":/mystyle". See \l {Creating a Custom Style} for more details about
    building custom styles. Custom styles do not need to implement all controls.
    By default, the styling system uses the \l {Default style} as a fallback
    for controls that a custom style does not provide. It is possible to
    specify a different fallback style to customize or extend one of the
    built-in styles.

    \code
    QQuickStyle::setStyle(":/mystyle");
    QQuickStyle::setFallbackStyle("Material");
    \endcode

    \sa {Styling Qt Quick Controls}
*/

static QStringList envPathList(const QByteArray &var)
{
    QStringList paths;
    if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
        const QByteArray value = qgetenv(var);
        paths += QString::fromLocal8Bit(value).split(QDir::listSeparator(), QString::SkipEmptyParts);
    }
    return paths;
}

static QStringList defaultImportPathList()
{
    QStringList importPaths;
    importPaths.reserve(3);
#ifdef Q_OS_ANDROID
    // androiddeployqt puts the QML files inside a resource file and they are not
    // showing up in the Qml2ImportsPath as a result
    importPaths += QStringLiteral(":/android_rcc_bundle/qml");
#else
# ifndef QT_STATIC
    importPaths += QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
# endif
#endif
    importPaths += QStringLiteral(":/qt-project.org/imports");
    importPaths += QCoreApplication::applicationDirPath();
    return importPaths;
}

struct QQuickStyleSpec
{
    QQuickStyleSpec() : custom(false), resolved(false) { }

    QString name()
    {
        if (!resolved)
            resolve();
        return style.mid(style.lastIndexOf(QLatin1Char('/')) + 1);
    }

    QString path()
    {
        if (!resolved)
            resolve();
        QString s = style;
        if (QQmlFile::isLocalFile(s))
            s = QQmlFile::urlToLocalFileOrQrc(s);
        return s.left(s.lastIndexOf(QLatin1Char('/')) + 1);
    }

    void setStyle(const QString &s)
    {
        style = s;
        resolved = false;
        resolve();
    }

    void setFallbackStyle(const QString &fallback, const QByteArray &method)
    {
        fallbackStyle = fallback;
        fallbackMethod = method;
    }

    static QString findStyle(const QString &path, const QString &name)
    {
        QDir dir(path);
        if (!dir.exists())
            return QString();

        if (name.isEmpty())
            return dir.absolutePath() + QLatin1Char('/');

        const QStringList entries = dir.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot);
        for (const QString &entry : entries) {
            if (entry.compare(name, Qt::CaseInsensitive) == 0)
                return dir.absoluteFilePath(entry);
        }

        return QString();
    }

    void resolve(const QUrl &baseUrl = QUrl())
    {
        if (style.isEmpty())
            style = QGuiApplicationPrivate::styleOverride;
        if (style.isEmpty())
            style = QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_STYLE"));
        if (fallbackStyle.isEmpty())
            setFallbackStyle(QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_FALLBACK_STYLE")), "QT_QUICK_CONTROLS_FALLBACK_STYLE");
#if QT_CONFIG(settings)
        if (style.isEmpty() || fallbackStyle.isEmpty()) {
            QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(QStringLiteral("Controls"));
            if (settings) {
                if (style.isEmpty())
                    style = settings->value(QStringLiteral("Style")).toString();
                if (fallbackStyle.isEmpty())
                    setFallbackStyle(settings->value(QStringLiteral("FallbackStyle")).toString(), ":/qtquickcontrols2.conf");
            }
        }
#endif

        // resolve a path relative to the config
        QString configPath = QFileInfo(resolveConfigFilePath()).path();
        QString stylePath = findStyle(configPath, style);
        if (!stylePath.isEmpty()) {
            style = stylePath;
            resolved = true;
        }

        custom = style.contains(QLatin1Char('/'));

        if (baseUrl.isValid()) {
            QString path = QQmlFile::urlToLocalFileOrQrc(baseUrl);
            QString stylePath = findStyle(path, style);
            if (!stylePath.isEmpty()) {
                style = stylePath;
                resolved = true;
            }
        }

        if (QGuiApplication::instance()) {
            if (!custom) {
                const QStringList stylePaths = QQuickStylePrivate::stylePaths();
                for (const QString &path : stylePaths) {
                    QString stylePath = findStyle(path, style);
                    if (!stylePath.isEmpty()) {
                        custom = !stylePath.startsWith(QQmlFile::urlToLocalFileOrQrc(baseUrl));
                        style = stylePath;
                        resolved = true;
                        break;
                    }
                }
            }
            resolved = true;
        }
    }

    void reset()
    {
        custom = false;
        resolved = false;
        style.clear();
        fallbackStyle.clear();
        fallbackMethod.clear();
        configFilePath.clear();
    }

    QString resolveConfigFilePath()
    {
        if (configFilePath.isEmpty()) {
            configFilePath = QFile::decodeName(qgetenv("QT_QUICK_CONTROLS_CONF"));
            if (configFilePath.isEmpty() || !QFile::exists(configFilePath)) {
                if (!configFilePath.isEmpty())
                    qWarning("QT_QUICK_CONTROLS_CONF=%s: No such file", qPrintable(configFilePath));

                configFilePath = QStringLiteral(":/qtquickcontrols2.conf");
            }
        }
        return configFilePath;
    }

    bool custom;
    bool resolved;
    QString style;
    QString fallbackStyle;
    QByteArray fallbackMethod;
    QString configFilePath;
    QStringList customStylePaths;
};

Q_GLOBAL_STATIC(QQuickStyleSpec, styleSpec)

static QStringList parseStylePathsWithColon(const QString &var)
{
    QStringList paths;
    const QChar colon = QLatin1Char(':');
    int currentIndex = 0;

    do {
        int nextColonIndex = -1;
        QString path;

        if (var.at(currentIndex) == colon) {
            // This is either a list separator, or a qrc path.
            if (var.at(currentIndex + 1) == colon) {
                // It's a double colon (list separator followed by qrc path);
                // find the end of the path.
                nextColonIndex = var.indexOf(colon, currentIndex + 2);
                path = var.mid(currentIndex + 1,
                    nextColonIndex == -1 ? -1 : nextColonIndex - currentIndex - 1);
            } else {
                // It's a single colon.
                nextColonIndex = var.indexOf(colon, currentIndex + 1);
                if (currentIndex == 0) {
                    // If we're at the start of the string, then it's a qrc path.
                    path = var.mid(currentIndex,
                        nextColonIndex == -1 ? -1 : nextColonIndex - currentIndex);
                } else {
                    // Otherwise, it's a separator.
                    path = var.mid(currentIndex + 1,
                        nextColonIndex == -1 ? -1 : nextColonIndex - currentIndex - 1);
                }
            }
        } else {
            // It's a file path.
            nextColonIndex = var.indexOf(colon, currentIndex);
            path = var.mid(currentIndex,
                nextColonIndex == -1 ? -1 : nextColonIndex - currentIndex);
        }

        paths += path;
        currentIndex = nextColonIndex;

        // Keep going until we can't find any more colons,
        // or we're at the last character.
    } while (currentIndex != -1 && currentIndex < var.size() - 1);

    return paths;
}

QStringList QQuickStylePrivate::stylePaths(bool resolve)
{
    // user-requested style path
    QStringList paths;
    if (resolve) {
        QString path = styleSpec()->path();
        if (path.endsWith(QLatin1Char('/')))
            path.chop(1);
        if (!path.isEmpty())
            paths += path;
    }

    if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE_PATH"))) {
        const QString value = QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_STYLE_PATH"));
        const QChar listSeparator = QDir::listSeparator();
        if (listSeparator == QLatin1Char(':')) {
            // Split manually to avoid breaking paths on systems where : is the list separator,
            // since it's also used for qrc paths.
            paths += parseStylePathsWithColon(value);
        } else {
            // Fast/simpler path for systems where something other than : is used as
            // the list separator (such as ';').
            const QStringList customPaths = value.split(listSeparator, QString::SkipEmptyParts);
            paths += customPaths;
        }
    }

    // system/custom style paths
    paths += styleSpec()->customStylePaths;
    paths += envPathList("QT_QUICK_CONTROLS_STYLE_PATH");

    // built-in import paths
    const QString targetPath = QStringLiteral("QtQuick/Controls.2");
    const QStringList importPaths = defaultImportPathList();
    for (const QString &importPath : importPaths) {
        QDir dir(importPath);
        if (dir.cd(targetPath))
            paths += dir.absolutePath();
    }

    paths.removeDuplicates();
    return paths;
}

QString QQuickStylePrivate::fallbackStyle()
{
    return styleSpec()->fallbackStyle;
}

bool QQuickStylePrivate::isCustomStyle()
{
    return styleSpec()->custom;
}

void QQuickStylePrivate::init(const QUrl &baseUrl)
{
    QQuickStyleSpec *spec = styleSpec();
    spec->resolve(baseUrl);

    if (!spec->fallbackStyle.isEmpty()) {
        QString fallbackStyle = spec->findStyle(QQmlFile::urlToLocalFileOrQrc(baseUrl), spec->fallbackStyle);
        if (fallbackStyle.isEmpty()) {
            if (spec->fallbackStyle.compare(QStringLiteral("Default")) != 0) {
                qWarning() << "ERROR: unable to locate fallback style" << spec->fallbackStyle;
                qInfo().nospace().noquote() << spec->fallbackMethod << ": the fallback style must be the name of one of the built-in Qt Quick Controls 2 styles.";
            }
            spec->fallbackStyle.clear();
        }
    }
}

void QQuickStylePrivate::reset()
{
    if (styleSpec())
        styleSpec()->reset();
}

QString QQuickStylePrivate::configFilePath()
{
    return styleSpec()->resolveConfigFilePath();
}

QSharedPointer<QSettings> QQuickStylePrivate::settings(const QString &group)
{
#ifndef QT_NO_SETTINGS
    const QString filePath = QQuickStylePrivate::configFilePath();
    if (QFile::exists(filePath)) {
        QFileSelector selector;
        QSettings *settings = new QSettings(selector.select(filePath), QSettings::IniFormat);
        if (!group.isEmpty())
            settings->beginGroup(group);
        return QSharedPointer<QSettings>(settings);
    }
#endif // QT_NO_SETTINGS
    return QSharedPointer<QSettings>();
}

#if QT_CONFIG(settings)
static void readValue(const QSharedPointer<QSettings> &settings, const QString &name, std::function<void(const QVariant &)> setValue)
{
    const QVariant var = settings->value(name);
    if (var.isValid())
        setValue(var);
}

template <typename Enum>
static Enum toEnumValue(const QVariant &var)
{
    // ### TODO: expose QFont enums to the meta object system using Q_ENUM
    //QMetaEnum enumeration = QMetaEnum::fromType<Enum>();
    //bool ok = false;
    //int value = enumeration.keyToValue(var.toByteArray(), &ok);
    //if (!ok)
    //    value = var.toInt();
    //return static_cast<Enum>(value);

    return static_cast<Enum>(var.toInt());
}

const QFont *QQuickStylePrivate::readFont(const QSharedPointer<QSettings> &settings)
{
    const QVariant var = settings->value(QStringLiteral("Font"));
    if (var.isValid())
        return new QFont(var.value<QFont>());

    QFont f;
    settings->beginGroup(QStringLiteral("Font"));
    readValue(settings, QStringLiteral("Family"), [&f](const QVariant &var) { f.setFamily(var.toString()); });
    readValue(settings, QStringLiteral("PointSize"), [&f](const QVariant &var) { f.setPointSizeF(var.toReal()); });
    readValue(settings, QStringLiteral("PixelSize"), [&f](const QVariant &var) { f.setPixelSize(var.toInt()); });
    readValue(settings, QStringLiteral("StyleHint"), [&f](const QVariant &var) { f.setStyleHint(toEnumValue<QFont::StyleHint>(var.toInt())); });
    readValue(settings, QStringLiteral("Weight"), [&f](const QVariant &var) { f.setWeight(toEnumValue<QFont::Weight>(var)); });
    readValue(settings, QStringLiteral("Style"), [&f](const QVariant &var) { f.setStyle(toEnumValue<QFont::Style>(var.toInt())); });
    settings->endGroup();
    return new QFont(f);
}

static void readColorGroup(const QSharedPointer<QSettings> &settings, QPalette::ColorGroup group, QPalette *palette)
{
    const QStringList keys = settings->childKeys();
    if (keys.isEmpty())
        return;

    static const int index = QPalette::staticMetaObject.indexOfEnumerator("ColorRole");
    Q_ASSERT(index != -1);
    QMetaEnum metaEnum = QPalette::staticMetaObject.enumerator(index);

    for (const QString &key : keys) {
        bool ok = false;
        int role = metaEnum.keyToValue(key.toUtf8(), &ok);
        if (ok)
            palette->setColor(group, static_cast<QPalette::ColorRole>(role), settings->value(key).value<QColor>());
    }
}

const QPalette *QQuickStylePrivate::readPalette(const QSharedPointer<QSettings> &settings)
{
    QPalette p;
    settings->beginGroup(QStringLiteral("Palette"));
    readColorGroup(settings, QPalette::All, &p);

    settings->beginGroup(QStringLiteral("Normal"));
    readColorGroup(settings, QPalette::Normal, &p);
    settings->endGroup();

    settings->beginGroup(QStringLiteral("Disabled"));
    readColorGroup(settings, QPalette::Disabled, &p);
    settings->endGroup();
    return new QPalette(p);
}
#endif // QT_CONFIG(settings)

static bool qt_is_dark_system_theme()
{
    if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
        if (const QPalette *systemPalette = theme->palette(QPlatformTheme::SystemPalette)) {
            const QColor &textColor = systemPalette->color(QPalette::WindowText);
            return textColor.red() > 128 && textColor.blue() > 128 && textColor.green() > 128;
        }
    }
    return false;
}

bool QQuickStylePrivate::isDarkSystemTheme()
{
    static bool dark = qt_is_dark_system_theme();
    return dark;
}

/*!
    Returns the name of the application style.

    \note The application style can be specified by passing a \c -style command
          line argument. Therefore \c name() may not return a fully resolved
          value if called before constructing a QGuiApplication.
*/
QString QQuickStyle::name()
{
    return styleSpec()->name();
}

/*!
    Returns the path of an overridden application style, or an empty
    string if the style is one of the built-in Qt Quick Controls 2 styles.

    \note The application style can be specified by passing a \c -style command
          line argument. Therefore \c path() may not return a fully resolved
          value if called before constructing a QGuiApplication.
*/
QString QQuickStyle::path()
{
    return styleSpec()->path();
}

/*!
    Sets the application style to \a style.

    \note The style must be configured \b before loading QML that imports Qt Quick Controls.
          It is not possible to change the style after the QML types have been registered.

    \sa setFallbackStyle(), {Using Styles in Qt Quick Controls}
*/
void QQuickStyle::setStyle(const QString &style)
{
    if (QQmlMetaType::isModule(QStringLiteral("QtQuick.Controls"), 2, 0)) {
        qWarning() << "ERROR: QQuickStyle::setStyle() must be called before loading QML that imports Qt Quick Controls 2.";
        return;
    }

    styleSpec()->setStyle(style);
}

/*!
    \since 5.8
    Sets the application fallback style to \a style.

    \note The fallback style must be the name of one of the built-in Qt Quick Controls styles, e.g. "Material".

    \note The style must be configured \b before loading QML that imports Qt Quick Controls.
          It is not possible to change the style after the QML types have been registered.

    The fallback style can be also specified by setting the \c QT_QUICK_CONTROLS_FALLBACK_STYLE
    \l {Supported Environment Variables in Qt Quick Controls}{environment variable}.

    \sa setStyle(), {Using Styles in Qt Quick Controls}
*/
void QQuickStyle::setFallbackStyle(const QString &style)
{
    if (QQmlMetaType::isModule(QStringLiteral("QtQuick.Controls"), 2, 0)) {
        qWarning() << "ERROR: QQuickStyle::setFallbackStyle() must be called before loading QML that imports Qt Quick Controls 2.";
        return;
    }

    styleSpec()->setFallbackStyle(style, "QQuickStyle::setFallbackStyle()");
}

/*!
    \since 5.9
    Returns the names of the available styles.

    \note The method must be called \b after creating an instance of QGuiApplication.

    \sa stylePathList(), addStylePath()
*/
QStringList QQuickStyle::availableStyles()
{
    QStringList styles;
    if (!QGuiApplication::instance()) {
        qWarning() << "ERROR: QQuickStyle::availableStyles() must be called after creating an instance of QGuiApplication.";
        return styles;
    }

    const QStringList stylePaths = QQuickStylePrivate::stylePaths();
    for (const QString &path : stylePaths) {
        const QList<QFileInfo> entries = QDir(path).entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
        for (const QFileInfo &entry : entries) {
            const QString name = entry.fileName();
            if (!name.endsWith(QLatin1String(".dSYM")) && name != QLatin1String("designer"))
                styles += name;
        }
    }
    styles.prepend(QStringLiteral("Default"));
    styles.removeDuplicates();
    return styles;
}

/*!
    \since 5.12

    Returns the list of directories where Qt Quick Controls 2 searches for available styles.

    By default, the list contains paths specified in the \c QT_QUICK_CONTROLS_STYLE_PATH
    environment variable, and any existing \c QtQuick/Controls.2 sub-directories in
    \l QQmlEngine::importPathList().

    \sa addStylePath(), availableStyles()
*/
QStringList QQuickStyle::stylePathList()
{
    return QQuickStylePrivate::stylePaths();
}

/*!
    \since 5.12

    Adds \a path as a directory where Qt Quick Controls 2 searches for available styles.

    The \a path may be any local filesystem directory or \l {The Qt Resource System}{Qt Resource} directory.
    For example, the following paths are all valid:

    \list
        \li \c {/path/to/styles/}
        \li \c {file:///path/to/styles/}
        \li \c {:/path/to/styles/}
        \li \c {qrc:/path/to/styles/})
    \endlist

    The \a path will be converted into \l {QDir::canonicalPath}{canonical form} before it is added to
    the style path list.

    The newly added \a path will be first in the stylePathList().

    \sa stylePathList(), availableStyles()
*/
void QQuickStyle::addStylePath(const QString &path)
{
    if (path.isEmpty())
        return;

    const QUrl url = QUrl(path);
    if (url.isRelative() || url.scheme() == QLatin1String("file")
            || (url.scheme().length() == 1 && QFile::exists(path)) ) {  // windows path
        styleSpec()->customStylePaths.prepend(QDir(path).canonicalPath());
    } else if (url.scheme() == QLatin1String("qrc")) {
        styleSpec()->customStylePaths.prepend(QLatin1Char(':') + url.path());
    } else {
        styleSpec()->customStylePaths.prepend(path);
    }
}

QT_END_NAMESPACE
