/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativepinchgenerator_p.h"

#include <QtTest/QtTest>
#include <QtGui/QGuiApplication>
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtGui/QStyleHints>

QT_BEGIN_NAMESPACE

QDeclarativePinchGenerator::QDeclarativePinchGenerator():
    target_(0),
    state_(Invalid),
    window_(0),
    activeSwipe_(0),
    replayTimer_(-1),
    replayBookmark_(-1),
    masterSwipe_(-1),
    replaySpeedFactor_(1.0),
    enabled_(true)
{
    setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton);
    swipeTimer_.invalidate();
    device_ = new QTouchDevice;
    device_->setType(QTouchDevice::TouchScreen);
    QWindowSystemInterface::registerTouchDevice(device_);
}

QDeclarativePinchGenerator::~QDeclarativePinchGenerator()
{
    clear();
}

void QDeclarativePinchGenerator::componentComplete()
{
    QQuickItem::componentComplete();
}

void QDeclarativePinchGenerator::mousePressEvent(QMouseEvent *event)
{
    if (state_ != Idle || !enabled_) {
        event->ignore();
        return;
    }
    Q_ASSERT(!activeSwipe_);
    Q_ASSERT(!swipeTimer_.isValid());
    // Start recording a pinch gesture.
    activeSwipe_ = new Swipe;
    activeSwipe_->touchPoints << event->pos();
    activeSwipe_->durations << 0;
    swipeTimer_.start();
    setState(Recording);
}

void QDeclarativePinchGenerator::mouseMoveEvent(QMouseEvent *event)
{
    if (state_ != Recording || !enabled_) {
        event->ignore();
        return;
    }
    Q_ASSERT(activeSwipe_);
    Q_ASSERT(swipeTimer_.isValid());

    activeSwipe_->touchPoints << event->pos();
    activeSwipe_->durations << swipeTimer_.elapsed();
    swipeTimer_.restart();
}

void QDeclarativePinchGenerator::mouseReleaseEvent(QMouseEvent *event)
{
    if (state_ != Recording || !enabled_) {
        event->ignore();
        return;
    }
    Q_ASSERT(activeSwipe_);
    Q_ASSERT(swipeTimer_.isValid());
    activeSwipe_->touchPoints << event->pos();
    activeSwipe_->durations << swipeTimer_.elapsed();

    if (swipes_.count() == SWIPES_REQUIRED)
        delete swipes_.takeFirst();
    swipes_ << activeSwipe_;
    activeSwipe_ = 0;
    swipeTimer_.invalidate();
    if (window_ && target_) setState(Idle); else setState(Invalid);
}

void QDeclarativePinchGenerator::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if (!enabled_) {
        event->ignore();
        return;
    }
    stop();
    clear();
    if (window_ && target_) setState(Idle); else setState(Invalid);
}

void QDeclarativePinchGenerator::keyPressEvent(QKeyEvent *e)
{
    if (!enabled_) {
        e->ignore();
    }

    if (e->key() == Qt::Key_C) {
        clear();
    } else if (e->key() == Qt::Key_R) {
        replay();
    } else if (e->key() == Qt::Key_S) {
        stop();
    } else if (e->key() == Qt::Key_Plus) {
        setReplaySpeedFactor(replaySpeedFactor() + 0.1);
    } else if (e->key() == Qt::Key_Minus) {
        setReplaySpeedFactor(replaySpeedFactor() - 0.1);
    } else {
        qDebug() << metaObject()->className() << "Unsupported key event.";
    }
}

bool QDeclarativePinchGenerator::enabled() const
{
    return enabled_;
}


void QDeclarativePinchGenerator::setEnabled(bool enabled)
{
    if (enabled == enabled_)
        return;
    enabled_ = enabled;
    if (!enabled_) {
        stop();
        clear();
    }
    emit enabledChanged();
}


qreal QDeclarativePinchGenerator::replaySpeedFactor() const
{
    return replaySpeedFactor_;
}

void QDeclarativePinchGenerator::setReplaySpeedFactor(qreal factor)
{
    if (factor == replaySpeedFactor_ || factor < 0.001)
        return;
    replaySpeedFactor_ = factor;
    emit replaySpeedFactorChanged();
}


QString QDeclarativePinchGenerator::state() const
{
    switch (state_) {
    case Invalid:
        return "Invalid";
    case Idle:
        return "Idle";
        break;
    case Recording:
        return "Recording";
        break;
    case Replaying:
        return "Replaying";
        break;
    default:
        Q_ASSERT(false);
    }
    return "How emberassing";
}

void QDeclarativePinchGenerator::setState(GeneratorState state)
{
    if (state == state_)
        return;
    state_ = state;
    emit stateChanged();
}

void QDeclarativePinchGenerator::itemChange(ItemChange change, const ItemChangeData & data)
{
    if (change == ItemSceneChange) {
        window_ = data.window;
        if (target_)
            setState(Idle);
    }
}

