/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the $MODULE$ 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 <QtGui>
#include <QtWidgets>
#include <QtTest>
#include <qpa/qwindowsysteminterface.h>

// #include <QDebug>

class tst_QScrollerWidget : public QWidget
{
public:
    tst_QScrollerWidget()
        : QWidget()
    {
        reset();
    }

    void reset()
    {
        receivedPrepare = false;
        receivedScroll = false;
        receivedFirst = false;
        receivedLast = false;
        receivedOvershoot = false;
    }

    bool event(QEvent *e)
    {
        switch (e->type()) {
        case QEvent::Gesture:
            e->setAccepted(false); // better reject the event or QGestureManager will make trouble
            return false;

        case QEvent::ScrollPrepare:
            {
                receivedPrepare = true;
                QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e);
                se->setViewportSize(QSizeF(100,100));
                se->setContentPosRange(scrollArea);
                se->setContentPos(scrollPosition);
                se->accept();
                return true;
            }

        case QEvent::Scroll:
            {
                receivedScroll = true;
                QScrollEvent *se = static_cast<QScrollEvent *>(e);
                // qDebug() << "Scroll for"<<this<<"pos"<<se->scrollPos()<<"ov"<<se->overshoot()<<"first"<<se->isFirst()<<"last"<<se->isLast();

                if (se->scrollState() == QScrollEvent::ScrollStarted)
                    receivedFirst = true;
                if (se->scrollState() == QScrollEvent::ScrollFinished)
                    receivedLast = true;

                currentPos = se->contentPos();
                overshoot = se->overshootDistance();
                if (!qFuzzyCompare(overshoot.x() + 1.0, 1.0) ||
                    !qFuzzyCompare(overshoot.y() + 1.0, 1.0))
                    receivedOvershoot = true;
                return true;
            }

        default:
            return QObject::event(e);
        }
    }


    QRectF scrollArea;
    QPointF scrollPosition;

    bool receivedPrepare;
    bool receivedScroll;
    bool receivedFirst;
    bool receivedLast;
    bool receivedOvershoot;

    QPointF currentPos;
    QPointF overshoot;
};


class tst_QScroller : public QObject
{
    Q_OBJECT
public:
    tst_QScroller() { }
    ~tst_QScroller() { }

private:
    void kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);
    void kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd);

private slots:
    void staticScrollers();
    void scrollerProperties();
    void scrollTo();
    void scroll();
    void overshoot();
    void multipleWindows();

private:
    QTouchDevice *m_touchScreen = QTest::createTouchDevice();
};

/*! \internal
    Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling.
    Tests some in between states but does not wait until scrolling is finished.
*/
void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
{
    sw->scrollPosition = from;
    sw->currentPos= from;

    QScroller *s1 = QScroller::scroller(sw);
    QCOMPARE(s1->state(), QScroller::Inactive);

    QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties();

    QTouchEvent::TouchPoint rawTouchPoint;
    rawTouchPoint.setId(0);

    // send the touch begin event
    QTouchEvent::TouchPoint touchPoint(0);
    touchPoint.setState(Qt::TouchPointPressed);
    touchPoint.setPos(touchStart);
    touchPoint.setScenePos(touchStart);
    touchPoint.setScreenPos(touchStart);
    QTouchEvent touchEvent1(QEvent::TouchBegin,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointPressed,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent1);

    QCOMPARE(s1->state(), QScroller::Pressed);

    // send the touch update far enough to trigger a scroll
    QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second.
    touchPoint.setPos(touchUpdate);
    touchPoint.setScenePos(touchUpdate);
    touchPoint.setScreenPos(touchUpdate);
    QTouchEvent touchEvent2(QEvent::TouchUpdate,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointMoved,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent2);

    QCOMPARE(s1->state(), QScroller::Dragging);
    QCOMPARE(sw->receivedPrepare, true);


    QTRY_COMPARE(sw->receivedFirst, true);
    QCOMPARE(sw->receivedScroll, true);
    QCOMPARE(sw->receivedOvershoot, false);

    // note that the scrolling goes in a different direction than the mouse move
    QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart;
    QVERIFY(qAbs(sw->currentPos.x() - calculatedPos.x()) < 1.0);
    QVERIFY(qAbs(sw->currentPos.y() - calculatedPos.y()) < 1.0);

    // send the touch end
    touchPoint.setPos(touchEnd);
    touchPoint.setScenePos(touchEnd);
    touchPoint.setScreenPos(touchEnd);
    QTouchEvent touchEvent5(QEvent::TouchEnd,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointReleased,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent5);
}

