/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>
#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h>
#include <QtVirtualKeyboard/private/qvirtualkeyboardinputcontext_p.h>
#include <QtVirtualKeyboard/private/shifthandler_p.h>
#include <QtVirtualKeyboard/private/fallbackinputmethod_p.h>
#include <QtVirtualKeyboard/qvirtualkeyboardtrace.h>
#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>

#include <QTimerEvent>
#include <QtCore/private/qobject_p.h>

QT_BEGIN_NAMESPACE
using namespace QtVirtualKeyboard;

class QVirtualKeyboardInputEnginePrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QVirtualKeyboardInputEngine)

public:
    QVirtualKeyboardInputEnginePrivate(QVirtualKeyboardInputEngine *q_ptr) :
        QObjectPrivate(),
        q_ptr(q_ptr),
        inputContext(nullptr),
        fallbackInputMethod(nullptr),
        textCase(QVirtualKeyboardInputEngine::TextCase::Lower),
        inputMode(QVirtualKeyboardInputEngine::InputMode::Latin),
        activeKey(Qt::Key_unknown),
        activeKeyModifiers(Qt::NoModifier),
        previousKey(Qt::Key_unknown),
        repeatTimer(0),
        repeatCount(0),
        recursiveMethodLock(0)
    {
    }

    virtual ~QVirtualKeyboardInputEnginePrivate()
    {
    }

    bool virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool isAutoRepeat)
    {
        Q_Q(QVirtualKeyboardInputEngine);
        bool accept = false;
        if (inputMethod) {
            accept = inputMethod->keyEvent(key, text, modifiers);
            if (!accept) {
                accept = fallbackInputMethod->keyEvent(key, text, modifiers);
            }
            emit q->virtualKeyClicked(key, text, modifiers, isAutoRepeat);
        } else if (QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS) {
            accept = fallbackInputMethod->keyEvent(key, text, modifiers);
            emit q->virtualKeyClicked(key, text, modifiers, isAutoRepeat);
        } else {
            qWarning() << "input method is not set";
        }
        return accept;
    }

    QVirtualKeyboardInputEngine* q_ptr;
    QVirtualKeyboardInputContext *inputContext;
    QPointer<QVirtualKeyboardAbstractInputMethod> inputMethod;
    QVirtualKeyboardAbstractInputMethod *fallbackInputMethod;
    QVirtualKeyboardInputEngine::TextCase textCase;
    QVirtualKeyboardInputEngine::InputMode inputMode;
    QList<int> inputModes;
    QMap<QVirtualKeyboardSelectionListModel::Type, QVirtualKeyboardSelectionListModel *> selectionListModels;
    Qt::Key activeKey;
    QString activeKeyText;
    Qt::KeyboardModifiers activeKeyModifiers;
    Qt::Key previousKey;
    int repeatTimer;
    int repeatCount;
    int recursiveMethodLock;
};

class RecursiveMethodGuard
{
public:
    explicit RecursiveMethodGuard(int &ref) : m_ref(ref)
    {
        m_ref++;
    }
    ~RecursiveMethodGuard()
    {
        m_ref--;
    }
    bool locked() const
    {
        return m_ref > 1;
    }
private:
    int &m_ref;
};

/*!
    \qmltype InputEngine
    \inqmlmodule QtQuick.VirtualKeyboard
    \ingroup qtvirtualkeyboard-qml
    \instantiates QVirtualKeyboardInputEngine
    \brief Maps the user input to the input methods.

    The input engine is responsible for routing input events to input
    methods. The actual input logic is implemented by the input methods.

    The input engine also includes the default input method, which takes
    care of default processing if the active input method does not handle
    the event.
*/

/*!
    \class QVirtualKeyboardInputEngine
    \inmodule QtVirtualKeyboard
    \brief The InputEngine class provides an input engine
    that supports C++ and QML integration.

    The input engine is responsible for routing input events to input
    methods. The actual input logic is implemented by the input methods.

    The input engine also includes the default input method, which takes
    care of default processing if the active input method does not handle
    the event.
*/

/*!
    \internal
    Constructs an input engine with input context as \a parent.
*/
QVirtualKeyboardInputEngine::QVirtualKeyboardInputEngine(QVirtualKeyboardInputContext *parent) :
    QObject(*new QVirtualKeyboardInputEnginePrivate(this), parent)
{
    Q_D(QVirtualKeyboardInputEngine);
    d->inputContext = parent;
}

