/****************************************************************************
**
** 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 "../shared/util.h"
#include "qquickabstractdialog_p.h"
#include <QtQml/QQmlComponent>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickView>
#include <QSignalSpy>

class tst_dialogs : public QQmlDataTest
{
    Q_OBJECT
public:

private slots:
    void initTestCase()
    {
        QQmlDataTest::initTestCase();
    }

    //Dialog
    void dialogImplicitWidth_data();
    void dialogImplicitWidth();
    void dialogContentResize();
    void dialogButtonHandler_data();
    void dialogButtonHandler();
    void dialogKeyHandler_data();
    void dialogKeyHandler();
    void dialogWithDynamicTitle();

    // FileDialog
    void fileDialogDefaultModality();
    void fileDialogNonModal();
    void fileDialogNameFilters();
    void fileDialogDefaultSuffix();

private:
};

void tst_dialogs::dialogImplicitWidth_data()
{
    QTest::addColumn<int>("standardButtons");
    QTest::addColumn<int>("minimumHeight");

    QTest::newRow("No buttons") <<
        int(QQuickAbstractDialog::NoButton) <<
        150;
    QTest::newRow("OK button") <<
        int(QQuickAbstractDialog::Ok) <<
        160;
}

void tst_dialogs::dialogImplicitWidth()
{
    QFETCH(int, standardButtons);
    QFETCH(int, minimumHeight);

    /* This is the outerSpacing from DefaultDialogWrapper.qml,
     * which is always present */
    int heightMargins = 12 * 2;
    QQmlEngine engine;
    engine.rootContext()->setContextProperty("buttonsFromTest", standardButtons);
    QQmlComponent component(&engine);
    component.loadUrl(testFileUrl("DialogImplicitSize.qml"));
    QObject *created = component.create();
    QScopedPointer<QObject> cleanup(created);
    QVERIFY2(created, qPrintable(component.errorString()));

    QTRY_VERIFY(created->property("width").toInt() >= 400);
    QTRY_VERIFY(created->property("height").toInt() >= minimumHeight + heightMargins);
}

void tst_dialogs::dialogContentResize()
{
    QQmlEngine engine;
    QQmlComponent component(&engine);
    component.loadUrl(testFileUrl("DialogMinimumSize.qml"));
    QObject *created = component.create();
    QScopedPointer<QObject> cleanup(created);
    QVERIFY2(created, qPrintable(component.errorString()));

    QTRY_COMPARE(created->property("width").toInt(), 400);
    QTRY_COMPARE(created->property("height").toInt(), 300);

    // Check that the content item has been sized up from its implicit size
    QQuickItem *userContent = created->findChild<QQuickItem*>("userContent");
    QVERIFY(userContent);
    QVERIFY(userContent->width() > 350);
    QVERIFY(userContent->height() > 200);
}

void tst_dialogs::dialogButtonHandler_data()
{
    QTest::addColumn<int>("standardButtons");
    QTest::addColumn<bool>("mustBlock");
    QTest::addColumn<QString>("expectedAction");

    QTest::newRow("Cancel, ignored") <<
        int(QQuickAbstractDialog::Cancel) <<
        false <<
        "rejected";
    QTest::newRow("Cancel, blocked") <<
        int(QQuickAbstractDialog::Cancel) <<
        true <<
        "";
    QTest::newRow("OK, ignored") <<
        int(QQuickAbstractDialog::Ok) <<
        false <<
        "accepted";
    QTest::newRow("OK, blocked") <<
        int(QQuickAbstractDialog::Ok) <<
        true <<
        "";
}

void tst_dialogs::dialogButtonHandler()
{
    QFETCH(int, standardButtons);
    QFETCH(bool, mustBlock);
    QFETCH(QString, expectedAction);

    QQmlEngine engine;
    engine.rootContext()->setContextProperty("buttonsFromTest", standardButtons);
    QQmlComponent component(&engine);
    component.loadUrl(testFileUrl("DialogButtonHandler.qml"));
    QObject *root = component.create();
    QScopedPointer<QObject> cleanup(root);
    QVERIFY2(root, qPrintable(component.errorString()));

    root->setProperty("visible", true);
    root->setProperty("mustBlock", mustBlock);

    QQuickWindow *window = root->findChild<QQuickWindow*>();
    QVERIFY(QTest::qWaitForWindowExposed(window));

    /* Hack to find the created buttons: since they are created by a
     * QQuickRepeater, they don't appear on the hierarchy tree; therefore, we
     * first need to find the repeater, and then to get its child. */
    const QList<QQuickItem*> children = root->findChildren<QQuickItem*>();
    QQuickItem *buttonWidget = nullptr;
    for (QQuickItem *child: children) {
        if (qstrcmp(child->metaObject()->className(), "QQuickRepeater") == 0 &&
            child->property("count").toInt() > 0) {
            int index = 0;
            QMetaObject::invokeMethod(child,
                                      "itemAt",
                                      Q_RETURN_ARG(QQuickItem *, buttonWidget),
                                      Q_ARG(int, index));
            break;
        }
    }
    QVERIFY(buttonWidget);

    const QPointF buttonCenterF(buttonWidget->width() / 2,
                                buttonWidget->height() / 2);
    const QPoint buttonCenter = buttonWidget->mapToScene(buttonCenterF).toPoint();

    QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, buttonCenter);
    QTRY_VERIFY(root->property("handlerWasCalled").toBool());

    QCOMPARE(root->property("buttonCode").toInt(), standardButtons);
    QCOMPARE(root->property("keyCode").toInt(), 0);

    QCOMPARE(root->property("actionCalled").toString(), expectedAction);
}

