/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSG 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 "qquickpincharea_p_p.h"
#include "qquickwindow.h"

#include <QtCore/qmath.h>
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
#include <private/qguiapplication_p.h>
#include <QVariant>

#include <float.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype PinchEvent
    \instantiates QQuickPinchEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief For specifying information about a pinch event.

    \b {The PinchEvent type was added in QtQuick 1.1}

    The \c center, \c startCenter, \c previousCenter properties provide the center position between the two touch points.

    The \c scale and \c previousScale properties provide the scale factor.

    The \c angle, \c previousAngle and \c rotation properties provide the angle between the two points and the amount of rotation.

    The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.

    The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
    be handled.

    \sa PinchArea
*/

/*!
    \qmlproperty QPointF QtQuick::PinchEvent::center
    \qmlproperty QPointF QtQuick::PinchEvent::startCenter
    \qmlproperty QPointF QtQuick::PinchEvent::previousCenter

    These properties hold the position of the center point between the two touch points.

    \list
    \li \c center is the current center point
    \li \c previousCenter is the center point of the previous event.
    \li \c startCenter is the center point when the gesture began
    \endlist
*/

/*!
    \qmlproperty real QtQuick::PinchEvent::scale
    \qmlproperty real QtQuick::PinchEvent::previousScale

    These properties hold the scale factor determined by the change in distance between the two touch points.

    \list
    \li \c scale is the current scale factor.
    \li \c previousScale is the scale factor of the previous event.
    \endlist

    When a pinch gesture is started, the scale is \c 1.0.
*/

/*!
    \qmlproperty real QtQuick::PinchEvent::angle
    \qmlproperty real QtQuick::PinchEvent::previousAngle
    \qmlproperty real QtQuick::PinchEvent::rotation

    These properties hold the angle between the two touch points.

    \list
    \li \c angle is the current angle between the two points in the range -180 to 180.
    \li \c previousAngle is the angle of the previous event.
    \li \c rotation is the total rotation since the pinch gesture started.
    \endlist

    When a pinch gesture is started, the rotation is \c 0.0.
*/

/*!
    \qmlproperty QPointF QtQuick::PinchEvent::point1
    \qmlproperty QPointF QtQuick::PinchEvent::startPoint1
    \qmlproperty QPointF QtQuick::PinchEvent::point2
    \qmlproperty QPointF QtQuick::PinchEvent::startPoint2

    These properties provide the actual touch points generating the pinch.

    \list
    \li \c point1 and \c point2 hold the current positions of the points.
    \li \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
    \endlist
*/

/*!
    \qmlproperty bool QtQuick::PinchEvent::accepted

    Setting this property to false in the \c PinchArea::onPinchStarted handler
    will result in no further pinch events being generated, and the gesture
    ignored.
*/

/*!
    \qmlproperty int QtQuick::PinchEvent::pointCount

    Holds the number of points currently touched.  The PinchArea will not react
    until two touch points have initited a gesture, but will remain active until
    all touch points have been released.
*/

QQuickPinch::QQuickPinch()
    : m_target(nullptr), m_minScale(1.0), m_maxScale(1.0)
    , m_minRotation(0.0), m_maxRotation(0.0)
    , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
    , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
{
}

QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
{
    delete pinch;
}

/*!
    \qmltype PinchArea
    \instantiates QQuickPinchArea
    \inqmlmodule QtQuick
    \ingroup qtquick-input
    \inherits Item
    \brief Enables simple pinch gesture handling.

    \b {The PinchArea type was added in QtQuick 1.1}

    A PinchArea is an invisible item that is typically used in conjunction with
    a visible item in order to provide pinch gesture handling for that item.

    The \l enabled property is used to enable and disable pinch handling for
    the proxied item. When disabled, the pinch area becomes transparent to
    mouse/touch events.

    PinchArea can be used in two ways:

    \list
    \li setting a \c pinch.target to provide automatic interaction with an item
    \li using the onPinchStarted, onPinchUpdated and onPinchFinished handlers
    \endlist

    Since Qt 5.5, PinchArea can react to native pinch gesture events from the
    operating system if available; otherwise it reacts only to touch events.

    \sa PinchEvent, QNativeGestureEvent, QTouchEvent
*/