void QVirtualKeyboardInputEngine::init()
{
    Q_D(QVirtualKeyboardInputEngine);
    ShiftHandler *shiftHandler = d->inputContext->priv()->shiftHandler();
    QObject::connect(shiftHandler, &ShiftHandler::shiftActiveChanged, this, &QVirtualKeyboardInputEngine::shiftChanged);
    QObject::connect(d->inputContext, &QVirtualKeyboardInputContext::localeChanged, this, &QVirtualKeyboardInputEngine::update);
    QObject::connect(d->inputContext, &QVirtualKeyboardInputContext::inputMethodHintsChanged, this, &QVirtualKeyboardInputEngine::updateSelectionListModels);
    QObject::connect(d->inputContext, &QVirtualKeyboardInputContext::localeChanged, this, &QVirtualKeyboardInputEngine::updateInputModes);
    QObject::connect(this, &QVirtualKeyboardInputEngine::inputMethodChanged, this, &QVirtualKeyboardInputEngine::updateInputModes);
    d->fallbackInputMethod = new FallbackInputMethod(this);
    if (d->fallbackInputMethod)
        d->fallbackInputMethod->setInputEngine(this);
    d->selectionListModels[QVirtualKeyboardSelectionListModel::Type::WordCandidateList] = new QVirtualKeyboardSelectionListModel(this);
}

/*!
    \internal
    Destroys the input engine and frees all allocated resources.
*/
QVirtualKeyboardInputEngine::~QVirtualKeyboardInputEngine()
{
}

/*!
    \qmlmethod bool InputEngine::virtualKeyPress(int key, string text, int modifiers, bool repeat)

    Called by the keyboard layer to indicate that \a key was pressed, with
    the given \a text and \a modifiers.

    The \a key is set as an active key (down key). The actual key event is
    triggered when the key is released by the virtualKeyRelease() method. The
    key press event can be discarded by calling virtualKeyCancel().

    The key press also initiates the key repeat timer if \a repeat is \c true.

    Returns \c true if the key was accepted by this input engine.

    \sa virtualKeyCancel(), virtualKeyRelease()
*/
/*!
    Called by the keyboard layer to indicate that \a key was pressed, with
    the given \a text and \a modifiers.

    The \a key is set as an active key (down key). The actual key event is
    triggered when the key is released by the virtualKeyRelease() method. The
    key press event can be discarded by calling virtualKeyCancel().

    The key press also initiates the key repeat timer if \a repeat is \c true.

    Returns \c true if the key was accepted by this input engine.

    \sa virtualKeyCancel(), virtualKeyRelease()
*/
bool QVirtualKeyboardInputEngine::virtualKeyPress(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool repeat)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyPress()"
#ifdef SENSITIVE_DEBUG
           << key << text << modifiers << repeat
#endif
        ;

    bool accept = false;
    if (d->activeKey == Qt::Key_unknown || d->activeKey == key) {
        d->activeKey = key;
        d->activeKeyText = text;
        d->activeKeyModifiers = modifiers;
        if (repeat) {
            d->repeatTimer = startTimer(600);
        }
        accept = true;
        emit activeKeyChanged(d->activeKey);
    } else {
        qWarning("key press ignored; key is already active");
    }
    return accept;
}

/*!
    \qmlmethod void InputEngine::virtualKeyCancel()

    Reverts the active key state without emitting the key event.
    This method is useful when the user discards the current key and
    the key state needs to be restored.
*/
/*!
    \fn void QVirtualKeyboardInputEngine::virtualKeyCancel()

    Reverts the active key state without emitting the key event.
    This method is useful when the user discards the current key and
    the key state needs to be restored.
*/
void QVirtualKeyboardInputEngine::virtualKeyCancel()
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyCancel()";
    if (d->activeKey != Qt::Key_unknown) {
        d->activeKey = Qt::Key_unknown;
        d->activeKeyText = QString();
        d->activeKeyModifiers = Qt::KeyboardModifiers();
        if (d->repeatTimer) {
            killTimer(d->repeatTimer);
            d->repeatTimer = 0;
            d->repeatCount = 0;
        }
        emit activeKeyChanged(d->activeKey);
    }
}

