/****************************************************************************
**
** 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/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) << 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());

            QStyleHints *styleHints = QGuiApplication::styleHints();
            const int dragThreshold = styleHints->startDragDistance();
            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);
                }
                if (QQuickWindowPrivate::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