/*!
    \qmlsignal QtQuick::PinchArea::pinchStarted(PinchEvent pinch)

    This signal is emitted when the pinch area detects that a pinch gesture has
    started: two touch points (fingers) have been detected, and they have moved
    beyond the \l {QStyleHints}{startDragDistance} threshold for the gesture to begin.

    The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
    property) provides information about the pinch gesture, including the scale,
    center and angle of the pinch. At the time of the \c pinchStarted signal,
    these values are reset to the default values, regardless of the results
    from previous gestures: pinch.scale will be \c 1.0 and pinch.rotation will be \c 0.0.
    As the gesture progresses, \l pinchUpdated will report the deviation from those
    defaults.

    To ignore this gesture set the \c pinch.accepted property to false.  The gesture
    will be canceled and no further events will be sent.
*/

/*!
    \qmlsignal QtQuick::PinchArea::pinchUpdated(PinchEvent pinch)

    This signal is emitted when the pinch area detects that a pinch gesture has changed.

    The \l {PinchEvent}{pinch} parameter provides information about the pinch
    gesture, including the scale, center and angle of the pinch. These values
    reflect changes only since the beginning of the current gesture, and
    therefore are not limited by the minimum and maximum limits in the
    \l {PinchArea}{pinch} property.
*/

/*!
    \qmlsignal QtQuick::PinchArea::pinchFinished(PinchEvent pinch)

    This signal is emitted when the pinch area detects that a pinch gesture has finished.

    The \l {PinchEvent}{pinch} parameter (not the same as the \l {PinchArea}{pinch}
    property) provides information about the pinch gesture, including the
    scale, center and angle of the pinch.
*/

/*!
    \qmlsignal QtQuick::PinchArea::smartZoom(PinchEvent pinch)
    \since 5.5

    This signal is emitted when the pinch area detects the smart zoom gesture.
    This gesture occurs only on certain operating systems such as \macos.

    The \l {PinchEvent}{pinch} parameter provides information about the pinch
    gesture, including the location where the gesture occurred.  \c pinch.scale
    will be greater than zero when the gesture indicates that the user wishes to
    enter smart zoom, and zero when exiting (even though typically the same gesture
    is used to toggle between the two states).
*/


/*!
    \qmlpropertygroup QtQuick::PinchArea::pinch
    \qmlproperty Item QtQuick::PinchArea::pinch.target
    \qmlproperty bool QtQuick::PinchArea::pinch.active
    \qmlproperty real QtQuick::PinchArea::pinch.minimumScale
    \qmlproperty real QtQuick::PinchArea::pinch.maximumScale
    \qmlproperty real QtQuick::PinchArea::pinch.minimumRotation
    \qmlproperty real QtQuick::PinchArea::pinch.maximumRotation
    \qmlproperty enumeration QtQuick::PinchArea::pinch.dragAxis
    \qmlproperty real QtQuick::PinchArea::pinch.minimumX
    \qmlproperty real QtQuick::PinchArea::pinch.maximumX
    \qmlproperty real QtQuick::PinchArea::pinch.minimumY
    \qmlproperty real QtQuick::PinchArea::pinch.maximumY

    \c pinch provides a convenient way to make an item react to pinch gestures.

    \list
    \li \c pinch.target specifies the id of the item to drag.
    \li \c pinch.active specifies if the target item is currently being dragged.
    \li \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item.scale property, but not the \c PinchEvent \l {PinchEvent}{scale} property.
    \li \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item.rotation property, but not the \c PinchEvent \l {PinchEvent}{rotation} property.
    \li \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XAndYAxis)
    \li \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
    \endlist
*/

QQuickPinchArea::QQuickPinchArea(QQuickItem *parent)
  : QQuickItem(*(new QQuickPinchAreaPrivate), parent)
{
    Q_D(QQuickPinchArea);
    d->init();
    setAcceptTouchEvents(true);
#ifdef Q_OS_OSX
    setAcceptHoverEvents(true); // needed to enable touch events on mouse hover.
#endif
}

QQuickPinchArea::~QQuickPinchArea()
{
}
/*!
    \qmlproperty bool QtQuick::PinchArea::enabled
    This property holds whether the item accepts pinch gestures.

    This property defaults to true.
*/
bool QQuickPinchArea::isEnabled() const
{
    Q_D(const QQuickPinchArea);
    return d->enabled;
}