/*!
    \qmlmethod bool InputEngine::virtualKeyRelease(int key, string text, int modifiers)

    Releases the key at \a key. The method emits a key event for the input
    method if the event has not been generated by a repeating timer.
    The \a text and \a modifiers are passed to the input method.

    Returns \c true if the key was accepted by the input engine.
*/
/*!
    Releases the key at \a key. The method emits a key event for the input
    method if the event has not been generated by a repeating timer.
    The \a text and \a modifiers are passed to the input method.

    Returns \c true if the key was accepted by the input engine.
*/
bool QVirtualKeyboardInputEngine::virtualKeyRelease(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyRelease()"
#ifdef SENSITIVE_DEBUG
           << key << text << modifiers
#endif
        ;

    bool accept = false;
    if (d->activeKey == key) {
        if (!d->repeatCount) {
            accept = d->virtualKeyClick(key, text, modifiers, false);
        } else {
            accept = true;
        }
    } else {
        qWarning("key release ignored; key is not pressed");
    }
    if (d->activeKey != Qt::Key_unknown) {
        d->previousKey = d->activeKey;
        emit previousKeyChanged(d->previousKey);
        d->activeKey = Qt::Key_unknown;
        d->activeKeyText = QString();
        d->activeKeyModifiers = Qt::KeyboardModifiers();
        if (d->repeatTimer) {
            killTimer(d->repeatTimer);
            d->repeatTimer = 0;
            d->repeatCount = 0;
        }
        emit activeKeyChanged(d->activeKey);
    }
    return accept;
}

/*!
    \qmlmethod bool InputEngine::virtualKeyClick(int key, string text, int modifiers)

    Emits a key click event for the given \a key, \a text and \a modifiers.
    Returns \c true if the key event was accepted by the input engine.
*/
/*!
    Emits a key click event for the given \a key, \a text and \a modifiers.
    Returns \c true if the key event was accepted by the input engine.
*/
bool QVirtualKeyboardInputEngine::virtualKeyClick(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::virtualKeyClick()"
#ifdef SENSITIVE_DEBUG
           << key << text << modifiers
#endif
        ;
    return d->virtualKeyClick(key, text, modifiers, false);
}

/*!
    Returns the \c InputContext instance associated with the input
    engine.
*/
QVirtualKeyboardInputContext *QVirtualKeyboardInputEngine::inputContext() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->inputContext;
}

/*!
    Returns the currently active key, or Qt::Key_unknown if no key is active.
*/
Qt::Key QVirtualKeyboardInputEngine::activeKey() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->activeKey;
}

/*!
    Returns the previously active key, or Qt::Key_unknown if no key has been
    active.
*/
Qt::Key QVirtualKeyboardInputEngine::previousKey() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->previousKey;
}

/*!
    Returns the active input method.
*/
QVirtualKeyboardAbstractInputMethod *QVirtualKeyboardInputEngine::inputMethod() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->inputMethod;
}

/*!
    Sets \a inputMethod as the active input method.
*/
void QVirtualKeyboardInputEngine::setInputMethod(QVirtualKeyboardAbstractInputMethod *inputMethod)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::setInputMethod():" << inputMethod;
    if (d->inputMethod != inputMethod) {
        update();
        if (d->inputMethod) {
            QObject::disconnect(d->inputMethod.data(), &QVirtualKeyboardAbstractInputMethod::selectionListsChanged, this, &QVirtualKeyboardInputEngine::updateSelectionListModels);
            d->inputMethod->setInputEngine(nullptr);
        }
        d->inputMethod = inputMethod;
        if (d->inputMethod) {
            d->inputMethod->setInputEngine(this);
            QObject::connect(d->inputMethod.data(), &QVirtualKeyboardAbstractInputMethod::selectionListsChanged, this, &QVirtualKeyboardInputEngine::updateSelectionListModels);

            // Set current text case
            d->inputMethod->setTextCase(d->textCase);
        }
        updateSelectionListModels();
        emit inputMethodChanged();
        emit patternRecognitionModesChanged();
    }
}

/*!
    Returns the list of available input modes.
*/
QList<int> QVirtualKeyboardInputEngine::inputModes() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->inputModes;
}