void QDeclarativePinchGenerator::timerEvent(QTimerEvent *event)
{
    Q_ASSERT(replayTimer_ == event->timerId());
    Q_UNUSED(event);
    Q_ASSERT(state_ == Replaying);

    int slaveSwipe = masterSwipe_ ^ 1;

    int masterCount = swipes_.at(masterSwipe_)->touchPoints.count();
    int slaveCount = swipes_.at(slaveSwipe)->touchPoints.count();

    if (replayBookmark_ == 0) {
        QTest::touchEvent(window_, device_)
                .press(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))
                .press(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_));
    } else if (replayBookmark_ == (slaveCount - 1)) {
        if (masterCount != slaveCount) {
            QTest::touchEvent(window_, device_)
                    .move(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))
                    .release(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_));
        } else {
            QTest::touchEvent(window_, device_)
                    .release(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))
                    .release(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_));
        }
    } else if (replayBookmark_ == (masterCount - 1)) {
            QTest::touchEvent(window_, device_)
                    .release(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_));
    }
    else {
        QTest::touchEvent(window_, device_)
                .move(0, swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))
                .move(1, swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_));
    }

    replayBookmark_++;
    if (replayBookmark_ >= swipes_.at(masterSwipe_)->touchPoints.count())
        stop();
    else {
        killTimer(replayTimer_);
        replayTimer_ = startTimer((swipes_.at(masterSwipe_)->durations.at(replayBookmark_) + 5) / replaySpeedFactor_ );
    }
}

QQuickItem* QDeclarativePinchGenerator::target() const
{
    return target_;
}

void QDeclarativePinchGenerator::setTarget(QQuickItem* target)
{
    if (target == target_)
        return;
    target_ = target;
    stop();
    clear();
    if (window_)
        setState(Idle);
    else
        setState(Invalid);
    emit targetChanged();
}

void QDeclarativePinchGenerator::pinch(QPoint point1From,
                                       QPoint point1To,
                                       QPoint point2From,
                                       QPoint point2To,
                                       int interval1,
                                       int interval2,
                                       int samples1,
                                       int samples2)
{
    Q_ASSERT(interval1 > 10);
    Q_ASSERT(interval2 > 10);
    Q_ASSERT(samples1 >= 2); // we need press and release events at minimum
    Q_ASSERT(samples2 >= 2);

    clear();

    Swipe* swipe1 = new Swipe;
    Swipe* swipe2 = new Swipe;
    for (int i = 0; i < samples1; ++i) {
        swipe1->touchPoints << point1From + (point1To - point1From) / samples1 * i;
        swipe1->durations << interval1;
    }
    for (int i = 0; i < samples2; ++i) {
        swipe2->touchPoints << point2From + (point2To - point2From) / samples2 * i;
        swipe2->durations << interval2;
    }
    swipes_ << swipe1 << swipe2;
    Q_ASSERT(swipes_.at(0));
    Q_ASSERT(swipes_.at(1));

    masterSwipe_ = (samples1 >= samples2) ? 0 : 1;

    replayTimer_ = startTimer(swipes_.at(masterSwipe_)->durations.at(0) / replaySpeedFactor_);
    replayBookmark_ = 0;
    setState(Replaying);
}

void QDeclarativePinchGenerator::pinchPress(QPoint point1From, QPoint point2From)
{
    QTest::touchEvent(window_, device_).press(0, point1From).press(1, point2From);
}

void QDeclarativePinchGenerator::pinchMoveTo(QPoint point1To, QPoint point2To)
{
    QTest::touchEvent(window_, device_).move(0, point1To).move(1, point2To);
}

void QDeclarativePinchGenerator::pinchRelease(QPoint point1To, QPoint point2To)
{
    QTest::touchEvent(window_, device_).release(0, point1To).release(1, point2To);
}

void QDeclarativePinchGenerator::replay()
{
    if (state_ != Idle) {
        qDebug() << "Wrong state, will not replay pinch, state: " << state_;
        return;
    }
    if (swipes_.count() < SWIPES_REQUIRED) {
        qDebug() << "Too few swipes, cannot replay, amount: " << swipes_.count();
        return;
    }
    if ((swipes_.at(0)->touchPoints.count() < 2) || (swipes_.at(1)->touchPoints.count() < 2)) {
        qDebug() << "Too few touchpoints, won't replay, amount: " <<
                    swipes_.at(0)->touchPoints.count() << (swipes_.at(1)->touchPoints.count() < 2);
        return;
    }

    masterSwipe_ = (swipes_.at(0)->touchPoints.count() >= swipes_.at(1)->touchPoints.count()) ? 0 : 1;

    replayTimer_ = startTimer(swipes_.at(masterSwipe_)->touchPoints.count() / replaySpeedFactor_);
    replayBookmark_ = 0;
    setState(Replaying);
}

void QDeclarativePinchGenerator::clear()
{
    stop();
    delete activeSwipe_;
    activeSwipe_ = 0;
    if (!swipes_.isEmpty()) {
        qDeleteAll(swipes_);
        swipes_.clear();
    }
}

void QDeclarativePinchGenerator::stop()
{
    if (state_ != Replaying)
        return;
    // stop replay
    Q_ASSERT(replayTimer_ != -1);
    killTimer(replayTimer_);
    replayTimer_ = -1;
    setState(Idle);
}

int QDeclarativePinchGenerator::startDragDistance()
{
    return qApp->styleHints()->startDragDistance();
}

QT_END_NAMESPACE