void QQuickPinchArea::setEnabled(bool a)
{
    Q_D(QQuickPinchArea);
    if (a != d->enabled) {
        d->enabled = a;
        emit enabledChanged();
    }
}

void QQuickPinchArea::touchEvent(QTouchEvent *event)
{
    Q_D(QQuickPinchArea);
    if (!d->enabled || !isVisible()) {
        QQuickItem::touchEvent(event);
        return;
    }

    // A common non-trivial starting scenario is the user puts down one finger,
    // then that finger remains stationary while putting down a second one.
    // However QQuickWindow will not send TouchUpdates for TouchPoints which
    // were not initially accepted; that would be inefficient and noisy.
    // So even if there is only one touchpoint so far, it's important to accept it
    // in order to get updates later on (and it's accepted by default anyway).
    // If the user puts down one finger, we're waiting for the other finger to drop.
    // Therefore updatePinch() must do the right thing for any combination of
    // points and states that may occur, and there is no reason to ignore any event.
    // One consequence though is that if PinchArea is on top of something else,
    // it's always going to accept the touches, and that means the item underneath
    // will not get them (unless the PA's parent is doing parent filtering,
    // as the Flickable does, for example).
    switch (event->type()) {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
        d->touchPoints.clear();
        for (int i = 0; i < event->touchPoints().count(); ++i) {
            if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
                d->touchPoints << event->touchPoints().at(i);
            }
        }
        updatePinch();
        break;
    case QEvent::TouchEnd:
        clearPinch();
        break;
    case QEvent::TouchCancel:
        cancelPinch();
        break;
    default:
        QQuickItem::touchEvent(event);
    }
}

void QQuickPinchArea::clearPinch()
{
    Q_D(QQuickPinchArea);

    d->touchPoints.clear();
    if (d->inPinch) {
        d->inPinch = false;
        QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
        QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
        pe.setStartCenter(d->pinchStartCenter);
        pe.setPreviousCenter(pinchCenter);
        pe.setPreviousAngle(d->pinchLastAngle);
        pe.setPreviousScale(d->pinchLastScale);
        pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
        pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
        pe.setPoint1(mapFromScene(d->lastPoint1));
        pe.setPoint2(mapFromScene(d->lastPoint2));
        emit pinchFinished(&pe);
        if (d->pinch && d->pinch->target())
            d->pinch->setActive(false);
    }
    d->pinchStartDist = 0;
    d->pinchActivated = false;
    d->initPinch = false;
    d->pinchRejected = false;
    d->stealMouse = false;
    d->id1 = -1;
    QQuickWindow *win = window();
    if (win && win->mouseGrabberItem() == this)
        ungrabMouse();
    setKeepMouseGrab(false);
}

void QQuickPinchArea::cancelPinch()
{
    Q_D(QQuickPinchArea);

    d->touchPoints.clear();
    if (d->inPinch) {
        d->inPinch = false;
        QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
        QQuickPinchEvent pe(d->pinchStartCenter, d->pinchStartScale, d->pinchStartAngle, d->pinchStartRotation);
        pe.setStartCenter(d->pinchStartCenter);
        pe.setPreviousCenter(pinchCenter);
        pe.setPreviousAngle(d->pinchLastAngle);
        pe.setPreviousScale(d->pinchLastScale);
        pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
        pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
        pe.setPoint1(pe.startPoint1());
        pe.setPoint2(pe.startPoint2());
        emit pinchFinished(&pe);

        d->pinchLastScale = d->pinchStartScale;
        d->sceneLastCenter = d->sceneStartCenter;
        d->pinchLastAngle = d->pinchStartAngle;
        d->lastPoint1 = pe.startPoint1();
        d->lastPoint2 = pe.startPoint2();
        updatePinchTarget();

        if (d->pinch && d->pinch->target())
            d->pinch->setActive(false);
    }
    d->pinchStartDist = 0;
    d->pinchActivated = false;
    d->initPinch = false;
    d->pinchRejected = false;
    d->stealMouse = false;
    d->id1 = -1;
    QQuickWindow *win = window();
    if (win && win->mouseGrabberItem() == this)
        ungrabMouse();
    setKeepMouseGrab(false);
}

