/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick 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 "qquickpinchhandler_p.h"
#include <QtQml/qqmlinfo.h>
#include <QtQuick/qquickwindow.h>
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
#include <private/qguiapplication_p.h>
#include <private/qquickmultipointhandler_p_p.h>
#include <private/qquickwindow_p.h>
#include <QEvent>
#include <QMouseEvent>
#include <QDebug>
#include <qpa/qplatformnativeinterface.h>
#include <math.h>

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcPinchHandler, "qt.quick.handler.pinch")

/*!
    \qmltype PinchHandler
    \instantiates QQuickPinchHandler
    \inherits MultiPointHandler
    \inqmlmodule QtQuick
    \ingroup qtquick-input-handlers
    \brief Handler for pinch gestures.

    PinchHandler is a handler that interprets a multi-finger gesture to
    interactively rotate, zoom, and drag an Item. Like other Input Handlers,
    by default it is fully functional, and manipulates its \l target,
    which is the Item within which it is declared.

    \snippet pointerHandlers/pinchHandler.qml 0

    It has properties to restrict the range of dragging, rotation, and zoom.

    If it is declared within one Item but is assigned a different \l target, it
    handles events within the bounds of the outer Item but manipulates the
    \c target Item instead:

    \snippet pointerHandlers/pinchHandlerDifferentTarget.qml 0

    A third way to use it is to set \l target to \c null and react to property
    changes in some other way:

    \snippet pointerHandlers/pinchHandlerNullTarget.qml 0

    \image touchpoints-pinchhandler.png

    \sa PinchArea
*/

QQuickPinchHandler::QQuickPinchHandler(QQuickItem *parent)
    : QQuickMultiPointHandler(parent, 2)
{
}

/*!
    \qmlproperty real QtQuick::PinchHandler::minimumScale

    The minimum acceptable \l {Item::scale}{scale} to be applied
    to the \l target.
*/
void QQuickPinchHandler::setMinimumScale(qreal minimumScale)
{
    if (qFuzzyCompare(m_minimumScale, minimumScale))
        return;

    m_minimumScale = minimumScale;
    emit minimumScaleChanged();
}

/*!
    \qmlproperty real QtQuick::PinchHandler::maximumScale

    The maximum acceptable \l {Item::scale}{scale} to be applied
    to the \l target.
*/
void QQuickPinchHandler::setMaximumScale(qreal maximumScale)
{
    if (qFuzzyCompare(m_maximumScale, maximumScale))
        return;

    m_maximumScale = maximumScale;
    emit maximumScaleChanged();
}

/*!
    \qmlproperty real QtQuick::PinchHandler::minimumRotation

    The minimum acceptable \l {Item::rotation}{rotation} to be applied
    to the \l target.
*/
void QQuickPinchHandler::setMinimumRotation(qreal minimumRotation)
{
    if (qFuzzyCompare(m_minimumRotation, minimumRotation))
        return;

    m_minimumRotation = minimumRotation;
    emit minimumRotationChanged();
}

/*!
    \qmlproperty real QtQuick::PinchHandler::maximumRotation

    The maximum acceptable \l {Item::rotation}{rotation} to be applied
    to the \l target.
*/
void QQuickPinchHandler::setMaximumRotation(qreal maximumRotation)
{
    if (qFuzzyCompare(m_maximumRotation, maximumRotation))
        return;

    m_maximumRotation = maximumRotation;
    emit maximumRotationChanged();
}

#if QT_DEPRECATED_SINCE(5, 12)
void QQuickPinchHandler::warnAboutMinMaxDeprecated() const
{
    qmlWarning(this) << "min and max constraints are now part of the xAxis and yAxis properties";
}

void QQuickPinchHandler::setMinimumX(qreal minX)
{
    warnAboutMinMaxDeprecated();
    if (qFuzzyCompare(m_minimumX, minX))
        return;
    m_minimumX = minX;
    emit minimumXChanged();
}

void QQuickPinchHandler::setMaximumX(qreal maxX)
{
    warnAboutMinMaxDeprecated();
    if (qFuzzyCompare(m_maximumX, maxX))
        return;
    m_maximumX = maxX;
    emit maximumXChanged();
}

void QQuickPinchHandler::setMinimumY(qreal minY)
{
    warnAboutMinMaxDeprecated();
    if (qFuzzyCompare(m_minimumY, minY))
        return;
    m_minimumY = minY;
    emit minimumYChanged();
}

void QQuickPinchHandler::setMaximumY(qreal maxY)
{
    warnAboutMinMaxDeprecated();
    if (qFuzzyCompare(m_maximumY, maxY))
        return;
    m_maximumY = maxY;
    emit maximumYChanged();
}
#endif

bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
    if (!QQuickMultiPointHandler::wantsPointerEvent(event))
        return false;

#if QT_CONFIG(gestures)
    if (const auto gesture = event->asPointerNativeGestureEvent()) {
        if (minimumPointCount() == 2) {
            switch (gesture->type()) {
            case Qt::BeginNativeGesture:
            case Qt::EndNativeGesture:
            case Qt::ZoomNativeGesture:
            case Qt::RotateNativeGesture:
                return parentContains(event->point(0));
            default:
                return false;
            }
        } else {
            return false;
        }
    }
#endif

    return true;
}

/*!
    \qmlpropertygroup QtQuick::PinchHandler::xAxis
    \qmlproperty real QtQuick::PinchHandler::xAxis.minimum
    \qmlproperty real QtQuick::PinchHandler::xAxis.maximum
    \qmlproperty bool QtQuick::PinchHandler::xAxis.enabled

    \c xAxis controls the constraints for horizontal translation of the \l target item.

    \c minimum is the minimum acceptable x coordinate of the translation.
    \c maximum is the maximum acceptable x coordinate of the translation.
    If \c enabled is true, horizontal dragging is allowed.
 */

/*!
    \qmlpropertygroup QtQuick::PinchHandler::yAxis
    \qmlproperty real QtQuick::PinchHandler::yAxis.minimum
    \qmlproperty real QtQuick::PinchHandler::yAxis.maximum
    \qmlproperty bool QtQuick::PinchHandler::yAxis.enabled

    \c yAxis controls the constraints for vertical translation of the \l target item.

    \c minimum is the minimum acceptable y coordinate of the translation.
    \c maximum is the maximum acceptable y coordinate of the translation.
    If \c enabled is true, vertical dragging is allowed.
 */

/*!
    \qmlproperty int QtQuick::PinchHandler::minimumTouchPoints

    The pinch begins when this number of fingers are pressed.
    Until then, PinchHandler tracks the positions of any pressed fingers,
    but if it's an insufficient number, it does not scale or rotate
    its \l target, and the \l active property will remain false.
*/

/*!
    \qmlproperty bool QtQuick::PinchHandler::active

    This property is true when all the constraints (epecially \l minimumTouchPoints)
    are satisfied and the \l target, if any, is being manipulated.
*/