/*! \internal
    Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling.
    This function does not have any in between tests, it does not expect the scroller to actually scroll.
*/
void tst_QScroller::kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd)
{
    sw->scrollPosition = from;
    sw->currentPos = from;

    QScroller *s1 = QScroller::scroller(sw);
    QCOMPARE(s1->state(), QScroller::Inactive);

    QScrollerProperties sp1 = s1->scrollerProperties();
    int fps = 60;

    QTouchEvent::TouchPoint rawTouchPoint;
    rawTouchPoint.setId(0);

    // send the touch begin event
    QTouchEvent::TouchPoint touchPoint(0);
    touchPoint.setState(Qt::TouchPointPressed);
    touchPoint.setPos(touchStart);
    touchPoint.setScenePos(touchStart);
    touchPoint.setScreenPos(touchStart);
    QTouchEvent touchEvent1(QEvent::TouchBegin,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointPressed,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent1);

    // send the touch update far enough to trigger a scroll
    QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second.
    touchPoint.setPos(touchUpdate);
    touchPoint.setScenePos(touchUpdate);
    touchPoint.setScreenPos(touchUpdate);
    QTouchEvent touchEvent2(QEvent::TouchUpdate,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointMoved,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent2);

    QTest::qWait(1000 / fps * 2); // wait until the first scroll move

    // send the touch end
    touchPoint.setPos(touchEnd);
    touchPoint.setScenePos(touchEnd);
    touchPoint.setScreenPos(touchEnd);
    QTouchEvent touchEvent5(QEvent::TouchEnd,
                            m_touchScreen,
                            Qt::NoModifier,
                            Qt::TouchPointReleased,
                            (QList<QTouchEvent::TouchPoint>() << touchPoint));
    QApplication::sendEvent(sw, &touchEvent5);
}


void tst_QScroller::staticScrollers()
{
    // scrollers
    {
        QObject *o1 = new QObject(this);
        QObject *o2 = new QObject(this);

        // get scroller for object
        QScroller *s1 = QScroller::scroller(o1);
        QScroller *s2 = QScroller::scroller(o2);

        QVERIFY(s1);
        QVERIFY(s2);
        QVERIFY(s1 != s2);

        QVERIFY(!QScroller::scroller(static_cast<const QObject*>(0)));
        QCOMPARE(QScroller::scroller(o1), s1);

        delete o1;
        delete o2;
    }

    // the same for properties
    {
        QObject *o1 = new QObject(this);
        QObject *o2 = new QObject(this);

        // get scroller for object
        QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties();
        QScrollerProperties sp2 = QScroller::scroller(o2)->scrollerProperties();

        // default properties should be the same
        QCOMPARE(sp1, sp2);

        QCOMPARE(QScroller::scroller(o1)->scrollerProperties(), sp1);

        delete o1;
        delete o2;
    }
}

