/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qtest.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlengine.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/qstylehints.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
#include "../../shared/util.h"

class tst_qquickapplication : public QQmlDataTest
{
    Q_OBJECT
public:
    tst_qquickapplication();

private slots:
    void active();
    void state();
    void layoutDirection();
    void font();
    void inputMethod();
    void styleHints();
    void cleanup();
    void displayName();
    void platformName();

private:
    QQmlEngine engine;
};

tst_qquickapplication::tst_qquickapplication()
{
}

void tst_qquickapplication::cleanup()
{
    if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
        QCoreApplication::processEvents();
    }
}

void tst_qquickapplication::active()
{
    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; "
                      "Item { "
                      "    property bool active: Qt.application.active; "
                      "    property bool active2: false; "
                      "    Connections { "
                      "        target: Qt.application; "
                      "        onActiveChanged: active2 = Qt.application.active; "
                      "    } "
                      "}", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickWindow window;
    item->setParentItem(window.contentItem());

    // If the platform plugin has the ApplicationState capability, app activation originate from it
    // as a result of a system event. We therefore have to simulate these events here.
    if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {

        // Flush pending events, in case the platform have already queued real application state events
        QWindowSystemInterface::flushWindowSystemEvents();

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
        QWindowSystemInterface::flushWindowSystemEvents();
        QVERIFY(item->property("active").toBool());
        QVERIFY(item->property("active2").toBool());

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
        QWindowSystemInterface::flushWindowSystemEvents();
        QVERIFY(!item->property("active").toBool());
        QVERIFY(!item->property("active2").toBool());
    } else {
        // Otherwise, app activation is triggered by window activation.
        window.show();
        window.requestActivate();
        QVERIFY(QTest::qWaitForWindowActive(&window));
        QCOMPARE(QGuiApplication::focusWindow(), &window);
        QVERIFY(item->property("active").toBool());
        QVERIFY(item->property("active2").toBool());

        // not active again
        QWindowSystemInterface::handleWindowActivated(nullptr);
        QTRY_VERIFY(QGuiApplication::focusWindow() != &window);
        QVERIFY(!item->property("active").toBool());
        QVERIFY(!item->property("active2").toBool());
    }
}

void tst_qquickapplication::state()
{
    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; "
                      "Item { "
                      "    property int state: Qt.application.state; "
                      "    property int state2: Qt.ApplicationInactive; "
                      "    Connections { "
                      "        target: Qt.application; "
                      "        onStateChanged: state2 = Qt.application.state; "
                      "    } "
                      "    Component.onCompleted: state2 = Qt.application.state; "
                      "}", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickWindow window;
    item->setParentItem(window.contentItem());

    // If the platform plugin has the ApplicationState capability, state changes originate from it
    // as a result of a system event. We therefore have to simulate these events here.
    if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {

        // Flush pending events, in case the platform have already queued real application state events
        QWindowSystemInterface::flushWindowSystemEvents();

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
        QWindowSystemInterface::flushWindowSystemEvents();
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationActive);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationActive);

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
        QWindowSystemInterface::flushWindowSystemEvents();
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationInactive);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationInactive);

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
        QWindowSystemInterface::flushWindowSystemEvents();
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationSuspended);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationSuspended);

        QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
        QWindowSystemInterface::flushWindowSystemEvents();
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationHidden);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationHidden);

    } else {
        // Otherwise, the application can only be in two states, Active and Inactive. These are
        // triggered by window activation.
        window.show();
        window.requestActivate();
        QVERIFY(QTest::qWaitForWindowActive(&window));
        QCOMPARE(QGuiApplication::focusWindow(), &window);
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationActive);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationActive);

        // not active again
        QWindowSystemInterface::handleWindowActivated(nullptr);
        QTRY_VERIFY(QGuiApplication::focusWindow() != &window);
        QCOMPARE(Qt::ApplicationState(item->property("state").toInt()), Qt::ApplicationInactive);
        QCOMPARE(Qt::ApplicationState(item->property("state2").toInt()), Qt::ApplicationInactive);
    }
}

void tst_qquickapplication::layoutDirection()
{

    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    // not mirrored
    QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight);

    // mirrored
    QGuiApplication::setLayoutDirection(Qt::RightToLeft);
    QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft);

    // not mirrored again
    QGuiApplication::setLayoutDirection(Qt::LeftToRight);
    QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight);
}

void tst_qquickapplication::font()
{
    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; Item { property font defaultFont: Qt.application.font }", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    QVariant defaultFontProperty = item->property("defaultFont");
    QVERIFY(defaultFontProperty.isValid());
    QCOMPARE(defaultFontProperty.type(), QVariant::Font);
    QCOMPARE(defaultFontProperty.value<QFont>(), qApp->font());
}

void tst_qquickapplication::inputMethod()
{
    // technically not in QQuickApplication, but testing anyway here
    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; Item { property variant inputMethod: Qt.inputMethod }", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    // check that the inputMethod property maches with application's input method
    QCOMPARE(qvariant_cast<QObject*>(item->property("inputMethod")), qApp->inputMethod());
}

void tst_qquickapplication::styleHints()
{
    // technically not in QQuickApplication, but testing anyway here
    QQmlComponent component(&engine);
    component.setData("import QtQuick 2.0; Item { property variant styleHints: Qt.styleHints }", QUrl::fromLocalFile(""));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    QCOMPARE(qvariant_cast<QObject*>(item->property("styleHints")), qApp->styleHints());
}

void tst_qquickapplication::displayName()
{
    QString name[3] = { QStringLiteral("APP NAME 0"),
                        QStringLiteral("APP NAME 1"),
                        QStringLiteral("APP NAME 2")
                      };

    QQmlComponent component(&engine, testFileUrl("tst_displayname.qml"));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    QCoreApplication::setApplicationName(name[0]);
    QCOMPARE(qvariant_cast<QString>(item->property("displayName")), name[0]);

    QGuiApplication::setApplicationName(name[1]);
    QCOMPARE(qvariant_cast<QString>(item->property("displayName")), name[1]);

    QMetaObject::invokeMethod(item, "updateDisplayName", Q_ARG(QVariant, QVariant(name[2])));
    QCOMPARE(QGuiApplication::applicationDisplayName(), name[2]);
}

void tst_qquickapplication::platformName()
{
    // Set up QML component
    QQmlComponent component(&engine, testFileUrl("tst_platformname.qml"));
    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
    QVERIFY(item);
    QQuickView view;
    item->setParentItem(view.rootObject());

    // Get native platform name
    QString guiApplicationPlatformName = QGuiApplication::platformName();
    QVERIFY(!guiApplicationPlatformName.isEmpty());

    // Get platform name from QML component and verify it's same
    QString qmlPlatformName = qvariant_cast<QString>(item->property("platformName"));
    QCOMPARE(qmlPlatformName, guiApplicationPlatformName);
}

QTEST_MAIN(tst_qquickapplication)

#include "tst_qquickapplication.moc"