void QQuickPinchHandler::onActiveChanged()
{
    QQuickMultiPointHandler::onActiveChanged();
    if (active()) {
        m_startAngles = angles(centroid().sceneGrabPosition());
        m_startDistance = averageTouchPointDistance(centroid().sceneGrabPosition());
        m_activeRotation = 0;
        m_activeTranslation = QVector2D();
        if (const QQuickItem *t = target()) {
            m_startScale = t->scale(); // TODO incompatible with independent x/y scaling
            m_startRotation = t->rotation();
            m_startPos = t->position();
        } else {
            m_startScale = m_accumulatedScale;
            m_startRotation = 0;
        }
        qCDebug(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
    } else {
        qCDebug(lcPinchHandler) << "deactivated with scale" << m_activeScale << "rotation" << m_activeRotation;
    }
}

void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
{
    if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) {
        for (const QQuickHandlerPoint &p : currentPoints())
            qCDebug(lcPinchHandler) << Qt::hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition();
    }
    QQuickMultiPointHandler::handlePointerEventImpl(event);

    qreal dist = 0;
#if QT_CONFIG(gestures)
    if (const auto gesture = event->asPointerNativeGestureEvent()) {
        mutableCentroid().reset(event->point(0));
        switch (gesture->type()) {
        case Qt::EndNativeGesture:
            m_activeScale = 1;
            m_activeRotation = 0;
            m_activeTranslation = QVector2D();
            mutableCentroid().reset();
            setActive(false);
            emit updated();
            return;
        case Qt::ZoomNativeGesture:
            m_activeScale *= 1 + gesture->value();
            break;
        case Qt::RotateNativeGesture:
            m_activeRotation += gesture->value();
            break;
        default:
            // Nothing of interest (which is unexpected, because wantsPointerEvent() should have returned false)
            return;
        }
        if (!active()) {
            setActive(true);
            // Native gestures for 2-finger pinch do not allow dragging, so
            // the centroid won't move during the gesture, and translation stays at zero
            m_activeTranslation = QVector2D();
        }
    } else
#endif // QT_CONFIG(gestures)
    {
        const bool containsReleasedPoints = event->isReleaseEvent();
        QVector<QQuickEventPoint *> chosenPoints;
        for (const QQuickHandlerPoint &p : currentPoints()) {
            QQuickEventPoint *ep = event->pointById(p.id());
            chosenPoints << ep;
        }
        if (!active()) {
            // Verify that at least one of the points has moved beyond threshold needed to activate the handler
            int numberOfPointsDraggedOverThreshold = 0;
            QVector2D accumulatedDrag;
            const QVector2D currentCentroid(centroid().scenePosition());
            const QVector2D pressCentroid(centroid().scenePressPosition());

            const int dragThreshold = QQuickPointerHandler::dragThreshold();
            const int dragThresholdSquared = dragThreshold * dragThreshold;

            double accumulatedCentroidDistance = 0;     // Used to detect scale
            if (event->isPressEvent())
                m_accumulatedStartCentroidDistance = 0;   // Used to detect scale

            float accumulatedMovementMagnitude = 0;

            for (QQuickEventPoint *point : qAsConst(chosenPoints)) {
                if (!containsReleasedPoints) {
                    accumulatedDrag += QVector2D(point->scenePressPosition() - point->scenePosition());
                    /*
                       In order to detect a drag, we want to check if all points have moved more or
                       less in the same direction.

                       We then take each point, and convert the point to a local coordinate system where
                       the centroid is the origin. This is done both for the press positions and the
                       current positions. We will then have two positions:

                       - pressCentroidRelativePosition
                           is the start point relative to the press centroid
                       - currentCentroidRelativePosition
                           is the current point relative to the current centroid

                       If those two points are far enough apart, it might not be considered as a drag
                       anymore. (Note that the threshold will matched to the average of the relative
                       movement of all the points). Therefore, a big relative movement will make a big
                       contribution to the average relative movement.

                       The algorithm then can be described as:
                         For each point:
                          - Calculate vector pressCentroidRelativePosition (from the press centroid to the press position)
                          - Calculate vector currentCentroidRelativePosition (from the current centroid to the current position)
                          - Calculate the relative movement vector:

                             centroidRelativeMovement = currentCentroidRelativePosition - pressCentroidRelativePosition

                           and measure its magnitude. Add the magnitude to the accumulatedMovementMagnitude.

                         Finally, if the accumulatedMovementMagnitude is below some threshold, it means
                         that the points were stationary or they were moved in parallel (e.g. the hand
                         was moved, but the relative position between each finger remained very much
                         the same). This is then used to rule out if there is a rotation or scale.
                    */
                    QVector2D pressCentroidRelativePosition = QVector2D(point->scenePosition()) - currentCentroid;
                    QVector2D currentCentroidRelativePosition = QVector2D(point->scenePressPosition()) - pressCentroid;
                    QVector2D centroidRelativeMovement = currentCentroidRelativePosition - pressCentroidRelativePosition;
                    accumulatedMovementMagnitude += centroidRelativeMovement.length();

                    accumulatedCentroidDistance += qreal(pressCentroidRelativePosition.length());
                    if (event->isPressEvent())
                        m_accumulatedStartCentroidDistance += qreal((QVector2D(point->scenePressPosition()) - pressCentroid).length());
                } else {
                    setPassiveGrab(point);
                }
                if (point->state() == QQuickEventPoint::Pressed) {
                    point->setAccepted(false); // don't stop propagation
                    setPassiveGrab(point);
                }
                Q_D(QQuickMultiPointHandler);
                if (d->dragOverThreshold(point))
                    ++numberOfPointsDraggedOverThreshold;
            }

            const bool requiredNumberOfPointsDraggedOverThreshold = numberOfPointsDraggedOverThreshold >= minimumPointCount() && numberOfPointsDraggedOverThreshold <= maximumPointCount();
            accumulatedMovementMagnitude /= currentPoints().count();

            QVector2D avgDrag = accumulatedDrag / currentPoints().count();
            if (!xAxis()->enabled())
                avgDrag.setX(0);
            if (!yAxis()->enabled())
                avgDrag.setY(0);

            const qreal centroidMovementDelta = qreal((currentCentroid - pressCentroid).length());

            qreal distanceToCentroidDelta = qAbs(accumulatedCentroidDistance - m_accumulatedStartCentroidDistance); // Used to detect scale
            if (numberOfPointsDraggedOverThreshold >= 1) {
                if (requiredNumberOfPointsDraggedOverThreshold && avgDrag.lengthSquared() >= dragThresholdSquared && accumulatedMovementMagnitude < dragThreshold) {
                    // Drag
                    if (grabPoints(chosenPoints))
                        setActive(true);
                } else if (distanceToCentroidDelta > dragThreshold) {    // all points should in accumulation have been moved beyond threshold (?)
                    // Scale
                    if (grabPoints(chosenPoints))
                        setActive(true);
                } else if (distanceToCentroidDelta < dragThreshold && (centroidMovementDelta < dragThreshold)) {
                    // Rotate
                    // Since it wasn't a scale and if we exceeded the dragthreshold, and the
                    // centroid didn't moved much, the points must have been moved around the centroid.
                    if (grabPoints(chosenPoints))
                        setActive(true);
                }
            }
            if (!active())
                return;
        }

        // avoid mapping the minima and maxima, as they might have unmappable values
        // such as -inf/+inf. Because of this we perform the bounding to min/max in local coords.
        // 1. scale
        dist = averageTouchPointDistance(centroid().scenePosition());
        m_activeScale = dist / m_startDistance;
        m_activeScale = qBound(m_minimumScale/m_startScale, m_activeScale, m_maximumScale/m_startScale);

        // 2. rotate
        QVector<PointData> newAngles = angles(centroid().scenePosition());
        const qreal angleDelta = averageAngleDelta(m_startAngles, newAngles);
        m_activeRotation += angleDelta;
        m_startAngles = std::move(newAngles);

        if (!containsReleasedPoints)
            acceptPoints(chosenPoints);
    }

    const qreal totalRotation = m_startRotation + m_activeRotation;
    const qreal rotation = qBound(m_minimumRotation, totalRotation, m_maximumRotation);
    m_activeRotation += (rotation - totalRotation);   //adjust for the potential bounding above
    m_accumulatedScale = m_startScale * m_activeScale;

    if (target() && target()->parentItem()) {
        const QPointF centroidParentPos = target()->parentItem()->mapFromScene(centroid().scenePosition());
        // 3. Drag/translate
        const QPointF centroidStartParentPos = target()->parentItem()->mapFromScene(centroid().sceneGrabPosition());
        m_activeTranslation = QVector2D(centroidParentPos - centroidStartParentPos);
        // apply rotation + scaling around the centroid - then apply translation.
        QPointF pos = QQuickItemPrivate::get(target())->adjustedPosForTransform(centroidParentPos,
                                                                                m_startPos, m_activeTranslation,
                                                                                m_startScale, m_activeScale,
                                                                                m_startRotation, m_activeRotation);

        if (xAxis()->enabled())
            pos.setX(qBound(xAxis()->minimum(), pos.x(), xAxis()->maximum()));
        else
            pos.rx() -= qreal(m_activeTranslation.x());
        if (yAxis()->enabled())
            pos.setY(qBound(yAxis()->minimum(), pos.y(), yAxis()->maximum()));
        else
            pos.ry() -= qreal(m_activeTranslation.y());

        target()->setPosition(pos);
        target()->setRotation(rotation);
        target()->setScale(m_accumulatedScale);
    } else {
        m_activeTranslation = QVector2D(centroid().scenePosition() - centroid().scenePressPosition());
    }

    qCDebug(lcPinchHandler) << "centroid" << centroid().scenePressPosition() << "->"  << centroid().scenePosition()
                            << ", distance" << m_startDistance << "->" << dist
                            << ", startScale" << m_startScale << "->" << m_accumulatedScale
                            << ", activeRotation" << m_activeRotation
                            << ", rotation" << rotation
                            << " from " << event->device()->type();

    emit updated();
}

