/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 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.LGPL3 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-3.0.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 (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qstandardgestures_p.h"
#include "qgesture.h"
#include "qgesture_p.h"
#include "qevent.h"
#include "qwidget.h"
#include "qabstractscrollarea.h"
#if QT_CONFIG(graphicsview)
#include <qgraphicssceneevent.h>
#endif
#include "qdebug.h"

#ifndef QT_NO_GESTURES

QT_BEGIN_NAMESPACE

// If the change in scale for a single touch event is out of this range,
// we consider it to be spurious.
static const qreal kSingleStepScaleMax = 2.0;
static const qreal kSingleStepScaleMin = 0.1;

QGesture *QPanGestureRecognizer::create(QObject *target)
{
    if (target && target->isWidgetType()) {
#if (defined(Q_OS_MACX) || defined(Q_OS_WIN)) && !defined(QT_NO_NATIVE_GESTURES)
        // for scroll areas on Windows and OS X we want to use native gestures instead
        if (!qobject_cast<QAbstractScrollArea *>(target->parent()))
            static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
#else
        static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
#endif
    }
    return new QPanGesture;
}

static QPointF panOffset(const QList<QTouchEvent::TouchPoint> &touchPoints, int maxCount)
{
    QPointF result;
    const int count = qMin(touchPoints.size(), maxCount);
    for (int p = 0; p < count; ++p)
        result += touchPoints.at(p).pos() - touchPoints.at(p).startPos();
    return result / qreal(count);
}

QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
                                                            QObject *,
                                                            QEvent *event)
{
    QPanGesture *q = static_cast<QPanGesture *>(state);
    QPanGesturePrivate *d = q->d_func();

    QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
    switch (event->type()) {
    case QEvent::TouchBegin: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        result = QGestureRecognizer::MayBeGesture;
        QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
        d->lastOffset = d->offset = QPointF();
        d->pointCount = m_pointCount;
        break;
    }
    case QEvent::TouchEnd: {
        if (q->state() != Qt::NoGesture) {
            const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
            if (ev->touchPoints().size() == d->pointCount) {
                d->lastOffset = d->offset;
                d->offset = panOffset(ev->touchPoints(), d->pointCount);
            }
            result = QGestureRecognizer::FinishGesture;
        } else {
            result = QGestureRecognizer::CancelGesture;
        }
        break;
    }
    case QEvent::TouchUpdate: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        if (ev->touchPoints().size() >= d->pointCount) {
            d->lastOffset = d->offset;
            d->offset = panOffset(ev->touchPoints(), d->pointCount);
            if (d->offset.x() > 10  || d->offset.y() > 10 ||
                d->offset.x() < -10 || d->offset.y() < -10) {
                q->setHotSpot(ev->touchPoints().first().startScreenPos());
                result = QGestureRecognizer::TriggerGesture;
            } else {
                result = QGestureRecognizer::MayBeGesture;
            }
        }
        break;
    }
    default:
        break;
    }
    return result;
}

void QPanGestureRecognizer::reset(QGesture *state)
{
    QPanGesture *pan = static_cast<QPanGesture*>(state);
    QPanGesturePrivate *d = pan->d_func();

    d->lastOffset = d->offset = QPointF();
    d->acceleration = 0;

    QGestureRecognizer::reset(state);
}


//
// QPinchGestureRecognizer
//

QPinchGestureRecognizer::QPinchGestureRecognizer()
{
}

QGesture *QPinchGestureRecognizer::create(QObject *target)
{
    if (target && target->isWidgetType()) {
        static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
    }
    return new QPinchGesture;
}

QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
                                                              QObject *,
                                                              QEvent *event)
{
    QPinchGesture *q = static_cast<QPinchGesture *>(state);
    QPinchGesturePrivate *d = q->d_func();

    QGestureRecognizer::Result result = QGestureRecognizer::Ignore;

    switch (event->type()) {
    case QEvent::TouchBegin: {
        result = QGestureRecognizer::MayBeGesture;
        break;
    }
    case QEvent::TouchEnd: {
        if (q->state() != Qt::NoGesture) {
            result = QGestureRecognizer::FinishGesture;
        } else {
            result = QGestureRecognizer::CancelGesture;
        }
        break;
    }
    case QEvent::TouchUpdate: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        d->changeFlags = { };
        if (ev->touchPoints().size() == 2) {
            QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
            QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);

            d->hotSpot = p1.screenPos();
            d->isHotSpotSet = true;

            QPointF centerPoint = (p1.screenPos() + p2.screenPos()) / 2.0;
            if (d->isNewSequence) {
                d->startPosition[0] = p1.screenPos();
                d->startPosition[1] = p2.screenPos();
                d->lastCenterPoint = centerPoint;
            } else {
                d->lastCenterPoint = d->centerPoint;
            }
            d->centerPoint = centerPoint;

            d->changeFlags |= QPinchGesture::CenterPointChanged;

            if (d->isNewSequence) {
                d->scaleFactor = 1.0;
                d->lastScaleFactor = 1.0;
            } else {
                d->lastScaleFactor = d->scaleFactor;
                QLineF line(p1.screenPos(), p2.screenPos());
                QLineF lastLine(p1.lastScreenPos(),  p2.lastScreenPos());
                qreal newScaleFactor = line.length() / lastLine.length();
                if (newScaleFactor > kSingleStepScaleMax || newScaleFactor < kSingleStepScaleMin)
                    return QGestureRecognizer::Ignore;
                d->scaleFactor = newScaleFactor;
            }
            d->totalScaleFactor = d->totalScaleFactor * d->scaleFactor;
            d->changeFlags |= QPinchGesture::ScaleFactorChanged;

            qreal angle = QLineF(p1.screenPos(), p2.screenPos()).angle();
            if (angle > 180)
                angle -= 360;
            qreal startAngle = QLineF(p1.startScreenPos(), p2.startScreenPos()).angle();
            if (startAngle > 180)
                startAngle -= 360;
            const qreal rotationAngle = startAngle - angle;
            if (d->isNewSequence)
                d->lastRotationAngle = 0.0;
            else
                d->lastRotationAngle = d->rotationAngle;
            d->rotationAngle = rotationAngle;
            d->totalRotationAngle += d->rotationAngle - d->lastRotationAngle;
            d->changeFlags |= QPinchGesture::RotationAngleChanged;

            d->totalChangeFlags |= d->changeFlags;
            d->isNewSequence = false;
            result = QGestureRecognizer::TriggerGesture;
        } else {
            d->isNewSequence = true;
            if (q->state() == Qt::NoGesture)
                result = QGestureRecognizer::Ignore;
            else
                result = QGestureRecognizer::FinishGesture;
        }
        break;
    }
    default:
        break;
    }
    return result;
}

void QPinchGestureRecognizer::reset(QGesture *state)
{
    QPinchGesture *pinch = static_cast<QPinchGesture *>(state);
    QPinchGesturePrivate *d = pinch->d_func();

    d->totalChangeFlags = d->changeFlags = { };

    d->startCenterPoint = d->lastCenterPoint = d->centerPoint = QPointF();
    d->totalScaleFactor = d->lastScaleFactor = d->scaleFactor = 1;
    d->totalRotationAngle = d->lastRotationAngle = d->rotationAngle = 0;

    d->isNewSequence = true;
    d->startPosition[0] = d->startPosition[1] = QPointF();

    QGestureRecognizer::reset(state);
}

//
// QSwipeGestureRecognizer
//

QSwipeGestureRecognizer::QSwipeGestureRecognizer()
{
}

QGesture *QSwipeGestureRecognizer::create(QObject *target)
{
    if (target && target->isWidgetType()) {
        static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
    }
    return new QSwipeGesture;
}

QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
                                                              QObject *,
                                                              QEvent *event)
{
    QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
    QSwipeGesturePrivate *d = q->d_func();

    QGestureRecognizer::Result result = QGestureRecognizer::Ignore;

    switch (event->type()) {
    case QEvent::TouchBegin: {
        d->velocityValue = 1;
        d->time.start();
        d->state = QSwipeGesturePrivate::Started;
        result = QGestureRecognizer::MayBeGesture;
        break;
    }
    case QEvent::TouchEnd: {
        if (q->state() != Qt::NoGesture) {
            result = QGestureRecognizer::FinishGesture;
        } else {
            result = QGestureRecognizer::CancelGesture;
        }
        break;
    }
    case QEvent::TouchUpdate: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        if (d->state == QSwipeGesturePrivate::NoGesture)
            result = QGestureRecognizer::CancelGesture;
        else if (ev->touchPoints().size() == 3) {
            d->state = QSwipeGesturePrivate::ThreePointsReached;
            QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
            QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
            QTouchEvent::TouchPoint p3 = ev->touchPoints().at(2);

            if (d->lastPositions[0].isNull()) {
                d->lastPositions[0] = p1.startScreenPos().toPoint();
                d->lastPositions[1] = p2.startScreenPos().toPoint();
                d->lastPositions[2] = p3.startScreenPos().toPoint();
            }
            d->hotSpot = p1.screenPos();
            d->isHotSpotSet = true;

            int xDistance = (p1.screenPos().x() - d->lastPositions[0].x() +
                             p2.screenPos().x() - d->lastPositions[1].x() +
                             p3.screenPos().x() - d->lastPositions[2].x()) / 3;
            int yDistance = (p1.screenPos().y() - d->lastPositions[0].y() +
                             p2.screenPos().y() - d->lastPositions[1].y() +
                             p3.screenPos().y() - d->lastPositions[2].y()) / 3;

            const int distance = xDistance >= yDistance ? xDistance : yDistance;
            int elapsedTime = d->time.restart();
            if (!elapsedTime)
                elapsedTime = 1;
            d->velocityValue = 0.9 * d->velocityValue + (qreal) distance / elapsedTime;
            d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();

            static const int MoveThreshold = 50;
            static const int directionChangeThreshold = MoveThreshold / 8;
            if (qAbs(xDistance) > MoveThreshold || qAbs(yDistance) > MoveThreshold) {
                // measure the distance to check if the direction changed
                d->lastPositions[0] = p1.screenPos().toPoint();
                d->lastPositions[1] = p2.screenPos().toPoint();
                d->lastPositions[2] = p3.screenPos().toPoint();
                result = QGestureRecognizer::TriggerGesture;
                // QTBUG-46195, small changes in direction should not cause the gesture to be canceled.
                if (d->verticalDirection == QSwipeGesture::NoDirection || qAbs(yDistance) > directionChangeThreshold) {
                    const QSwipeGesture::SwipeDirection vertical = yDistance > 0
                        ? QSwipeGesture::Down : QSwipeGesture::Up;
                    if (d->verticalDirection != QSwipeGesture::NoDirection && d->verticalDirection != vertical)
                        result = QGestureRecognizer::CancelGesture;
                    d->verticalDirection = vertical;
                }
                if (d->horizontalDirection == QSwipeGesture::NoDirection || qAbs(xDistance) > directionChangeThreshold) {
                    const QSwipeGesture::SwipeDirection horizontal = xDistance > 0
                        ? QSwipeGesture::Right : QSwipeGesture::Left;
                    if (d->horizontalDirection != QSwipeGesture::NoDirection && d->horizontalDirection != horizontal)
                        result = QGestureRecognizer::CancelGesture;
                    d->horizontalDirection = horizontal;
                }
            } else {
                if (q->state() != Qt::NoGesture)
                    result = QGestureRecognizer::TriggerGesture;
                else
                    result = QGestureRecognizer::MayBeGesture;
            }
        } else if (ev->touchPoints().size() > 3) {
            result = QGestureRecognizer::CancelGesture;
        } else { // less than 3 touch points
            switch (d->state) {
            case QSwipeGesturePrivate::NoGesture:
                result = QGestureRecognizer::MayBeGesture;
                break;
            case QSwipeGesturePrivate::Started:
                result = QGestureRecognizer::Ignore;
                break;
            case QSwipeGesturePrivate::ThreePointsReached:
                result = (ev->touchPointStates() & Qt::TouchPointPressed)
                    ? QGestureRecognizer::CancelGesture : QGestureRecognizer::Ignore;
                break;
            }
        }
        break;
    }
    default:
        break;
    }
    return result;
}

void QSwipeGestureRecognizer::reset(QGesture *state)
{
    QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
    QSwipeGesturePrivate *d = q->d_func();

    d->verticalDirection = d->horizontalDirection = QSwipeGesture::NoDirection;
    d->swipeAngle = 0;

    d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
    d->state = QSwipeGesturePrivate::NoGesture;
    d->velocityValue = 0;
    d->time.invalidate();

    QGestureRecognizer::reset(state);
}

//
// QTapGestureRecognizer
//

QTapGestureRecognizer::QTapGestureRecognizer()
{
}

QGesture *QTapGestureRecognizer::create(QObject *target)
{
    if (target && target->isWidgetType()) {
        static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
    }
    return new QTapGesture;
}

QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state,
                                                            QObject *,
                                                            QEvent *event)
{
    QTapGesture *q = static_cast<QTapGesture *>(state);
    QTapGesturePrivate *d = q->d_func();

    const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);

    QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;

    switch (event->type()) {
    case QEvent::TouchBegin: {
        d->position = ev->touchPoints().at(0).pos();
        q->setHotSpot(ev->touchPoints().at(0).screenPos());
        result = QGestureRecognizer::TriggerGesture;
        break;
    }
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd: {
        if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) {
            QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
            QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
            enum { TapRadius = 40 };
            if (delta.manhattanLength() <= TapRadius) {
                if (event->type() == QEvent::TouchEnd)
                    result = QGestureRecognizer::FinishGesture;
                else
                    result = QGestureRecognizer::TriggerGesture;
            }
        }
        break;
    }
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        result = QGestureRecognizer::Ignore;
        break;
    default:
        result = QGestureRecognizer::Ignore;
        break;
    }
    return result;
}

void QTapGestureRecognizer::reset(QGesture *state)
{
    QTapGesture *q = static_cast<QTapGesture *>(state);
    QTapGesturePrivate *d = q->d_func();

    d->position = QPointF();

    QGestureRecognizer::reset(state);
}

//
// QTapAndHoldGestureRecognizer
//

QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer()
{
}

QGesture *QTapAndHoldGestureRecognizer::create(QObject *target)
{
    if (target && target->isWidgetType()) {
        static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents);
    }
    return new QTapAndHoldGesture;
}

QGestureRecognizer::Result
QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
                                        QEvent *event)
{
    QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
    QTapAndHoldGesturePrivate *d = q->d_func();

    if (object == state && event->type() == QEvent::Timer) {
        q->killTimer(d->timerId);
        d->timerId = 0;
        return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
    }

    enum { TapRadius = 40 };

    switch (event->type()) {
#if QT_CONFIG(graphicsview)
    case QEvent::GraphicsSceneMousePress: {
        const QGraphicsSceneMouseEvent *gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
        d->position = gsme->screenPos();
        q->setHotSpot(d->position);
        if (d->timerId)
            q->killTimer(d->timerId);
        d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
        return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
    }
#endif
    case QEvent::MouseButtonPress: {
        const QMouseEvent *me = static_cast<const QMouseEvent *>(event);
        d->position = me->globalPos();
        q->setHotSpot(d->position);
        if (d->timerId)
            q->killTimer(d->timerId);
        d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
        return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
    }
    case QEvent::TouchBegin: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        d->position = ev->touchPoints().at(0).startScreenPos();
        q->setHotSpot(d->position);
        if (d->timerId)
            q->killTimer(d->timerId);
        d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
        return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
    }
#if QT_CONFIG(graphicsview)
    case QEvent::GraphicsSceneMouseRelease:
#endif
    case QEvent::MouseButtonRelease:
    case QEvent::TouchEnd:
        return QGestureRecognizer::CancelGesture; // get out of the MayBeGesture state
    case QEvent::TouchUpdate: {
        const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
        if (d->timerId && ev->touchPoints().size() == 1) {
            QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
            QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
            if (delta.manhattanLength() <= TapRadius)
                return QGestureRecognizer::MayBeGesture;
        }
        return QGestureRecognizer::CancelGesture;
    }
    case QEvent::MouseMove: {
        const QMouseEvent *me = static_cast<const QMouseEvent *>(event);
        QPoint delta = me->globalPos() - d->position.toPoint();
        if (d->timerId && delta.manhattanLength() <= TapRadius)
            return QGestureRecognizer::MayBeGesture;
        return QGestureRecognizer::CancelGesture;
    }
#if QT_CONFIG(graphicsview)
    case QEvent::GraphicsSceneMouseMove: {
        const QGraphicsSceneMouseEvent *gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
        QPoint delta = gsme->screenPos() - d->position.toPoint();
        if (d->timerId && delta.manhattanLength() <= TapRadius)
            return QGestureRecognizer::MayBeGesture;
        return QGestureRecognizer::CancelGesture;
    }
#endif
    default:
        return QGestureRecognizer::Ignore;
    }
}

void QTapAndHoldGestureRecognizer::reset(QGesture *state)
{
    QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state);
    QTapAndHoldGesturePrivate *d = q->d_func();

    d->position = QPointF();
    if (d->timerId)
        q->killTimer(d->timerId);
    d->timerId = 0;

    QGestureRecognizer::reset(state);
}

QT_END_NAMESPACE

#endif // QT_NO_GESTURES
