/****************************************************************************
**
** Copyright (C) 2018 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 <QtTest/QtTest>
#include <QtTest/QSignalSpy>
#include <QtGui/QStyleHints>
#include <qpa/qwindowsysteminterface.h>
#include <private/qquickpincharea_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/qquickview.h>
#include <QtQml/qqmlcontext.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"

class tst_QQuickPinchArea: public QQmlDataTest
{
    Q_OBJECT
public:
    tst_QQuickPinchArea() { }
private slots:
    void initTestCase();
    void cleanupTestCase();
    void pinchProperties();
    void scale();
    void pan();
    void retouch();
    void cancel();
    void transformedPinchArea_data();
    void transformedPinchArea();

private:
    QQuickView *createView();
    QTouchDevice *device = nullptr;
};
void tst_QQuickPinchArea::initTestCase()
{
    QQmlDataTest::initTestCase();
    if (!device) {
        device = new QTouchDevice;
        device->setType(QTouchDevice::TouchScreen);
        QWindowSystemInterface::registerTouchDevice(device);
    }
}

void tst_QQuickPinchArea::cleanupTestCase()
{

}
void tst_QQuickPinchArea::pinchProperties()
{
    QScopedPointer<QQuickView> window(createView());
    window->setSource(testFileUrl("pinchproperties.qml"));
    window->show();
    QVERIFY(window->rootObject() != nullptr);

    QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
    QQuickPinch *pinch = pinchArea->pinch();
    QVERIFY(pinchArea != nullptr);
    QVERIFY(pinch != nullptr);

    // target
    QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
    QVERIFY(blackRect != nullptr);
    QCOMPARE(blackRect, pinch->target());
    QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
    QVERIFY(rootItem != nullptr);
    QSignalSpy targetSpy(pinch, SIGNAL(targetChanged()));
    pinch->setTarget(rootItem);
    QCOMPARE(targetSpy.count(),1);
    pinch->setTarget(rootItem);
    QCOMPARE(targetSpy.count(),1);

    // axis
    QCOMPARE(pinch->axis(), QQuickPinch::XAndYAxis);
    QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged()));
    pinch->setAxis(QQuickPinch::XAxis);
    QCOMPARE(pinch->axis(), QQuickPinch::XAxis);
    QCOMPARE(axisSpy.count(),1);
    pinch->setAxis(QQuickPinch::XAxis);
    QCOMPARE(axisSpy.count(),1);

    // minimum and maximum drag properties
    QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged()));
    QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged()));
    QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged()));
    QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged()));

    QCOMPARE(pinch->xmin(), 0.0);
    QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width());
    QCOMPARE(pinch->ymin(), 0.0);
    QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height());

    pinch->setXmin(10);
    pinch->setXmax(10);
    pinch->setYmin(10);
    pinch->setYmax(10);

    QCOMPARE(pinch->xmin(), 10.0);
    QCOMPARE(pinch->xmax(), 10.0);
    QCOMPARE(pinch->ymin(), 10.0);
    QCOMPARE(pinch->ymax(), 10.0);

    QCOMPARE(xminSpy.count(),1);
    QCOMPARE(xmaxSpy.count(),1);
    QCOMPARE(yminSpy.count(),1);
    QCOMPARE(ymaxSpy.count(),1);

    pinch->setXmin(10);
    pinch->setXmax(10);
    pinch->setYmin(10);
    pinch->setYmax(10);

    QCOMPARE(xminSpy.count(),1);
    QCOMPARE(xmaxSpy.count(),1);
    QCOMPARE(yminSpy.count(),1);
    QCOMPARE(ymaxSpy.count(),1);

    // minimum and maximum scale properties
    QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged()));
    QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged()));

    QCOMPARE(pinch->minimumScale(), 1.0);
    QCOMPARE(pinch->maximumScale(), 2.0);

    pinch->setMinimumScale(0.5);
    pinch->setMaximumScale(1.5);

    QCOMPARE(pinch->minimumScale(), 0.5);
    QCOMPARE(pinch->maximumScale(), 1.5);

    QCOMPARE(scaleMinSpy.count(),1);
    QCOMPARE(scaleMaxSpy.count(),1);

    pinch->setMinimumScale(0.5);
    pinch->setMaximumScale(1.5);

    QCOMPARE(scaleMinSpy.count(),1);
    QCOMPARE(scaleMaxSpy.count(),1);

    // minimum and maximum rotation properties
    QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged()));
    QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged()));

    QCOMPARE(pinch->minimumRotation(), 0.0);
    QCOMPARE(pinch->maximumRotation(), 90.0);

    pinch->setMinimumRotation(-90.0);
    pinch->setMaximumRotation(45.0);

    QCOMPARE(pinch->minimumRotation(), -90.0);
    QCOMPARE(pinch->maximumRotation(), 45.0);

    QCOMPARE(rotMinSpy.count(),1);
    QCOMPARE(rotMaxSpy.count(),1);

    pinch->setMinimumRotation(-90.0);
    pinch->setMaximumRotation(45.0);

    QCOMPARE(rotMinSpy.count(),1);
    QCOMPARE(rotMaxSpy.count(),1);
}

QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i)
{
    QTouchEvent::TouchPoint touchPoint(id);
    touchPoint.setPos(i->mapFromScene(p));
    touchPoint.setScreenPos(v->mapToGlobal(p));
    touchPoint.setScenePos(p);
    return touchPoint;
}

void tst_QQuickPinchArea::scale()
{
    QQuickView *window = createView();
    QScopedPointer<QQuickView> scope(window);
    window->setSource(testFileUrl("pinchproperties.qml"));
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY(window->rootObject() != nullptr);
    qApp->processEvents();

    QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
    QQuickPinch *pinch = pinchArea->pinch();
    QVERIFY(pinchArea != nullptr);
    QVERIFY(pinch != nullptr);

    QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
    QVERIFY(root != nullptr);

    // target
    QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
    QVERIFY(blackRect != nullptr);

    QPoint p1(80, 80);
    QPoint p2(100, 100);
    {
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
        pinchSequence.press(0, p1, window).commit();
        QQuickTouchUtils::flush(window);
        // In order for the stationary point to remember its previous position,
        // we have to reuse the same pinchSequence object.  Otherwise if we let it
        // be destroyed and then start a new sequence, point 0 will default to being
        // stationary at 0, 0, and PinchArea will filter out that touchpoint because
        // it is outside its bounds.
        pinchSequence.stationary(0).press(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.0);
        QVERIFY(root->property("pinchActive").toBool());

        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.5);
        QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
        QCOMPARE(blackRect->scale(), 1.5);
    }

    // scale beyond bound
    p1 -= QPoint(50,50);
    p2 += QPoint(50,50);
    {
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        QCOMPARE(blackRect->scale(), 2.0);
        pinchSequence.release(0, p1, window).release(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
    }
    QVERIFY(!root->property("pinchActive").toBool());
}

void tst_QQuickPinchArea::pan()
{
    QQuickView *window = createView();
    QScopedPointer<QQuickView> scope(window);
    window->setSource(testFileUrl("pinchproperties.qml"));
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY(window->rootObject() != nullptr);
    qApp->processEvents();

    QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
    QQuickPinch *pinch = pinchArea->pinch();
    QVERIFY(pinchArea != nullptr);
    QVERIFY(pinch != nullptr);

    QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
    QVERIFY(root != nullptr);

    // target
    QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
    QVERIFY(blackRect != nullptr);

    QPoint p1(80, 80);
    QPoint p2(100, 100);
    {
        const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
        pinchSequence.press(0, p1, window).commit();
        QQuickTouchUtils::flush(window);
        // In order for the stationary point to remember its previous position,
        // we have to reuse the same pinchSequence object.
        pinchSequence.stationary(0).press(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        QVERIFY(!root->property("pinchActive").toBool());
        QCOMPARE(root->property("scale").toReal(), -1.0);

        p1 += QPoint(dragThreshold - 1, 0);
        p2 += QPoint(dragThreshold - 1, 0);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        // movement < dragThreshold: pinch not yet active
        QVERIFY(!root->property("pinchActive").toBool());
        QCOMPARE(root->property("scale").toReal(), -1.0);

        // exactly the dragThreshold: pinch starts
        p1 += QPoint(1, 0);
        p2 += QPoint(1, 0);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        QVERIFY(root->property("pinchActive").toBool());
        QCOMPARE(root->property("scale").toReal(), 1.0);

        // Calculation of the center point is tricky at first:
        // center point of the two touch points in item coordinates:
        // scene coordinates: (80, 80) + (dragThreshold, 0), (100, 100) + (dragThreshold, 0)
        //                    = ((180+dT)/2, 180/2) = (90+dT, 90)
        // item  coordinates: (scene) - (50, 50) = (40+dT, 40)
        QCOMPARE(root->property("center").toPointF(), QPointF(40 + dragThreshold, 40));
        // pan started, but no actual movement registered yet:
        // blackrect starts at 50,50
        QCOMPARE(blackRect->x(), 50.0);
        QCOMPARE(blackRect->y(), 50.0);

        p1 += QPoint(10, 0);
        p2 += QPoint(10, 0);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 + dragThreshold, 40));
        QCOMPARE(blackRect->x(), 60.0);
        QCOMPARE(blackRect->y(), 50.0);

        p1 += QPoint(0, 10);
        p2 += QPoint(0, 10);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        // next big surprise: the center is in item local coordinates and the item was just
        // moved 10 to the right... which offsets the center point 10 to the left
        QCOMPARE(root->property("center").toPointF(), QPointF(40 + 10 - 10 + dragThreshold, 40 + 10));
        QCOMPARE(blackRect->x(), 60.0);
        QCOMPARE(blackRect->y(), 60.0);

        p1 += QPoint(10, 10);
        p2 += QPoint(10, 10);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        // now the item moved again, thus the center point of the touch is moved in total by (10, 10)
        QCOMPARE(root->property("center").toPointF(), QPointF(50 + dragThreshold, 50));
        QCOMPARE(blackRect->x(), 70.0);
        QCOMPARE(blackRect->y(), 70.0);
    }

    // pan x beyond bound
    p1 += QPoint(100,100);
    p2 += QPoint(100,100);
    QTest::touchEvent(window, device).move(0, p1, window).move(1, p2, window);
    QQuickTouchUtils::flush(window);

    QCOMPARE(blackRect->x(), 140.0);
    QCOMPARE(blackRect->y(), 170.0);

    QTest::touchEvent(window, device).release(0, p1, window).release(1, p2, window);
    QQuickTouchUtils::flush(window);
    QVERIFY(!root->property("pinchActive").toBool());
}

// test pinch, release one point, touch again to continue pinch
void tst_QQuickPinchArea::retouch()
{
    QQuickView *window = createView();
    QScopedPointer<QQuickView> scope(window);
    window->setSource(testFileUrl("pinchproperties.qml"));
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY(window->rootObject() != nullptr);
    qApp->processEvents();

    QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
    QQuickPinch *pinch = pinchArea->pinch();
    QVERIFY(pinchArea != nullptr);
    QVERIFY(pinch != nullptr);

    QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
    QVERIFY(root != nullptr);

    QSignalSpy startedSpy(pinchArea, SIGNAL(pinchStarted(QQuickPinchEvent*)));
    QSignalSpy finishedSpy(pinchArea, SIGNAL(pinchFinished(QQuickPinchEvent*)));

    // target
    QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
    QVERIFY(blackRect != nullptr);

    QPoint p1(80, 80);
    QPoint p2(100, 100);
    {
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
        pinchSequence.press(0, p1, window).commit();
        QQuickTouchUtils::flush(window);
        // In order for the stationary point to remember its previous position,
        // we have to reuse the same pinchSequence object.
        pinchSequence.stationary(0).press(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.0);
        QVERIFY(root->property("pinchActive").toBool());

        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(startedSpy.count(), 1);

        QCOMPARE(root->property("scale").toReal(), 1.5);
        QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
        QCOMPARE(blackRect->scale(), 1.5);

        QCOMPARE(window->rootObject()->property("pointCount").toInt(), 2);

        QCOMPARE(startedSpy.count(), 1);
        QCOMPARE(finishedSpy.count(), 0);

        // Hold down the first finger but release the second one
        pinchSequence.stationary(0).release(1, p2, window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(startedSpy.count(), 1);
        QCOMPARE(finishedSpy.count(), 0);

        QCOMPARE(window->rootObject()->property("pointCount").toInt(), 1);

        // Keep holding down the first finger and re-touch the second one, then move them both
        pinchSequence.stationary(0).press(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1, window).move(1, p2, window).commit();
        QQuickTouchUtils::flush(window);

        // Lifting and retouching results in onPinchStarted being called again
        QCOMPARE(startedSpy.count(), 2);
        QCOMPARE(finishedSpy.count(), 0);

        QCOMPARE(window->rootObject()->property("pointCount").toInt(), 2);

        pinchSequence.release(0, p1, window).release(1, p2, window).commit();
        QQuickTouchUtils::flush(window);

        QVERIFY(!root->property("pinchActive").toBool());
        QCOMPARE(startedSpy.count(), 2);
        QCOMPARE(finishedSpy.count(), 1);
    }
}

void tst_QQuickPinchArea::cancel()
{
    QQuickView *window = createView();
    QScopedPointer<QQuickView> scope(window);
    window->setSource(testFileUrl("pinchproperties.qml"));
    window->show();
    QVERIFY(QTest::qWaitForWindowExposed(window));
    QVERIFY(window->rootObject() != nullptr);
    qApp->processEvents();

    QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
    QQuickPinch *pinch = pinchArea->pinch();
    QVERIFY(pinchArea != nullptr);
    QVERIFY(pinch != nullptr);

    QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
    QVERIFY(root != nullptr);

    // target
    QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
    QVERIFY(blackRect != nullptr);

    QPoint p1(80, 80);
    QPoint p2(100, 100);
    {
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(window, device);
        pinchSequence.press(0, p1, window).commit();
        QQuickTouchUtils::flush(window);
        // In order for the stationary point to remember its previous position,
        // we have to reuse the same pinchSequence object.  Otherwise if we let it
        // be destroyed and then start a new sequence, point 0 will default to being
        // stationary at 0, 0, and PinchArea will filter out that touchpoint because
        // it is outside its bounds.
        pinchSequence.stationary(0).press(1, p2, window).commit();
        QQuickTouchUtils::flush(window);
        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.0);
        QVERIFY(root->property("pinchActive").toBool());

        p1 -= QPoint(10,10);
        p2 += QPoint(10,10);
        pinchSequence.move(0, p1,window).move(1, p2,window).commit();
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.5);
        QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
        QCOMPARE(blackRect->scale(), 1.5);

        QTouchEvent cancelEvent(QEvent::TouchCancel);
        cancelEvent.setDevice(device);
        QCoreApplication::sendEvent(window, &cancelEvent);
        QQuickTouchUtils::flush(window);

        QCOMPARE(root->property("scale").toReal(), 1.0);
        QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
        QCOMPARE(blackRect->scale(), 1.0);
        QVERIFY(!root->property("pinchActive").toBool());
    }
}

void tst_QQuickPinchArea::transformedPinchArea_data()
{
    QTest::addColumn<QPoint>("p1");
    QTest::addColumn<QPoint>("p2");
    QTest::addColumn<bool>("shouldPinch");

    QTest::newRow("checking inner pinch 1")
        << QPoint(200, 140) << QPoint(200, 260) << true;

    QTest::newRow("checking inner pinch 2")
        << QPoint(140, 200) << QPoint(200, 140) << true;

    QTest::newRow("checking inner pinch 3")
        << QPoint(140, 200) << QPoint(260, 200) << true;

    QTest::newRow("checking outer pinch 1")
        << QPoint(140, 140) << QPoint(260, 260) << false;

    QTest::newRow("checking outer pinch 2")
        << QPoint(140, 140) << QPoint(200, 200) << false;

    QTest::newRow("checking outer pinch 3")
        << QPoint(140, 260) << QPoint(260, 260) << false;
}

void tst_QQuickPinchArea::transformedPinchArea()
{
    QFETCH(QPoint, p1);
    QFETCH(QPoint, p2);
    QFETCH(bool, shouldPinch);

    QQuickView *view = createView();
    QScopedPointer<QQuickView> scope(view);
    view->setSource(testFileUrl("transformedPinchArea.qml"));
    view->show();
    QVERIFY(QTest::qWaitForWindowExposed(view));
    QVERIFY(view->rootObject() != nullptr);
    qApp->processEvents();

    QQuickPinchArea *pinchArea = view->rootObject()->findChild<QQuickPinchArea*>("pinchArea");
    QVERIFY(pinchArea != nullptr);

    const int threshold = qApp->styleHints()->startDragDistance();

    {
        QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(view, device);
        // start pinch
        pinchSequence.press(0, p1, view).commit();
        QQuickTouchUtils::flush(view);
        // In order for the stationary point to remember its previous position,
        // we have to reuse the same pinchSequence object.
        pinchSequence.stationary(0).press(1, p2, view).commit();
        QQuickTouchUtils::flush(view);
        pinchSequence.stationary(0).move(1, p2 + QPoint(threshold * 2, 0), view).commit();
        QQuickTouchUtils::flush(view);
        QCOMPARE(pinchArea->property("pinching").toBool(), shouldPinch);

        // release pinch
        pinchSequence.release(0, p1, view).release(1, p2, view).commit();
        QQuickTouchUtils::flush(view);
        QCOMPARE(pinchArea->property("pinching").toBool(), false);
    }
}

QQuickView *tst_QQuickPinchArea::createView()
{
    QQuickView *window = new QQuickView(nullptr);
    window->setGeometry(0,0,240,320);

    return window;
}

QTEST_MAIN(tst_QQuickPinchArea)

#include "tst_qquickpincharea.moc"