void tst_dialogs::dialogKeyHandler_data()
{
    QTest::addColumn<int>("key");
    QTest::addColumn<bool>("mustBlock");
    QTest::addColumn<int>("expectedButton");
    QTest::addColumn<QString>("expectedAction");

    QTest::newRow("Escape, ignored") <<
        int(Qt::Key_Escape) <<
        false <<
        int(QQuickAbstractDialog::Cancel) <<
        "rejected";
    QTest::newRow("Cancel, blocked") <<
        int(Qt::Key_Escape) <<
        true <<
        int(QQuickAbstractDialog::Cancel) <<
        "";
    QTest::newRow("Enter, ignored") <<
        int(Qt::Key_Enter) <<
        false <<
        int(QQuickAbstractDialog::Ok) <<
        "accepted";
    QTest::newRow("Enter, blocked") <<
        int(Qt::Key_Enter) <<
        true <<
        int(QQuickAbstractDialog::Ok) <<
        "";
}

void tst_dialogs::dialogKeyHandler()
{
    QFETCH(int, key);
    QFETCH(bool, mustBlock);
    QFETCH(int, expectedButton);
    QFETCH(QString, expectedAction);

    QQmlEngine engine;
    QQuickAbstractDialog::StandardButtons buttons =
        QQuickAbstractDialog::Ok | QQuickAbstractDialog::Cancel;
    engine.rootContext()->setContextProperty("buttonsFromTest", int(buttons));
    QQmlComponent component(&engine);
    component.loadUrl(testFileUrl("DialogButtonHandler.qml"));
    QObject *root = component.create();
    QScopedPointer<QObject> cleanup(root);
    QVERIFY2(root, qPrintable(component.errorString()));

    root->setProperty("visible", true);
    root->setProperty("mustBlock", mustBlock);

    QQuickWindow *window = root->findChild<QQuickWindow*>();
    QVERIFY(QTest::qWaitForWindowExposed(window));

    QTest::keyClick(window, Qt::Key(key));
    QTRY_VERIFY(root->property("handlerWasCalled").toBool());

    QCOMPARE(root->property("buttonCode").toInt(), expectedButton);
    QCOMPARE(root->property("keyCode").toInt(), key);

    QCOMPARE(root->property("actionCalled").toString(), expectedAction);
}

void tst_dialogs::fileDialogDefaultModality()
{
    QQuickView *window = new QQuickView;
    QScopedPointer<QQuickWindow> cleanup(window);

    window->setSource(testFileUrl("RectWithFileDialog.qml"));
    window->setGeometry(240,240,1024,320);
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY2(window->rootObject(), qPrintable(window->errors().value(0).toString()));

    // Click to show
    QObject *dlg = qvariant_cast<QObject *>(window->rootObject()->property("fileDialog"));
    QSignalSpy spyVisibilityChanged(dlg, SIGNAL(visibilityChanged()));
    QTest::mouseClick(window, Qt::LeftButton, {}, QPoint(1000, 100));  // show
    QTRY_VERIFY(spyVisibilityChanged.count() > 0);
    int visibilityChangedCount = spyVisibilityChanged.count();
    // Can't hide by clicking the main window, because dialog is modal.
    QTest::mouseClick(window, Qt::LeftButton, {}, QPoint(1000, 100));
    /*
        On OS X, if you send an event directly to a window, the modal dialog
        doesn't block the event, so the window will process it normally. This
        is a different code path compared to having a user click the mouse and
        generate a native event; in that case the OS does the filtering itself,
        and Qt will not even see the event. But simulating real events in the
        test framework is generally unstable. So there isn't a good way to test
        modality on OS X.
        This test sometimes fails on other platforms too.  Maybe it's not reliable
        to try to click the main window in a location which is outside the
        dialog, without checking or guaranteeing it somehow.
    */
    QSKIP("Modality test is flaky in general and doesn't work at all on OS X");
    // So we expect no change in visibility.
    QCOMPARE(spyVisibilityChanged.count(), visibilityChangedCount);

    QCOMPARE(dlg->property("visible").toBool(), true);
    QMetaObject::invokeMethod(dlg, "close");
    QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount);
    visibilityChangedCount = spyVisibilityChanged.count();
    QCOMPARE(dlg->property("visible").toBool(), false);
    QMetaObject::invokeMethod(dlg, "open");
    QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount);
    QCOMPARE(dlg->property("visible").toBool(), true);
    QCOMPARE(dlg->property("modality").toInt(), (int)Qt::WindowModal);
}

