/****************************************************************************
**
** 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: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 "quicktestevent_p.h"
#include <QtTest/qtestkeyboard.h>
#include <QtQml/qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickwindow.h>
#include <qpa/qwindowsysteminterface.h>

QT_BEGIN_NAMESPACE

namespace QTest {
    extern int Q_TESTLIB_EXPORT defaultMouseDelay();
}

QuickTestEvent::QuickTestEvent(QObject *parent)
    : QObject(parent)
{
}

QuickTestEvent::~QuickTestEvent()
{
}

int QuickTestEvent::defaultMouseDelay() const
{
    return QTest::defaultMouseDelay();
}

bool QuickTestEvent::keyPress(int key, int modifiers, int delay)
{
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyPress(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

bool QuickTestEvent::keyRelease(int key, int modifiers, int delay)
{
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyRelease(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

bool QuickTestEvent::keyClick(int key, int modifiers, int delay)
{
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyClick(window, Qt::Key(key), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

bool QuickTestEvent::keyPressChar(const QString &character, int modifiers, int delay)
{
    QTEST_ASSERT(character.length() == 1);
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyPress(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

bool QuickTestEvent::keyReleaseChar(const QString &character, int modifiers, int delay)
{
    QTEST_ASSERT(character.length() == 1);
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyRelease(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int delay)
{
    QTEST_ASSERT(character.length() == 1);
    QWindow *window = activeWindow();
    if (!window)
        return false;
    QTest::keyClick(window, character[0].toLatin1(), Qt::KeyboardModifiers(modifiers), delay);
    return true;
}

#if QT_CONFIG(shortcut)
// valueToKeySequence() is copied from qquickshortcut.cpp
static QKeySequence valueToKeySequence(const QVariant &value)
{
    if (value.userType() == QMetaType::Int)
        return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
    return QKeySequence::fromString(value.toString());
}
#endif

bool QuickTestEvent::keySequence(const QVariant &keySequence)
{
    QWindow *window = activeWindow();
    if (!window)
        return false;
#if QT_CONFIG(shortcut)
    QTest::keySequence(window, valueToKeySequence(keySequence));
#else
    Q_UNUSED(keySequence);
#endif
    return true;
}

namespace QtQuickTest
{
    enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove, MouseDoubleClickSequence };

    int lastMouseTimestamp = 0;

    // TODO should be Qt::MouseButtons buttons in case multiple buttons are pressed
    static void mouseEvent(MouseAction action, QWindow *window,
                           QObject *item, Qt::MouseButton button,
                           Qt::KeyboardModifiers stateKey, const QPointF &_pos, int delay=-1)
    {
        QTEST_ASSERT(window);
        QTEST_ASSERT(item);

        if (delay == -1 || delay < QTest::defaultMouseDelay())
            delay = QTest::defaultMouseDelay();
        if (delay > 0) {
            QTest::qWait(delay);
            lastMouseTimestamp += delay;
        }

        if (action == MouseClick) {
            mouseEvent(MousePress, window, item, button, stateKey, _pos);
            mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
            return;
        }

        if (action == MouseDoubleClickSequence) {
            mouseEvent(MousePress, window, item, button, stateKey, _pos);
            mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
            mouseEvent(MousePress, window, item, button, stateKey, _pos);
            mouseEvent(MouseDoubleClick, window, item, button, stateKey, _pos);
            mouseEvent(MouseRelease, window, item, button, stateKey, _pos);
            return;
        }

        QPoint pos = _pos.toPoint();
        QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
        if (sgitem)
            pos = sgitem->mapToScene(_pos).toPoint();
        QTEST_ASSERT(button == Qt::NoButton || button & Qt::MouseButtonMask);
        QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);

        stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);

        QMouseEvent me(QEvent::User, QPoint(), Qt::LeftButton, button, stateKey);
        switch (action)
        {
            case MousePress:
                me = QMouseEvent(QEvent::MouseButtonPress, pos, window->mapToGlobal(pos), button, button, stateKey);
                me.setTimestamp(++lastMouseTimestamp);
                break;
            case MouseRelease:
                me = QMouseEvent(QEvent::MouseButtonRelease, pos, window->mapToGlobal(pos), button, {}, stateKey);
                me.setTimestamp(++lastMouseTimestamp);
                lastMouseTimestamp += 500; // avoid double clicks being generated
                break;
            case MouseDoubleClick:
                me = QMouseEvent(QEvent::MouseButtonDblClick, pos, window->mapToGlobal(pos), button, button, stateKey);
                me.setTimestamp(++lastMouseTimestamp);
                break;
            case MouseMove:
                // with move event the button is NoButton, but 'buttons' holds the currently pressed buttons
                me = QMouseEvent(QEvent::MouseMove, pos, window->mapToGlobal(pos), Qt::NoButton, button, stateKey);
                me.setTimestamp(++lastMouseTimestamp);
                break;
            default:
                QTEST_ASSERT(false);
        }
        QSpontaneKeyEvent::setSpontaneous(&me);
        if (!qApp->notify(window, &me)) {
            static const char *mouseActionNames[] =
                { "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove", "MouseDoubleClickSequence" };
            QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving window");
            QWARN(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toLatin1().data());
        }
    }

#if QT_CONFIG(wheelevent)
    static void mouseWheel(QWindow* window, QObject* item, Qt::MouseButtons buttons,
                                Qt::KeyboardModifiers stateKey,
                                QPointF _pos, int xDelta, int yDelta, int delay = -1)
    {
        QTEST_ASSERT(window);
        QTEST_ASSERT(item);
        if (delay == -1 || delay < QTest::defaultMouseDelay())
            delay = QTest::defaultMouseDelay();
        if (delay > 0)
            QTest::qWait(delay);

        QPoint pos;
        QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
        if (sgitem)
            pos = sgitem->mapToScene(_pos).toPoint();

        QTEST_ASSERT(buttons == Qt::NoButton || buttons & Qt::MouseButtonMask);
        QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);

        stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask);
        QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), buttons,
                       stateKey, Qt::NoScrollPhase, false);

        QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm
        if (!qApp->notify(window, &we))
            QTest::qWarn("Wheel event not accepted by receiving window");
    }
#endif
};

bool QuickTestEvent::mousePress
    (QObject *item, qreal x, qreal y, int button,
     int modifiers, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    m_pressedButtons.setFlag(Qt::MouseButton(button), true);
    QtQuickTest::mouseEvent(QtQuickTest::MousePress, view, item,
                            Qt::MouseButton(button),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), delay);
    return true;
}

#if QT_CONFIG(wheelevent)
bool QuickTestEvent::mouseWheel(
    QObject *item, qreal x, qreal y, int buttons,
    int modifiers, int xDelta, int yDelta, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    QtQuickTest::mouseWheel(view, item, Qt::MouseButtons(buttons),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), xDelta, yDelta, delay);
    return true;
}
#endif

bool QuickTestEvent::mouseRelease
    (QObject *item, qreal x, qreal y, int button,
     int modifiers, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    m_pressedButtons.setFlag(Qt::MouseButton(button), false);
    QtQuickTest::mouseEvent(QtQuickTest::MouseRelease, view, item,
                            Qt::MouseButton(button),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), delay);
    return true;
}

bool QuickTestEvent::mouseClick
    (QObject *item, qreal x, qreal y, int button,
     int modifiers, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    QtQuickTest::mouseEvent(QtQuickTest::MouseClick, view, item,
                            Qt::MouseButton(button),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), delay);
    return true;
}

bool QuickTestEvent::mouseDoubleClick
    (QObject *item, qreal x, qreal y, int button,
     int modifiers, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    QtQuickTest::mouseEvent(QtQuickTest::MouseDoubleClick, view, item,
                            Qt::MouseButton(button),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), delay);
    return true;
}

bool QuickTestEvent::mouseDoubleClickSequence
    (QObject *item, qreal x, qreal y, int button,
     int modifiers, int delay)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    QtQuickTest::mouseEvent(QtQuickTest::MouseDoubleClickSequence, view, item,
                            Qt::MouseButton(button),
                            Qt::KeyboardModifiers(modifiers),
                            QPointF(x, y), delay);
    return true;
}

bool QuickTestEvent::mouseMove
    (QObject *item, qreal x, qreal y, int delay, int buttons)
{
    QWindow *view = eventWindow(item);
    if (!view)
        return false;
    const Qt::MouseButtons effectiveButtons = buttons ? Qt::MouseButtons(buttons) : m_pressedButtons;
    QtQuickTest::mouseEvent(QtQuickTest::MouseMove, view, item,
                            Qt::MouseButton(int(effectiveButtons)), Qt::NoModifier,
                            QPointF(x, y), delay);
    return true;
}

QWindow *QuickTestEvent::eventWindow(QObject *item)
{
    QWindow * window = qobject_cast<QWindow *>(item);
    if (window)
        return window;

    QQuickItem *quickItem = qobject_cast<QQuickItem *>(item);
    if (quickItem)
        return quickItem->window();

    QQuickItem *testParentitem = qobject_cast<QQuickItem *>(parent());
    if (testParentitem)
        return testParentitem->window();
    return nullptr;
}

QWindow *QuickTestEvent::activeWindow()
{
    if (QWindow *window = QGuiApplication::focusWindow())
        return window;
    return eventWindow();
}

QQuickTouchEventSequence::QQuickTouchEventSequence(QuickTestEvent *testEvent, QObject *item)
        : QObject(testEvent)
        , m_sequence(QTest::touchEvent(testEvent->eventWindow(item), testEvent->touchDevice()))
        , m_testEvent(testEvent)
{
}

QObject *QQuickTouchEventSequence::press(int touchId, QObject *item, qreal x, qreal y)
{
    QWindow *view = m_testEvent->eventWindow(item);
    if (view) {
        QPointF pos(x, y);
        QQuickItem *quickItem = qobject_cast<QQuickItem *>(item);
        if (quickItem) {
            pos = quickItem->mapToScene(pos);
        }
        m_sequence.press(touchId, pos.toPoint(), view);
    }
    return this;
}

QObject *QQuickTouchEventSequence::move(int touchId, QObject *item, qreal x, qreal y)
{
    QWindow *view = m_testEvent->eventWindow(item);
    if (view) {
        QPointF pos(x, y);
        QQuickItem *quickItem = qobject_cast<QQuickItem *>(item);
        if (quickItem) {
            pos = quickItem->mapToScene(pos);
        }
        m_sequence.move(touchId, pos.toPoint(), view);
    }
    return this;
}

QObject *QQuickTouchEventSequence::release(int touchId, QObject *item, qreal x, qreal y)
{
    QWindow *view = m_testEvent->eventWindow(item);
    if (view) {
        QPointF pos(x, y);
        QQuickItem *quickItem = qobject_cast<QQuickItem *>(item);
        if (quickItem) {
            pos = quickItem->mapToScene(pos);
        }
        m_sequence.release(touchId, pos.toPoint(), view);
    }
    return this;
}

QObject *QQuickTouchEventSequence::stationary(int touchId)
{
    m_sequence.stationary(touchId);
    return this;
}

QObject *QQuickTouchEventSequence::commit()
{
    m_sequence.commit();
    return this;
}

/*!
    Return a simulated touchscreen, creating one if necessary

    \internal
*/

QTouchDevice *QuickTestEvent::touchDevice()
{
    static QTouchDevice *device(nullptr);

    if (!device) {
        device = new QTouchDevice;
        device->setType(QTouchDevice::TouchScreen);
        QWindowSystemInterface::registerTouchDevice(device);
    }
    return device;
}

/*!
    Creates a new QQuickTouchEventSequence.

    If valid, \a item determines the QWindow that touch events are sent to.
    Test code should use touchEvent() from the QML TestCase type.

    \internal
*/
QQuickTouchEventSequence *QuickTestEvent::touchEvent(QObject *item)
{
    return new QQuickTouchEventSequence(this, item);
}

QT_END_NAMESPACE