QVirtualKeyboardInputEngine::InputMode QVirtualKeyboardInputEngine::inputMode() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->inputMode;
}

void QVirtualKeyboardInputEngine::setInputMode(QVirtualKeyboardInputEngine::InputMode inputMode)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::setInputMode():" << inputMode;
    if (d->inputMethod) {
#ifdef QT_DEBUG
        // Cached input modes should be in sync with the input method
        // If the assert below fails, we have missed an update somewhere
        QList<int> cachedInputModes(d->inputModes);
        updateInputModes();
        Q_ASSERT(cachedInputModes == d->inputModes);
#endif
        if (d->inputModes.contains(static_cast<int>(inputMode))) {
            d->inputMethod->setInputMode(d->inputContext->locale(), inputMode);
            if (d->inputMode != inputMode) {
                d->inputMode = inputMode;
                emit inputModeChanged();
            }
        } else {
            qWarning() << "Input mode" << inputMode <<
                          "is not in the list of available input modes" << d->inputModes;
        }
    }
}

QVirtualKeyboardSelectionListModel *QVirtualKeyboardInputEngine::wordCandidateListModel() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    return d->selectionListModels[QVirtualKeyboardSelectionListModel::Type::WordCandidateList];
}

bool QVirtualKeyboardInputEngine::wordCandidateListVisibleHint() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    const auto it = d->selectionListModels.constFind(QVirtualKeyboardSelectionListModel::Type::WordCandidateList);
    if (it == d->selectionListModels.cend())
        return false;
    return it.value()->dataSource() != nullptr;
}

/*!
   Returns list of supported pattern recognition modes.
*/
QList<int> QVirtualKeyboardInputEngine::patternRecognitionModes() const
{
    Q_D(const QVirtualKeyboardInputEngine);
    QList<PatternRecognitionMode> patterRecognitionModeList;
    if (d->inputMethod)
        patterRecognitionModeList = d->inputMethod->patternRecognitionModes();
    QList<int> resultList;
    if (patterRecognitionModeList.isEmpty())
        return resultList;
    resultList.reserve(patterRecognitionModeList.size());
    for (const PatternRecognitionMode &patternRecognitionMode : qAsConst(patterRecognitionModeList))
        resultList.append(static_cast<int>(patternRecognitionMode));
    return resultList;
}

/*!
    \qmlmethod QVirtualKeyboardTrace InputEngine::traceBegin(int traceId, int patternRecognitionMode, var traceCaptureDeviceInfo, var traceScreenInfo)
    \since QtQuick.VirtualKeyboard 2.0

    Starts a trace interaction with the input engine.

    The trace is uniquely identified by the \a traceId. The input engine will assign
    the id to the Trace object if the input method accepts the event.

    The \a patternRecognitionMode specifies the recognition mode used for the pattern.

    If the current input method accepts the event it returns a Trace object associated with this interaction.
    If the input method discards the event, it returns a null value.

    The \a traceCaptureDeviceInfo provides information about the source device and the \a traceScreenInfo
    provides information about the screen context.

    By definition, the Trace object remains valid until the traceEnd() method is called.

    The trace interaction is ended by calling the \l {InputEngine::traceEnd()} {InputEngine.traceEnd()} method.
*/
/*!
    \since QtQuick.VirtualKeyboard 2.0

    Starts a trace interaction with the input engine.

    The trace is uniquely identified by the \a traceId. The input engine will assign
    the id to the QVirtualKeyboardTrace object if the input method accepts the event.

    The \a patternRecognitionMode specifies the recognition mode used for the pattern.

    If the current input method accepts the event it returns a QVirtualKeyboardTrace object associated with this interaction.
    If the input method discards the event, it returns a NULL value.

    The \a traceCaptureDeviceInfo provides information about the source device and the \a traceScreenInfo
    provides information about the screen context.

    By definition, the QVirtualKeyboardTrace object remains valid until the traceEnd() method is called.

    The trace interaction is ended by calling the traceEnd() method.
*/
QVirtualKeyboardTrace *QVirtualKeyboardInputEngine::traceBegin(
        int traceId, PatternRecognitionMode patternRecognitionMode,
        const QVariantMap &traceCaptureDeviceInfo, const QVariantMap &traceScreenInfo)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::traceBegin():"
                            << "traceId:" << traceId
                            << "patternRecognitionMode:" << patternRecognitionMode
                            << "traceCaptureDeviceInfo:" << traceCaptureDeviceInfo
                            << "traceScreenInfo:" << traceScreenInfo;
    if (!d->inputMethod)
        return nullptr;
    if (patternRecognitionMode == PatternRecognitionMode::None)
        return nullptr;
    if (!d->inputMethod->patternRecognitionModes().contains(patternRecognitionMode))
        return nullptr;
    QVirtualKeyboardTrace *trace = d->inputMethod->traceBegin(traceId, patternRecognitionMode, traceCaptureDeviceInfo, traceScreenInfo);
    if (trace)
        trace->setTraceId(traceId);
    return trace;
}

