/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativepincharea_p.h"
#include "qdeclarativepincharea_p_p.h"

#include <QApplication>
#include <QGraphicsScene>

#include <float.h>
#include <math.h>

QT_BEGIN_NAMESPACE


/*!
    \qmlclass PinchEvent QDeclarativePinchEvent
    \ingroup qml-event-elements
    \brief The PinchEvent object provides information about a pinch event.

    \bold {The PinchEvent element 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 PinchEvent::center
    \qmlproperty QPointF PinchEvent::startCenter
    \qmlproperty QPointF PinchEvent::previousCenter

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

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

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

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

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

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

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

    These properties hold the angle between the two touch points.

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

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

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

    These properties provide the actual touch points generating the pinch.

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

/*!
    \qmlproperty bool 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 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.
*/

QDeclarativePinch::QDeclarativePinch()
    : m_target(0), 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)
{
}

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

/*!
    \qmlclass PinchArea QDeclarativePinchArea
    \brief The PinchArea item enables simple pinch gesture handling.
    \inherits Item

    \bold {The PinchArea element 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
    \o setting a \c pinch.target to provide automatic interaction with an element
    \o using the onPinchStarted, onPinchUpdated and onPinchFinished handlers
    \endlist

    \sa PinchEvent
*/

/*!
    \qmlsignal PinchArea::onPinchStarted()

    This handler is called when the pinch area detects that a pinch gesture has started.

    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
    including the scale, center and angle of the pinch.

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

/*!
    \qmlsignal PinchArea::onPinchUpdated()

    This handler is called 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.
*/

/*!
    \qmlsignal PinchArea::onPinchFinished()

    This handler is called when the pinch area detects that a pinch gesture has finished.

    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
    including the scale, center and angle of the pinch.
*/


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

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

    \list
    \i \c pinch.target specifies the id of the item to drag.
    \i \c pinch.active specifies if the target item is currently being dragged.
    \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
    \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
    \i \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)
    \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
    \endlist
*/

QDeclarativePinchArea::QDeclarativePinchArea(QDeclarativeItem *parent)
  : QDeclarativeItem(*(new QDeclarativePinchAreaPrivate), parent)
{
    Q_D(QDeclarativePinchArea);
    d->init();
}

QDeclarativePinchArea::~QDeclarativePinchArea()
{
}