void QQuickPinchArea::updatePinch()
{
    Q_D(QQuickPinchArea);

    QQuickWindow *win = window();

    if (d->touchPoints.count() < 2) {
        setKeepMouseGrab(false);
        QQuickWindow *c = window();
        if (c && c->mouseGrabberItem() == this)
            ungrabMouse();
    }

    if (d->touchPoints.count() == 0) {
        if (d->inPinch) {
            d->inPinch = false;
            QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
            QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(pinchCenter);
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(mapFromScene(d->lastPoint1));
            pe.setPoint2(mapFromScene(d->lastPoint2));
            emit pinchFinished(&pe);
            d->pinchStartDist = 0;
            d->pinchActivated = false;
            if (d->pinch && d->pinch->target())
                d->pinch->setActive(false);
        }
        d->initPinch = false;
        d->pinchRejected = false;
        d->stealMouse = false;
        return;
    }

    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);

    if (touchPoint1.state() == Qt::TouchPointPressed)
        d->sceneStartPoint1 = touchPoint1.scenePos();

    if (touchPoint2.state() == Qt::TouchPointPressed)
        d->sceneStartPoint2 = touchPoint2.scenePos();

    QRectF bounds = clipRect();
    // Pinch is not started unless there are exactly two touch points
    // AND one or more of the points has just now been pressed (wasn't pressed already)
    // AND both points are inside the bounds.
    if (d->touchPoints.count() == 2
            && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed) &&
            bounds.contains(touchPoint1.pos()) && bounds.contains(touchPoint2.pos())) {
        d->id1 = touchPoint1.id();
        d->pinchActivated = true;
        d->initPinch = true;

        int touchMouseId = QQuickWindowPrivate::get(win)->touchMouseId;
        if (touchPoint1.id() == touchMouseId || touchPoint2.id() == touchMouseId) {
            if (win && win->mouseGrabberItem() != this) {
                grabMouse();
            }
        }
    }
    if (d->pinchActivated && !d->pinchRejected) {
        const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
        QPointF p1 = touchPoint1.scenePos();
        QPointF p2 = touchPoint2.scenePos();
        qreal dx = p1.x() - p2.x();
        qreal dy = p1.y() - p2.y();
        qreal dist = qSqrt(dx*dx + dy*dy);
        QPointF sceneCenter = (p1 + p2)/2;
        qreal angle = QLineF(p1, p2).angle();
        if (d->touchPoints.count() == 1) {
            // If we only have one point then just move the center
            if (d->id1 == touchPoint1.id())
                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
            else
                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
            angle = d->pinchLastAngle;
        }
        d->id1 = touchPoint1.id();
        if (angle > 180)
            angle -= 360;
        if (!d->inPinch || d->initPinch) {
            if (d->touchPoints.count() >= 2) {
                if (d->initPinch) {
                    if (!d->inPinch)
                        d->pinchStartDist = dist;
                    d->initPinch = false;
                }
                d->sceneStartCenter = sceneCenter;
                d->sceneLastCenter = sceneCenter;
                d->pinchStartCenter = mapFromScene(sceneCenter);
                d->pinchStartAngle = angle;
                d->pinchLastScale = 1.0;
                d->pinchLastAngle = angle;
                d->pinchRotation = 0.0;
                d->lastPoint1 = p1;
                d->lastPoint2 = p2;
                if (qAbs(dist - d->pinchStartDist) >= dragThreshold ||
                        (pinch()->axis() != QQuickPinch::NoDrag &&
                         (qAbs(p1.x()-d->sceneStartPoint1.x()) >= dragThreshold
                          || qAbs(p1.y()-d->sceneStartPoint1.y()) >= dragThreshold
                          || qAbs(p2.x()-d->sceneStartPoint2.x()) >= dragThreshold
                          || qAbs(p2.y()-d->sceneStartPoint2.y()) >= dragThreshold))) {
                    QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
                    d->pinchStartDist = dist;
                    pe.setStartCenter(d->pinchStartCenter);
                    pe.setPreviousCenter(d->pinchStartCenter);
                    pe.setPreviousAngle(d->pinchLastAngle);
                    pe.setPreviousScale(d->pinchLastScale);
                    pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
                    pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
                    pe.setPoint1(mapFromScene(d->lastPoint1));
                    pe.setPoint2(mapFromScene(d->lastPoint2));
                    pe.setPointCount(d->touchPoints.count());
                    emit pinchStarted(&pe);
                    if (pe.accepted()) {
                        d->inPinch = true;
                        d->stealMouse = true;
                        if (win && win->mouseGrabberItem() != this)
                            grabMouse();
                        setKeepMouseGrab(true);
                        grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
                        d->inPinch = true;
                        d->stealMouse = true;
                        if (d->pinch && d->pinch->target()) {
                            d->pinchStartPos = pinch()->target()->position();
                            d->pinchStartScale = d->pinch->target()->scale();
                            d->pinchStartRotation = d->pinch->target()->rotation();
                            d->pinch->setActive(true);
                        }
                    } else {
                        d->pinchRejected = true;
                    }
                }
            }
        } else if (d->pinchStartDist > 0) {
            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
            qreal da = d->pinchLastAngle - angle;
            if (da > 180)
                da -= 360;
            else if (da < -180)
                da += 360;
            d->pinchRotation += da;
            QPointF pinchCenter = mapFromScene(sceneCenter);
            QQuickPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(touchPoint1.pos());
            pe.setPoint2(touchPoint2.pos());
            pe.setPointCount(d->touchPoints.count());
            d->pinchLastScale = scale;
            d->sceneLastCenter = sceneCenter;
            d->pinchLastAngle = angle;
            d->lastPoint1 = touchPoint1.scenePos();
            d->lastPoint2 = touchPoint2.scenePos();
            emit pinchUpdated(&pe);
            updatePinchTarget();
        }
    }
}