/*!
    \qmlmethod bool InputEngine::traceEnd(Trace trace)

    Ends the trace interaction with the input engine.

    The \a trace object may be discarded at any point after calling this function.

    The function returns true if the trace interaction was accepted (i.e. the touch
    events should not be used for anything else).
*/
/*!
    Ends the trace interaction with the input engine.

    The \a trace object may be discarded at any point after calling this function.

    The function returns true if the trace interaction was accepted (i.e. the touch
    events should not be used for anything else).
*/
bool QVirtualKeyboardInputEngine::traceEnd(QVirtualKeyboardTrace *trace)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::traceEnd():" << trace;
    Q_ASSERT(trace);
    if (!d->inputMethod)
        return false;
    return d->inputMethod->traceEnd(trace);
}

/*!
    \since QtQuick.VirtualKeyboard 2.0

    This function attempts to reselect a word located at the \a cursorPosition.
    The \a reselectFlags define the rules for how the word should be selected in
    relation to the cursor position.

    The function returns \c true if the word was successfully reselected.
*/
bool QVirtualKeyboardInputEngine::reselect(int cursorPosition, const ReselectFlags &reselectFlags)
{
    Q_D(QVirtualKeyboardInputEngine);
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputEngine::reselect():" << cursorPosition << reselectFlags;
    if (!d->inputMethod || !wordCandidateListVisibleHint())
        return false;
    return d->inputMethod->reselect(cursorPosition, reselectFlags);
}

/*!
    \internal
    This method is called when the current preedit text is clicked.
*/
bool QVirtualKeyboardInputEngine::clickPreeditText(int cursorPosition)
{
    Q_D(QVirtualKeyboardInputEngine);
    if (!d->inputMethod)
        return false;
    return d->inputMethod->clickPreeditText(cursorPosition);
}

/*!
    \internal
    Resets the input method.
*/
void QVirtualKeyboardInputEngine::reset()
{
    Q_D(QVirtualKeyboardInputEngine);
    if (d->inputMethod) {
        RecursiveMethodGuard guard(d->recursiveMethodLock);
        if (!guard.locked()) {
            emit inputMethodReset();
            updateInputModes();
        }
    } else {
        updateInputModes();
    }
}

/*!
    \internal
    Updates the input method's state. This method is called whenever the input
    context is changed.
*/
void QVirtualKeyboardInputEngine::update()
{
    Q_D(QVirtualKeyboardInputEngine);
    if (d->inputMethod) {
        RecursiveMethodGuard guard(d->recursiveMethodLock);
        if (!guard.locked()) {
            emit inputMethodUpdate();
        }
    }
}

/*!
    \internal
    Updates the text case for the input method.
*/
void QVirtualKeyboardInputEngine::shiftChanged()
{
    Q_D(QVirtualKeyboardInputEngine);
    TextCase newCase = d->inputContext->priv()->shiftHandler()->isShiftActive() ? TextCase::Upper : TextCase::Lower;
    if (d->textCase != newCase) {
        d->textCase = newCase;
        if (d->inputMethod) {
            d->inputMethod->setTextCase(d->textCase);
        }
    }
}