/*!
    \qmlproperty bool PinchArea::enabled
    This property holds whether the item accepts pinch gestures.

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

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

bool QDeclarativePinchArea::event(QEvent *event)
{
    Q_D(QDeclarativePinchArea);
    if (!d->absorb || !isVisible())
        return QDeclarativeItem::event(event);
    switch (event->type()) {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate: {
            QTouchEvent *touch = static_cast<QTouchEvent*>(event);
            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();
        }
        return true;
    case QEvent::TouchEnd:
        d->touchPoints.clear();
        updatePinch();
        break;
    default:
        return QDeclarativeItem::event(event);
    }

    return QDeclarativeItem::event(event);
}

void QDeclarativePinchArea::updatePinch()
{
    Q_D(QDeclarativePinchArea);
    if (d->touchPoints.count() == 0) {
        if (d->inPinch) {
            d->stealMouse = false;
            setKeepMouseGrab(false);
            d->inPinch = false;
            QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
            QDeclarativePinchEvent 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);
        }
        return;
    }
    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
    if (d->touchPoints.count() == 2
        && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
        d->id1 = touchPoint1.id();
        d->sceneStartPoint1 = touchPoint1.scenePos();
        d->sceneStartPoint2 = touchPoint2.scenePos();
        d->inPinch = false;
        d->pinchRejected = false;
        d->pinchActivated = true;
    } else if (d->pinchActivated && !d->pinchRejected) {
        const int dragThreshold = QApplication::startDragDistance();
        QPointF p1 = touchPoint1.scenePos();
        QPointF p2 = touchPoint2.scenePos();
        qreal dx = p1.x() - p2.x();
        qreal dy = p1.y() - p2.y();
        qreal dist = sqrt(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) {
            if (d->touchPoints.count() >= 2
                    && (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)) {
                d->sceneStartCenter = sceneCenter;
                d->sceneLastCenter = sceneCenter;
                d->pinchStartCenter = mapFromScene(sceneCenter);
                d->pinchStartDist = dist;
                d->pinchStartAngle = angle;
                d->pinchLastScale = 1.0;
                d->pinchLastAngle = angle;
                d->pinchRotation = 0.0;
                d->lastPoint1 = p1;
                d->lastPoint2 = p2;
                QDeclarativePinchEvent pe(d->pinchStartCenter, 1.0, 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(d->touchPoints.count());
                emit pinchStarted(&pe);
                if (pe.accepted()) {
                    d->inPinch = true;
                    d->stealMouse = true;
                    QGraphicsScene *s = scene();
                    if (s && s->mouseGrabberItem() != this)
                        grabMouse();
                    setKeepMouseGrab(true);
                    if (d->pinch && d->pinch->target()) {
                        d->pinchStartPos = pinch()->target()->pos();
                        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);
            QDeclarativePinchEvent 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);
            if (d->pinch && d->pinch->target()) {
                qreal s = d->pinchStartScale * scale;
                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
                pinch()->target()->setScale(s);
                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
                if (pinch()->axis() & QDeclarativePinch::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() & QDeclarativePinch::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);
                }
            }
        }
    }
}

void QDeclarativePinchArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativePinchArea);
    d->stealMouse = false;
    if (!d->absorb)
        QDeclarativeItem::mousePressEvent(event);
    else {
        setKeepMouseGrab(false);
        event->setAccepted(true);
    }
}

void QDeclarativePinchArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativePinchArea);
    if (!d->absorb) {
        QDeclarativeItem::mouseMoveEvent(event);
        return;
    }
}

void QDeclarativePinchArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativePinchArea);
    d->stealMouse = false;
    if (!d->absorb) {
        QDeclarativeItem::mouseReleaseEvent(event);
    } else {
        QGraphicsScene *s = scene();
        if (s && s->mouseGrabberItem() == this)
            ungrabMouse();
        setKeepMouseGrab(false);
    }
}

bool QDeclarativePinchArea::sceneEvent(QEvent *event)
{
    bool rv = QDeclarativeItem::sceneEvent(event);
    if (event->type() == QEvent::UngrabMouse) {
        setKeepMouseGrab(false);
    }
    return rv;
}

bool QDeclarativePinchArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativePinchArea);
    QGraphicsSceneMouseEvent mouseEvent(event->type());
    QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();

    QGraphicsScene *s = scene();
    QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
    bool stealThisEvent = d->stealMouse;
    if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
        mouseEvent.setAccepted(false);
        for (int i = 0x1; i <= 0x10; i <<= 1) {
            if (event->buttons() & i) {
                Qt::MouseButton button = Qt::MouseButton(i);
                mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
            }
        }
        mouseEvent.setScenePos(event->scenePos());
        mouseEvent.setLastScenePos(event->lastScenePos());
        mouseEvent.setPos(mapFromScene(event->scenePos()));
        mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));

        switch(mouseEvent.type()) {
        case QEvent::GraphicsSceneMouseMove:
            mouseMoveEvent(&mouseEvent);
            break;
        case QEvent::GraphicsSceneMousePress:
            mousePressEvent(&mouseEvent);
            break;
        case QEvent::GraphicsSceneMouseRelease:
            mouseReleaseEvent(&mouseEvent);
            break;
        default:
            break;
        }
        grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
            grabMouse();

        return stealThisEvent;
    }
    if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
        d->stealMouse = false;
        if (s && s->mouseGrabberItem() == this)
            ungrabMouse();
        setKeepMouseGrab(false);
    }
    return false;
}

bool QDeclarativePinchArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
{
    Q_D(QDeclarativePinchArea);
    if (!d->absorb || !isVisible())
        return QDeclarativeItem::sceneEventFilter(i, e);
    switch (e->type()) {
    case QEvent::GraphicsSceneMousePress:
    case QEvent::GraphicsSceneMouseMove:
    case QEvent::GraphicsSceneMouseRelease:
        return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
        break;
    case QEvent::TouchBegin:
    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();
        }
        return d->inPinch;
    case QEvent::TouchEnd:
        d->touchPoints.clear();
        updatePinch();
        break;
    default:
        break;
    }

    return QDeclarativeItem::sceneEventFilter(i, e);
}

void QDeclarativePinchArea::geometryChanged(const QRectF &newGeometry,
                                            const QRectF &oldGeometry)
{
    QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
}

QVariant QDeclarativePinchArea::itemChange(GraphicsItemChange change,
                                       const QVariant &value)
{
    return QDeclarativeItem::itemChange(change, value);
}

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


QT_END_NAMESPACE