void QQuickPinchArea::updatePinchTarget()
{
    Q_D(QQuickPinchArea);
    if (d->pinch && d->pinch->target()) {
        qreal s = d->pinchStartScale * d->pinchLastScale;
        s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
        pinch()->target()->setScale(s);
        QPointF pos = d->sceneLastCenter - d->sceneStartCenter + d->pinchStartPos;
        if (pinch()->axis() & QQuickPinch::XAxis) {
            qreal x = pos.x();
            if (x < pinch()->xmin())
                x = pinch()->xmin();
            else if (x > pinch()->xmax())
                x = pinch()->xmax();
            pinch()->target()->setX(x);
        }
        if (pinch()->axis() & QQuickPinch::YAxis) {
            qreal y = pos.y();
            if (y < pinch()->ymin())
                y = pinch()->ymin();
            else if (y > pinch()->ymax())
                y = pinch()->ymax();
            pinch()->target()->setY(y);
        }
        if (d->pinchStartRotation >= pinch()->minimumRotation()
                && d->pinchStartRotation <= pinch()->maximumRotation()) {
            qreal r = d->pinchRotation + d->pinchStartRotation;
            r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
            pinch()->target()->setRotation(r);
        }
    }
}

bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
    Q_D(QQuickPinchArea);
    if (!d->enabled || !isVisible())
        return QQuickItem::childMouseEventFilter(i, e);
    switch (e->type()) {
    case QEvent::TouchBegin:
        clearPinch();
        Q_FALLTHROUGH();
    case QEvent::TouchUpdate: {
             QTouchEvent *touch = static_cast<QTouchEvent*>(e);
            d->touchPoints.clear();
            for (int i = 0; i < touch->touchPoints().count(); ++i)
                if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
                    d->touchPoints << touch->touchPoints().at(i);
            updatePinch();
        }
        e->setAccepted(d->inPinch);
        return d->inPinch;
    case QEvent::TouchEnd:
        clearPinch();
        break;
    default:
        break;
    }

    return QQuickItem::childMouseEventFilter(i, e);
}

void QQuickPinchArea::geometryChanged(const QRectF &newGeometry,
                                            const QRectF &oldGeometry)
{
    QQuickItem::geometryChanged(newGeometry, oldGeometry);
}

void QQuickPinchArea::itemChange(ItemChange change, const ItemChangeData &value)
{
    QQuickItem::itemChange(change, value);
}