void tst_dialogs::fileDialogNonModal()
{
    QQuickView *window = new QQuickView;
    QScopedPointer<QQuickWindow> cleanup(window);

    window->setSource(testFileUrl("RectWithFileDialog.qml"));
    window->setGeometry(240,240,1024,320);
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY2(window->rootObject(), qPrintable(window->errors().value(0).toString()));

    // Click to toggle visibility
    QObject *dlg = qvariant_cast<QObject *>(window->rootObject()->property("fileDialog"));
    dlg->setProperty("modality", QVariant((int)Qt::NonModal));
    QSignalSpy spyVisibilityChanged(dlg, SIGNAL(visibilityChanged()));
    QTest::mouseClick(window, Qt::LeftButton, {}, QPoint(1000, 100));  // show
    QTRY_VERIFY(spyVisibilityChanged.count() > 0);
    int visibilityChangedCount = spyVisibilityChanged.count();
    QCOMPARE(dlg->property("visible").toBool(), true);
    QTest::mouseClick(window, Qt::LeftButton, {}, QPoint(1000, 100));  // hide
    QTRY_VERIFY(spyVisibilityChanged.count() > visibilityChangedCount);
    QCOMPARE(dlg->property("visible").toBool(), false);
#ifdef Q_OS_WIN
    QCOMPARE(dlg->property("modality").toInt(), (int)Qt::ApplicationModal);
#else
    QCOMPARE(dlg->property("modality").toInt(), (int)Qt::NonModal);
#endif
}

void tst_dialogs::fileDialogNameFilters()
{
    QQuickView *window = new QQuickView;
    QScopedPointer<QQuickWindow> cleanup(window);

    window->setSource(testFileUrl("RectWithFileDialog.qml"));
    window->setGeometry(240,240,1024,320);
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY2(window->rootObject(), qPrintable(window->errors().value(0).toString()));

    QObject *dlg = qvariant_cast<QObject *>(window->rootObject()->property("fileDialog"));
    QStringList filters;
    filters << "QML files (*.qml)";
    filters << "Image files (*.jpg, *.png, *.gif)";
    filters << "All files (*)";
    dlg->setProperty("nameFilters", QVariant(filters));
    QCOMPARE(dlg->property("selectedNameFilter").toString(), filters.first());
}

void tst_dialogs::fileDialogDefaultSuffix()
{
    QQuickView *window = new QQuickView;
    QScopedPointer<QQuickWindow> cleanup(window);

    const QUrl sourceUrl = testFileUrl("RectWithFileDialog.qml");
    window->setSource(sourceUrl);
    window->setGeometry(240, 240, 1024, 320);
    window->show();
    QTRY_VERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY(window->rootObject());

    QObject *dlg = qvariant_cast<QObject *>(window->rootObject()->property("fileDialog"));
    QCOMPARE(dlg->property("defaultSuffix").toString(), QString());
    dlg->setProperty("defaultSuffix", "txt");
    QCOMPARE(dlg->property("defaultSuffix").toString(), QString("txt"));
    dlg->setProperty("defaultSuffix", ".txt");
    QCOMPARE(dlg->property("defaultSuffix").toString(), QString("txt"));
    dlg->setProperty("defaultSuffix", QString());
    QCOMPARE(dlg->property("defaultSuffix").toString(), QString());
}

void tst_dialogs::dialogWithDynamicTitle()
{
    QQmlEngine engine;
    QQmlComponent component(&engine);
    component.loadUrl(testFileUrl("DialogWithDynamicTitle.qml"));
    QObject *dlg = component.create();
    QScopedPointer<QObject> cleanup(dlg);
    QVERIFY2(dlg, qPrintable(component.errorString()));
    QWindow *window = dlg->findChild<QWindow *>();
    QVERIFY(window);
    QTRY_COMPARE(window->title(), QLatin1String("Title"));
    dlg->setProperty("newTitle", true);
    QTRY_COMPARE(window->title(), QLatin1String("New Title"));
}

QTEST_MAIN(tst_dialogs)

#include "tst_dialogs.moc"
