/****************************************************************************
**
** 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 Trace 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 SelectionListModel 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