/*!
    \internal
*/
void QVirtualKeyboardInputEngine::updateSelectionListModels()
{
    Q_D(QVirtualKeyboardInputEngine);
    QList<QVirtualKeyboardSelectionListModel::Type> inactiveSelectionLists = d->selectionListModels.keys();
    if (d->inputMethod) {
        // Allocate selection lists for the input method
        const QList<QVirtualKeyboardSelectionListModel::Type> activeSelectionLists = d->inputMethod->selectionLists();
        for (const QVirtualKeyboardSelectionListModel::Type &selectionListType : activeSelectionLists) {
            auto it = d->selectionListModels.find(selectionListType);
            if (it == d->selectionListModels.end()) {
                it = d->selectionListModels.insert(selectionListType, new QVirtualKeyboardSelectionListModel(this));
                if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
                    emit wordCandidateListModelChanged();
            }
            it.value()->setDataSource(d->inputMethod, selectionListType);
            if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
                emit wordCandidateListVisibleHintChanged();
            inactiveSelectionLists.removeAll(selectionListType);
        }
    }

    // Deallocate inactive selection lists
    for (const QVirtualKeyboardSelectionListModel::Type &selectionListType : qAsConst(inactiveSelectionLists)) {
        const auto it = d->selectionListModels.constFind(selectionListType);
        if (it != d->selectionListModels.cend()) {
            it.value()->setDataSource(nullptr, selectionListType);
            if (selectionListType == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
                emit wordCandidateListVisibleHintChanged();
        }
    }
}

/*!
    \internal
*/
void QVirtualKeyboardInputEngine::updateInputModes()
{
    Q_D(QVirtualKeyboardInputEngine);
    QList<int> newInputModes;
    if (d->inputMethod) {
        QList<InputMode> tmpList(d->inputMethod->inputModes(d->inputContext->locale()));
        if (!tmpList.isEmpty()) {
            std::transform(tmpList.constBegin(), tmpList.constEnd(),
                           std::back_inserter(newInputModes),
                           [tmpList] (InputMode inputMode) {
                               return static_cast<int>(inputMode);
                           });
        }
    }
    if (d->inputModes != newInputModes) {
        d->inputModes = newInputModes;
        emit inputModesChanged();
    }
}

/*!
    \internal
*/
void QVirtualKeyboardInputEngine::timerEvent(QTimerEvent *timerEvent)
{
    Q_D(QVirtualKeyboardInputEngine);
    if (timerEvent->timerId() == d->repeatTimer) {
        d->repeatTimer = 0;
        d->virtualKeyClick(d->activeKey, d->activeKeyText, d->activeKeyModifiers, true);
        d->repeatTimer = startTimer(50);
        d->repeatCount++;
    }
}

/*!
    \qmlproperty int InputEngine::activeKey

    Currently pressed key.
*/

/*!
    \property QVirtualKeyboardInputEngine::activeKey
    \brief the active key.

    Currently pressed key.
*/

/*!
    \qmlproperty int InputEngine::previousKey

    Previously pressed key.
*/
/*!
    \property QVirtualKeyboardInputEngine::previousKey
    \brief the previous active key.

    Previously pressed key.
*/

/*!
    \qmlproperty InputMethod InputEngine::inputMethod

    Use this property to set the active input method, or to monitor when the
    active input method changes.
*/

/*!
    \property QVirtualKeyboardInputEngine::inputMethod
    \brief the active input method.

    Use this property to set active the input method, or to monitor when the
    active input method changes.
*/

/*!
    \qmlproperty list<int> InputEngine::inputModes

    The list of available input modes is dependent on the input method and
    locale. This property is updated when either of the dependencies change.
*/

/*!
    \property QVirtualKeyboardInputEngine::inputModes
    \brief the available input modes for active input method.

    The list of available input modes is dependent on the input method and
    locale. This property is updated when either of the dependencies changes.
*/

/*!
    \qmlproperty int InputEngine::inputMode

    Use this property to get or set the current input mode. The
    InputEngine::inputModes property provides the list of valid input modes
    for the current input method and locale.

    The predefined input modes are:

    \list
        \li \c InputEngine.InputMode.Latin The default input mode for latin text.
        \li \c InputEngine.InputMode.Numeric Only numeric input is allowed.
        \li \c InputEngine.InputMode.Dialable Only dialable input is allowed.
        \li \c InputEngine.InputMode.Pinyin Pinyin input mode for Chinese.
        \li \c InputEngine.InputMode.Cangjie Cangjie input mode for Chinese.
        \li \c InputEngine.InputMode.Zhuyin Zhuyin input mode for Chinese.
        \li \c InputEngine.InputMode.Hangul Hangul input mode for Korean.
        \li \c InputEngine.InputMode.Hiragana Hiragana input mode for Japanese.
        \li \c InputEngine.InputMode.Katakana Katakana input mode for Japanese.
        \li \c InputEngine.InputMode.FullwidthLatin Fullwidth latin input mode for East Asian languages.
        \li \c InputEngine.InputMode.Greek Greek input mode.
        \li \c InputEngine.InputMode.Cyrillic Cyrillic input mode.
        \li \c InputEngine.InputMode.Arabic Arabic input mode.
        \li \c InputEngine.InputMode.Hebrew Hebrew input mode.
        \li \c InputEngine.InputMode.ChineseHandwriting Chinese handwriting.
        \li \c InputEngine.InputMode.JapaneseHandwriting Japanese handwriting.
        \li \c InputEngine.InputMode.KoreanHandwriting Korean handwriting.
        \li \c InputEngine.InputMode.Thai Thai input mode.
    \endlist
*/

/*!
    \property QVirtualKeyboardInputEngine::inputMode
    \brief the current input mode.

    Use this property to get or set the current input mode. The
    InputEngine::inputModes provides list of valid input modes
    for current input method and locale.
*/

/*!
    \qmlproperty QVirtualKeyboardSelectionListModel InputEngine::wordCandidateListModel

    Use this property to access the list model for the word candidate
    list.
*/

/*!
    \property QVirtualKeyboardInputEngine::wordCandidateListModel
    \brief list model for the word candidate list.

    Use this property to access the list model for the word candidate
    list.
*/

/*!
    \qmlproperty bool InputEngine::wordCandidateListVisibleHint

    Use this property to check if the word candidate list should be visible
    in the UI.
*/

/*!
    \property QVirtualKeyboardInputEngine::wordCandidateListVisibleHint
    \brief visible hint for the word candidate list.

    Use this property to check if the word candidate list should be visible
    in the UI.
*/

/*!
    \enum QVirtualKeyboardInputEngine::InputMode

    This enum specifies the input mode for the input method.

    \value Latin
           The default input mode for latin text.
    \value Numeric
           Only numeric input is allowed.
    \value Dialable
           Only dialable input is allowed.
    \value Pinyin
           Pinyin input mode for Chinese.
    \value Cangjie
           Cangjie input mode for Chinese.
    \value Zhuyin
           Zhuyin input mode for Chinese.
    \value Hangul
           Hangul input mode for Korean.
    \value Hiragana
           Hiragana input mode for Japanese.
    \value Katakana
           Katakana input mode for Japanese.
    \value FullwidthLatin
           Fullwidth latin input mode for East Asian languages.
    \value Greek
           Greek input mode.
    \value Cyrillic
           Cyrillic input mode.
    \value Arabic
           Arabic input mode.
    \value Hebrew
           Hebrew input mode.
    \value ChineseHandwriting
           Chinese handwriting input mode.
    \value JapaneseHandwriting
           Japanese handwriting input mode.
    \value KoreanHandwriting
           Korean handwriting input mode.
    \value Thai
           Thai input mode.
*/

/*!
    \enum QVirtualKeyboardInputEngine::TextCase

    This enum specifies the text case for the input method.

    \value Lower
           Lower case text.
    \value Upper
           Upper case text.
*/

/*!
    \enum QVirtualKeyboardInputEngine::PatternRecognitionMode

    This enum specifies the input mode for the input method.

    \value None
           Pattern recognition is not available.
    \value PatternRecognitionDisabled
           \c obsolete Use PatternRecognitionMode::None
    \value Handwriting
           Pattern recognition mode for handwriting recognition.
    \value HandwritingRecoginition
           \c obsolete Use PatternRecognitionMode::Handwriting
*/

/*!
    \enum QVirtualKeyboardInputEngine::ReselectFlag

    This enum specifies the rules for word reselection.

    \value WordBeforeCursor
           Activate the word before the cursor. When this flag is used exclusively, the word must end exactly at the cursor.
    \value WordAfterCursor
           Activate the word after the cursor. When this flag is used exclusively, the word must start exactly at the cursor.
    \value WordAtCursor
           Activate the word at the cursor. This flag is a combination of the above flags with the exception that the word cannot start or stop at the cursor.
*/

/*!
    \qmlsignal void InputEngine::virtualKeyClicked(int key, string text, int modifiers)

    Indicates that the virtual \a key was clicked with the given \a text and
    \a modifiers.
    This signal is emitted after the input method has processed the key event.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::virtualKeyClicked(Qt::Key key, const QString &text, Qt::KeyboardModifiers modifiers, bool isAutoRepeat)

    Indicates that the virtual \a key was clicked with the given \a text and
    \a modifiers. The \a isAutoRepeat indicates if the event is automatically
    repeated while the key is being pressed.
    This signal is emitted after the input method has processed the key event.
*/

/*!
    \qmlproperty list<int> InputEngine::patternRecognitionModes
    \since QtQuick.VirtualKeyboard 2.0

    The list of available pattern recognition modes.

    Possible values:

    \value InputEngine.PatternRecognitionMode.None
           Pattern recognition is not available.
    \value InputEngine.PatternRecognitionMode.PatternRecognitionDisabled
           \c obsolete - Use \c None instead.
    \value InputEngine.PatternRecognitionMode.Handwriting
           Pattern recognition mode for handwriting recognition.
    \value InputEngine.PatternRecognitionMode.HandwritingRecoginition
           \c obsolete - Use \c Handwriting instead.

*/

/*!
    \property QVirtualKeyboardInputEngine::patternRecognitionModes
    \since QtQuick.VirtualKeyboard 2.0
    \brief the list of available pattern recognition modes.

    The list of available pattern recognition modes.
*/

/*!
    \qmlsignal void InputEngine::activeKeyChanged(int key)

    Indicates that the active \a key has changed.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::activeKeyChanged(Qt::Key key)

    Indicates that the active \a key has changed.
*/

/*!
    \qmlsignal void InputEngine::previousKeyChanged(int key)

    Indicates that the previous \a key has changed.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::previousKeyChanged(Qt::Key key)

    Indicates that the previous \a key has changed.
*/

/*!
    \qmlsignal void InputEngine::inputMethodChanged()

    Indicates that the input method has changed.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::inputMethodChanged()

    Indicates that the input method has changed.
*/

/*!
    \qmlsignal void InputEngine::inputMethodReset()

    Emitted when the input method needs to be reset.

    \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::reset()
    and InputMethod::reset() when the input method is activated.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::inputMethodReset()

    Emitted when the input method needs to be reset.

    \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::reset()
    and InputMethod::reset() when the input method is activated.
*/

/*!
    \qmlsignal void InputEngine::inputMethodUpdate()

    \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::update()
    and InputMethod::update() when the input method is activated.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::inputMethodUpdate()

    \note This signal is automatically connected to QVirtualKeyboardAbstractInputMethod::update()
    and InputMethod::update() when the input method is activated.
*/

/*!
    \qmlsignal void InputEngine::inputModesChanged()

    Indicates that the available input modes have changed.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::inputModesChanged()

    Indicates that the available input modes have changed.
*/

/*!
    \qmlsignal void InputEngine::inputModeChanged()

    Indicates that the input mode has changed.
*/

/*!
    \fn void QVirtualKeyboardInputEngine::inputModeChanged()

    Indicates that the input mode has changed.
*/

/*!
    \qmlsignal void InputEngine::patternRecognitionModesChanged()
    \since QtQuick.VirtualKeyboard 2.0

    Indicates that the available pattern recognition modes have changed.

    The predefined pattern recognition modes are:

    \list
        \li \c InputEngine.PatternRecognitionMode.None Pattern recognition is not available.
        \li \c InputEngine.PatternRecognitionMode.PatternRecognitionDisabled \c obsolete Use InputEngine.PatternRecognitionMode.None
        \li \c InputEngine.PatternRecognitionMode.Handwriting Pattern recognition mode for handwriting recognition.
        \li \c InputEngine.PatternRecognitionMode.HandwritingRecoginition \c obsolete Use InputEngine.PatternRecognitionMode.Handwriting
    \endlist
*/

/*!
    \fn void QVirtualKeyboardInputEngine::patternRecognitionModesChanged()
    \since QtQuick.VirtualKeyboard 2.0

    Indicates that the available pattern recognition modes have changed.
*/

QT_END_NAMESPACE