bool QQuickPinchArea::event(QEvent *event)
{
    Q_D(QQuickPinchArea);
    if (!d->enabled || !isVisible())
        return QQuickItem::event(event);

    switch (event->type()) {
#if QT_CONFIG(gestures)
    case QEvent::NativeGesture: {
        QNativeGestureEvent *gesture = static_cast<QNativeGestureEvent *>(event);
        switch (gesture->gestureType()) {
        case Qt::BeginNativeGesture:
            clearPinch(); // probably not necessary; JIC
            d->pinchStartCenter = gesture->localPos();
            d->pinchStartAngle = 0.0;
            d->pinchStartRotation = 0.0;
            d->pinchRotation = 0.0;
            d->pinchStartScale = 1.0;
            d->pinchLastAngle = 0.0;
            d->pinchLastScale = 1.0;
            d->sceneStartPoint1 = gesture->windowPos();
            d->sceneStartPoint2 = gesture->windowPos(); // TODO we never really know
            d->lastPoint1 = gesture->windowPos();
            d->lastPoint2 = gesture->windowPos(); // TODO we never really know
            if (d->pinch && d->pinch->target()) {
                d->pinchStartPos = d->pinch->target()->position();
                d->pinchStartScale = d->pinch->target()->scale();
                d->pinchStartRotation = d->pinch->target()->rotation();
                d->pinch->setActive(true);
            }
            break;
        case Qt::EndNativeGesture:
            clearPinch();
            break;
        case Qt::ZoomNativeGesture: {
            qreal scale = d->pinchLastScale * (1.0 + gesture->value());
            QQuickPinchEvent pe(d->pinchStartCenter, scale, d->pinchLastAngle, 0.0);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(d->pinchStartCenter);
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(mapFromScene(d->lastPoint1));
            pe.setPoint2(mapFromScene(d->lastPoint2));
            pe.setPointCount(2);
            d->pinchLastScale = scale;
            if (d->inPinch)
                emit pinchUpdated(&pe);
            else
                emit pinchStarted(&pe);
            d->inPinch = true;
            updatePinchTarget();
        } break;
        case Qt::SmartZoomNativeGesture: {
            if (gesture->value() > 0.0 && d->pinch && d->pinch->target()) {
                d->pinchStartPos = pinch()->target()->position();
                d->pinchStartCenter = mapToItem(pinch()->target()->parentItem(), pinch()->target()->boundingRect().center());
                d->pinchStartScale = d->pinch->target()->scale();
                d->pinchStartRotation = d->pinch->target()->rotation();
                d->pinchLastScale = d->pinchStartScale = d->pinch->target()->scale();
                d->pinchLastAngle = d->pinchStartRotation = d->pinch->target()->rotation();
            }
            QQuickPinchEvent pe(gesture->localPos(), gesture->value(), d->pinchLastAngle, 0.0);
            pe.setStartCenter(gesture->localPos());
            pe.setPreviousCenter(d->pinchStartCenter);
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(gesture->localPos());
            pe.setStartPoint2(gesture->localPos());
            pe.setPoint1(mapFromScene(gesture->windowPos()));
            pe.setPoint2(mapFromScene(gesture->windowPos()));
            pe.setPointCount(2);
            emit smartZoom(&pe);
        } break;
        case Qt::RotateNativeGesture: {
            qreal angle = d->pinchLastAngle + gesture->value();
            QQuickPinchEvent pe(d->pinchStartCenter, d->pinchLastScale, angle, 0.0);
            pe.setStartCenter(d->pinchStartCenter);
            pe.setPreviousCenter(d->pinchStartCenter);
            pe.setPreviousAngle(d->pinchLastAngle);
            pe.setPreviousScale(d->pinchLastScale);
            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
            pe.setPoint1(mapFromScene(d->lastPoint1));
            pe.setPoint2(mapFromScene(d->lastPoint2));
            pe.setPointCount(2);
            d->pinchLastAngle = angle;
            if (d->inPinch)
                emit pinchUpdated(&pe);
            else
                emit pinchStarted(&pe);
            d->inPinch = true;
            d->pinchRotation = angle;
            updatePinchTarget();
        } break;
        default:
            return QQuickItem::event(event);
        }
    } break;
#endif // gestures
    case QEvent::Wheel:
        event->ignore();
        return false;
    default:
         return QQuickItem::event(event);
    }

    return true;
}

QQuickPinch *QQuickPinchArea::pinch()
{
    Q_D(QQuickPinchArea);
    if (!d->pinch)
        d->pinch = new QQuickPinch;
    return d->pinch;
}

QT_END_NAMESPACE

#include "moc_qquickpincharea_p.cpp"