void tst_QScroller::scrollerProperties()
{
    QObject *o1 = new QObject(this);
    QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties();

    QScrollerProperties::ScrollMetric metrics[] =
    {
        QScrollerProperties::MousePressEventDelay,                    // qreal [s]
        QScrollerProperties::DragStartDistance,                       // qreal [m]
        QScrollerProperties::DragVelocitySmoothingFactor,             // qreal [0..1/s]  (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF)
        QScrollerProperties::AxisLockThreshold,                       // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|)

        QScrollerProperties::DecelerationFactor,                      // slope of the curve

        QScrollerProperties::MinimumVelocity,                         // qreal [m/s]
        QScrollerProperties::MaximumVelocity,                         // qreal [m/s]
        QScrollerProperties::MaximumClickThroughVelocity,             // qreal [m/s]

        QScrollerProperties::AcceleratingFlickMaximumTime,            // qreal [s]
        QScrollerProperties::AcceleratingFlickSpeedupFactor,          // qreal [1..]

        QScrollerProperties::SnapPositionRatio,                       // qreal [0..1]
        QScrollerProperties::SnapTime,                                // qreal [s]

        QScrollerProperties::OvershootDragResistanceFactor,           // qreal [0..1]
        QScrollerProperties::OvershootDragDistanceFactor,             // qreal [0..1]
        QScrollerProperties::OvershootScrollDistanceFactor,           // qreal [0..1]
        QScrollerProperties::OvershootScrollTime,                     // qreal [s]
    };

    for (unsigned int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); i++) {
        sp1.setScrollMetric(metrics[i], 0.9);
        QCOMPARE(sp1.scrollMetric(metrics[i]).toDouble(), 0.9);
    }
    sp1.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve(QEasingCurve::OutQuart));
    QCOMPARE(sp1.scrollMetric(QScrollerProperties::ScrollingCurve).toEasingCurve().type(), QEasingCurve::OutQuart);

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff));
    QCOMPARE(sp1.scrollMetric(QScrollerProperties::HorizontalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOff);

    sp1.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
    QCOMPARE(sp1.scrollMetric(QScrollerProperties::VerticalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOn);

    sp1.setScrollMetric(QScrollerProperties::FrameRate, QVariant::fromValue(QScrollerProperties::Fps20));
    QCOMPARE(sp1.scrollMetric(QScrollerProperties::FrameRate).value<QScrollerProperties::FrameRates>(), QScrollerProperties::Fps20);
}

void tst_QScroller::scrollTo()
{
    QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
    sw->show();
    QApplication::setActiveWindow(sw.data());
    if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
        QSKIP("Failed to show and activate window");

    sw->scrollArea = QRectF(0, 0, 1000, 1000);
    sw->scrollPosition = QPointF(500, 500);

    QScroller *s1 = QScroller::scroller(sw.data());
    QCOMPARE(s1->state(), QScroller::Inactive);

    // a normal scroll
    s1->scrollTo(QPointF(100,100), 100);
    QTest::qWait(200);

    QTRY_COMPARE(sw->receivedPrepare, true);
    QCOMPARE(sw->receivedScroll, true);
    QCOMPARE(sw->receivedFirst, true);
    QCOMPARE(sw->receivedLast, true);
    QCOMPARE(sw->receivedOvershoot, false);
    QTRY_VERIFY(qFuzzyCompare(sw->currentPos.x(), 100));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 100));
}

void tst_QScroller::scroll()
{
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
    // -- good case. normal scroll
    QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget());
    sw->scrollArea = QRectF(0, 0, 1000, 1000);
    QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
    sw->setGeometry(100, 100, 400, 300);
    sw->show();
    QApplication::setActiveWindow(sw.data());
    if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
        QSKIP("Failed to show and activate window");

    QScroller *s1 = QScroller::scroller(sw.data());
    kineticScroll(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
    // now we should be scrolling
    QTRY_COMPARE(s1->state(), QScroller::Scrolling);

    // wait until finished, check that no further first scroll is sent
    sw->receivedFirst = false;
    sw->receivedScroll = false;
    QTRY_VERIFY(s1->state() != QScroller::Scrolling);

    QCOMPARE(sw->receivedFirst, false);
    QCOMPARE(sw->receivedScroll, true);
    QCOMPARE(sw->receivedLast, true);
    QVERIFY(sw->currentPos.x() < 400);
    QVERIFY(sw->currentPos.y() < 400);

    // -- try to scroll when nothing to scroll

    sw->reset();
    sw->scrollArea = QRectF(0, 0, 0, 1000);
    kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    QCOMPARE(sw->currentPos.x(), 0.0);
    QCOMPARE(sw->currentPos.y(), 500.0);
#endif
}