/*!
    \readonly
    \qmlproperty QtQuick::HandlerPoint QtQuick::PinchHandler::centroid

    A point exactly in the middle of the currently-pressed touch points.
    The \l target will be rotated around this point.
*/

/*!
    \readonly
    \qmlproperty real QtQuick::PinchHandler::scale

    The scale factor that will automatically be set on the \l target if it is not null.
    Otherwise, bindings can be used to do arbitrary things with this value.
    While the pinch gesture is being performed, it is continuously multiplied by
    \l activeScale; after the gesture ends, it stays the same; and when the next
    pinch gesture begins, it begins to be multiplied by activeScale again.
*/

/*!
    \readonly
    \qmlproperty real QtQuick::PinchHandler::activeScale

    The scale factor while the pinch gesture is being performed.
    It is 1.0 when the gesture begins, increases as the touchpoints are spread
    apart, and decreases as the touchpoints are brought together.
    If \l target is not null, its \l {Item::scale}{scale} will be automatically
    multiplied by this value.
    Otherwise, bindings can be used to do arbitrary things with this value.
*/

/*!
    \readonly
    \qmlproperty real QtQuick::PinchHandler::rotation

    The rotation of the pinch gesture in degrees, with positive values clockwise.
    It is 0 when the gesture begins. If \l target is not null, this will be
    automatically applied to its \l {Item::rotation}{rotation}. Otherwise,
    bindings can be used to do arbitrary things with this value.
*/

/*!
    \readonly
    \qmlproperty QVector2D QtQuick::PinchHandler::translation

    The translation of the gesture \l centroid. It is \c (0, 0) when the
    gesture begins.
*/

QT_END_NAMESPACE