void tst_QScroller::overshoot()
{
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
    QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
    sw->scrollArea = QRectF(0, 0, 1000, 1000);
    QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
    sw->setGeometry(100, 100, 400, 300);
    sw->show();
    QApplication::setActiveWindow(sw.data());
    if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
        QSKIP("Failed to show and activate window");

    QScroller *s1 = QScroller::scroller(sw.data());
    QScrollerProperties sp1 = s1->scrollerProperties();

    sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5);
    sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2);
    sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2);

    // -- try to scroll with overshoot (when scrollable good case)

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
    s1->setScrollerProperties(sp1);
    kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    //qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
    QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
    QCOMPARE(sw->receivedOvershoot, true);

    // -- try to scroll with overshoot (when scrollable bad case)
    sw->reset();
    sw->scrollArea = QRectF(0, 0, 0, 1000);

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
    s1->setScrollerProperties(sp1);
    kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    //qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
    QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
    QCOMPARE(sw->receivedOvershoot, false);

    // -- try to scroll with overshoot (always on)
    sw->reset();
    sw->scrollArea = QRectF(0, 0, 0, 1000);

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
    s1->setScrollerProperties(sp1);
    kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    //qDebug() << "Overshoot fuzzy: "<<sw->currentPos;

    QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
    QCOMPARE(sw->receivedOvershoot, true);

    // -- try to scroll with overshoot (always off)
    sw->reset();
    sw->scrollArea = QRectF(0, 0, 1000, 1000);

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff));
    s1->setScrollerProperties(sp1);
    kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
    QCOMPARE(sw->receivedOvershoot, false);

    // -- try to scroll with overshoot (always on but max overshoot = 0)
    sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0);
    sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0);
    sw->reset();
    sw->scrollArea = QRectF(0, 0, 1000, 1000);

    sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
    s1->setScrollerProperties(sp1);
    kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));

    QTRY_COMPARE(s1->state(), QScroller::Inactive);

    QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
    QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
    QCOMPARE(sw->receivedOvershoot, false);
#endif
}

void tst_QScroller::multipleWindows()
{
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
    QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget);
    sw1->scrollArea = QRectF(0, 0, 1000, 1000);
    QScroller::grabGesture(sw1.data(), QScroller::TouchGesture);
    sw1->setGeometry(100, 100, 400, 300);

    QScroller *s1 = QScroller::scroller(sw1.data());
    kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
    // now we should be scrolling
    QTRY_COMPARE(s1->state(), QScroller::Scrolling);

    // That was fun! Do it again!
    QScopedPointer<tst_QScrollerWidget> sw2(new tst_QScrollerWidget());
    sw2->scrollArea = QRectF(0, 0, 1000, 1000);
    QScroller::grabGesture(sw2.data(), QScroller::TouchGesture);
    sw2->setGeometry(100, 100, 400, 300);

    QScroller *s2 = QScroller::scroller(sw2.data());
    kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
    // now we should be scrolling
    QTRY_COMPARE(s2->state(), QScroller::Scrolling);

    // wait for both to stop
    QTRY_VERIFY(s1->state() != QScroller::Scrolling);
    QTRY_VERIFY(s2->state() != QScroller::Scrolling);

    sw1.reset(); // destroy one window
    sw2->reset(); // reset the other scroller's internal state
    // make sure we can still scroll the remaining one without crashing (QTBUG-71232)
    kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
#endif
}

QTEST_MAIN(tst_QScroller)

#include "tst_qscroller.moc"
