/****************************************************************************
**
** Copyright (C) 2018 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/private/qvirtualkeyboardinputcontext_p.h>
#include <QtVirtualKeyboard/private/platforminputcontext_p.h>
#include <QtVirtualKeyboard/private/settings_p.h>
#include <QtVirtualKeyboard/private/shifthandler_p.h>
#include <QtVirtualKeyboard/private/virtualkeyboarddebug_p.h>
#include <QtVirtualKeyboard/private/enterkeyaction_p.h>
#include <QtVirtualKeyboard/qvirtualkeyboardinputengine.h>

#include <QGuiApplication>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickwindow.h>
#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/private/qguiapplication_p.h>

QT_BEGIN_NAMESPACE

bool operator==(const QInputMethodEvent::Attribute &attribute1, const QInputMethodEvent::Attribute &attribute2)
{
    return attribute1.start == attribute2.start &&
           attribute1.length == attribute2.length &&
           attribute1.type == attribute2.type &&
           attribute1.value == attribute2.value;
}

using namespace QtVirtualKeyboard;

const bool QtVirtualKeyboard::QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS = qEnvironmentVariableIsSet("QT_VIRTUALKEYBOARD_FORCE_EVENTS_WITHOUT_FOCUS");

QVirtualKeyboardInputContextPrivate::QVirtualKeyboardInputContextPrivate(QVirtualKeyboardInputContext *q_ptr) :
    QObject(nullptr),
    q_ptr(q_ptr),
    platformInputContext(nullptr),
    inputEngine(nullptr),
    _shiftHandler(nullptr),
    keyboardRect(),
    previewRect(),
    _previewVisible(false),
    animating(false),
    _focus(false),
    cursorPosition(0),
    anchorPosition(0),
    forceAnchorPosition(-1),
    _forceCursorPosition(-1),
    inputMethodHints(Qt::ImhNone),
    preeditText(),
    preeditTextAttributes(),
    surroundingText(),
    selectedText(),
    anchorRectangle(),
    cursorRectangle(),
    selectionControlVisible(false),
    anchorRectIntersectsClipRect(false),
    cursorRectIntersectsClipRect(false)
#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
    , activeNavigationKeys()
#endif
{
}

void QVirtualKeyboardInputContextPrivate::init()
{
    Q_Q(QVirtualKeyboardInputContext);
    QGuiApplicationPrivate *guiApplicationPrivate = QGuiApplicationPrivate::instance();
    QPlatformIntegration *platformIntegration = guiApplicationPrivate->platformIntegration();
    QPlatformInputContext *unknownPlatformInputContext = platformIntegration->inputContext();
    platformInputContext = qobject_cast<PlatformInputContext *>(unknownPlatformInputContext);
    inputEngine = new QVirtualKeyboardInputEngine(q);
    _shiftHandler = new ShiftHandler(q);
    inputEngine->init();
    _shiftHandler->init();
    _shadow.setInputContext(q);
    if (platformInputContext) {
        platformInputContext->setInputContext(q);
        QObject::connect(platformInputContext, &PlatformInputContext::focusObjectChanged, this, &QVirtualKeyboardInputContextPrivate::onInputItemChanged);
        QObject::connect(platformInputContext, &PlatformInputContext::focusObjectChanged, this, &QVirtualKeyboardInputContextPrivate::inputItemChanged);
    }
}

QVirtualKeyboardInputContextPrivate::~QVirtualKeyboardInputContextPrivate()
{
}

bool QVirtualKeyboardInputContextPrivate::focus() const
{
    return _focus;
}

void QVirtualKeyboardInputContextPrivate::setFocus(bool focus)
{
    if (_focus != focus) {
        VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::setFocus():" << focus;
        _focus = focus;
        emit focusChanged();
    }
}

QRectF QVirtualKeyboardInputContextPrivate::keyboardRectangle() const
{
    return keyboardRect;
}

void QVirtualKeyboardInputContextPrivate::setKeyboardRectangle(QRectF rectangle)
{
    if (keyboardRect != rectangle) {
        keyboardRect = rectangle;
        emit keyboardRectangleChanged();
        platformInputContext->emitKeyboardRectChanged();
    }
}

QRectF QVirtualKeyboardInputContextPrivate::previewRectangle() const
{
    return previewRect;
}

void QVirtualKeyboardInputContextPrivate::setPreviewRectangle(QRectF rectangle)
{
    if (previewRect != rectangle) {
        previewRect = rectangle;
        emit previewRectangleChanged();
    }
}

bool QVirtualKeyboardInputContextPrivate::previewVisible() const
{
    return _previewVisible;
}

void QVirtualKeyboardInputContextPrivate::setPreviewVisible(bool visible)
{
    if (_previewVisible != visible) {
        _previewVisible = visible;
        emit previewVisibleChanged();
    }
}

QString QVirtualKeyboardInputContextPrivate::locale() const
{
    return platformInputContext ? platformInputContext->locale().name() : QString();
}

void QVirtualKeyboardInputContextPrivate::setLocale(const QString &locale)
{
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::setLocale():" << locale;
    QLocale newLocale(locale);
    if (newLocale != platformInputContext->locale()) {
        platformInputContext->setLocale(newLocale);
        platformInputContext->setInputDirection(newLocale.textDirection());
        emit localeChanged();
    }
}

QObject *QVirtualKeyboardInputContextPrivate::inputItem() const
{
    return platformInputContext ? platformInputContext->focusObject() : nullptr;
}

ShiftHandler *QVirtualKeyboardInputContextPrivate::shiftHandler() const
{
    return _shiftHandler;
}

ShadowInputContext *QVirtualKeyboardInputContextPrivate::shadow() const
{
    return const_cast<ShadowInputContext *>(&_shadow);
}

QStringList QVirtualKeyboardInputContextPrivate::inputMethods() const
{
    return platformInputContext ? platformInputContext->inputMethods() : QStringList();
}

bool QVirtualKeyboardInputContextPrivate::fileExists(const QUrl &fileUrl)
{
    QString fileName;
    if (fileUrl.scheme() == QLatin1String("qrc")) {
        fileName = QLatin1Char(':') + fileUrl.path();
    } else {
        fileName = fileUrl.toLocalFile();
    }
    return !fileName.isEmpty() && QFile::exists(fileName);
}

bool QVirtualKeyboardInputContextPrivate::hasEnterKeyAction(QObject *item) const
{
    return item != nullptr && qmlAttachedPropertiesObject<EnterKeyAction>(item, false);
}

void QVirtualKeyboardInputContextPrivate::registerInputPanel(QObject *inputPanel)
{
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::registerInputPanel():" << inputPanel;
    Q_ASSERT(!this->inputPanel);
    this->inputPanel = inputPanel;
    if (QQuickItem *item = qobject_cast<QQuickItem *>(inputPanel))
        item->setZ(std::numeric_limits<qreal>::max());
}

void QVirtualKeyboardInputContextPrivate::hideInputPanel()
{
    platformInputContext->hideInputPanel();
}

void QVirtualKeyboardInputContextPrivate::updateAvailableLocales(const QStringList &availableLocales)
{
    Settings *settings = Settings::instance();
    if (settings)
        settings->setAvailableLocales(availableLocales);
}

void QVirtualKeyboardInputContextPrivate::forceCursorPosition(int anchorPosition, int cursorPosition)
{
    if (!_shadow.inputItem())
        return;
    if (!platformInputContext->m_visible)
        return;
    if (testState(State::Reselect))
        return;
    if (testState(State::SyncShadowInput))
        return;

    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::forceCursorPosition():" << cursorPosition << "anchorPosition:" << anchorPosition;
    if (!preeditText.isEmpty()) {
        forceAnchorPosition = -1;
        _forceCursorPosition = cursorPosition;
        if (cursorPosition > this->cursorPosition)
            _forceCursorPosition += preeditText.length();
        commit();
    } else {
        forceAnchorPosition = anchorPosition;
        _forceCursorPosition = cursorPosition;
        Q_Q(QVirtualKeyboardInputContext);
        q->setPreeditText(QString());
        if (!inputMethodHints.testFlag(Qt::ImhNoPredictiveText) &&
                   cursorPosition > 0 && selectedText.isEmpty()) {
            QVirtualKeyboardScopedState reselectState(this, State::Reselect);
            if (inputEngine->reselect(cursorPosition, QVirtualKeyboardInputEngine::ReselectFlag::WordAtCursor))
                setState(State::InputMethodClick);
        }
    }
}

void QVirtualKeyboardInputContextPrivate::onInputItemChanged()
{
    if (QObject *item = inputItem()) {
        if (QQuickItem *vkbPanel = qobject_cast<QQuickItem*>(inputPanel)) {
            if (QQuickItem *quickItem = qobject_cast<QQuickItem*>(item)) {
                const QVariant isDesktopPanel = vkbPanel->property("desktopPanel");
                /*
                    For integrated keyboards, make sure it's a sibling to the overlay. The
                    high z-order will make sure it gets events also during a modal session.
                */
                if (isDesktopPanel.isValid() && !isDesktopPanel.toBool())
                    vkbPanel->setParentItem(quickItem->window()->contentItem());
            }
        }
    } else {
        if (!activeKeys.isEmpty()) {
            // After losing keyboard focus it is impossible to track pressed keys
            activeKeys.clear();
            clearState(State::KeyEvent);
        }
    }
    clearState(State::InputMethodClick);
}

void QVirtualKeyboardInputContextPrivate::sendPreedit(const QString &text, const QList<QInputMethodEvent::Attribute> &attributes, int replaceFrom, int replaceLength)
{
    VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::sendPreedit()"
#ifdef SENSITIVE_DEBUG
           << text << replaceFrom << replaceLength
#endif
        ;

    bool textChanged = preeditText != text;
    bool attributesChanged = preeditTextAttributes != attributes;

    if (textChanged || attributesChanged) {
        preeditText = text;
        preeditTextAttributes = attributes;

        if (platformInputContext) {
            QInputMethodEvent event(text, attributes);
            const bool replace = replaceFrom != 0 || replaceLength > 0;
            if (replace)
                event.setCommitString(QString(), replaceFrom, replaceLength);

            sendInputMethodEvent(&event);

            // Send also to shadow input if only attributes changed.
            // In this case the update() may not be called, so the shadow
            // input may be out of sync.
            if (_shadow.inputItem() && !replace && !text.isEmpty() &&
                    !textChanged && attributesChanged) {
                VIRTUALKEYBOARD_DEBUG() << "QVirtualKeyboardInputContextPrivate::sendPreedit(shadow)"
#ifdef SENSITIVE_DEBUG
                       << text << replaceFrom << replaceLength
#endif
                    ;
                event.setAccepted(true);
                QGuiApplication::sendEvent(_shadow.inputItem(), &event);
            }
        }

        if (textChanged) {
            Q_Q(QVirtualKeyboardInputContext);
            emit q->preeditTextChanged();
        }
    }

    if (preeditText.isEmpty())
        preeditTextAttributes.clear();
}

void QVirtualKeyboardInputContextPrivate::sendInputMethodEvent(QInputMethodEvent *event)
{
    QVirtualKeyboardScopedState inputMethodEventState(this, State::InputMethodEvent);
    platformInputContext->sendEvent(event);
}

void QVirtualKeyboardInputContextPrivate::reset()
{
    inputEngine->reset();
}

void QVirtualKeyboardInputContextPrivate::commit()
{
    inputEngine->update();
}

void QVirtualKeyboardInputContextPrivate::update(Qt::InputMethodQueries queries)
{
    Q_Q(QVirtualKeyboardInputContext);

    // No need to fetch input clip rectangle during animation
    if (!(queries & ~Qt::ImInputItemClipRectangle) && animating)
        return;

    // fetch
    QInputMethodQueryEvent imQueryEvent(Qt::InputMethodQueries(Qt::ImHints |
                    Qt::ImQueryInput | Qt::ImInputItemClipRectangle));
    platformInputContext->sendEvent(&imQueryEvent);
    Qt::InputMethodHints inputMethodHints = Qt::InputMethodHints(imQueryEvent.value(Qt::ImHints).toInt());
    const int cursorPosition = imQueryEvent.value(Qt::ImCursorPosition).toInt();
    const int anchorPosition = imQueryEvent.value(Qt::ImAnchorPosition).toInt();
    QRectF anchorRectangle;
    QRectF cursorRectangle;
    if (const QGuiApplication *app = qApp) {
        anchorRectangle = app->inputMethod()->anchorRectangle();
        cursorRectangle = app->inputMethod()->cursorRectangle();
    } else {
        anchorRectangle = this->anchorRectangle;
        cursorRectangle = this->cursorRectangle;
    }
    QString surroundingText = imQueryEvent.value(Qt::ImSurroundingText).toString();
    QString selectedText = imQueryEvent.value(Qt::ImCurrentSelection).toString();

    // check against changes
    bool newInputMethodHints = inputMethodHints != this->inputMethodHints;
    bool newSurroundingText = surroundingText != this->surroundingText;
    bool newSelectedText = selectedText != this->selectedText;
    bool newAnchorPosition = anchorPosition != this->anchorPosition;
    bool newCursorPosition = cursorPosition != this->cursorPosition;
    bool newAnchorRectangle = anchorRectangle != this->anchorRectangle;
    bool newCursorRectangle = cursorRectangle != this->cursorRectangle;
    bool selectionControlVisible = platformInputContext->isInputPanelVisible() && (cursorPosition != anchorPosition) && !inputMethodHints.testFlag(Qt::ImhNoTextHandles);
    bool newSelectionControlVisible = selectionControlVisible != this->selectionControlVisible;

    QRectF inputItemClipRect = imQueryEvent.value(Qt::ImInputItemClipRectangle).toRectF();
    QRectF anchorRect = imQueryEvent.value(Qt::ImAnchorRectangle).toRectF();
    QRectF cursorRect = imQueryEvent.value(Qt::ImCursorRectangle).toRectF();

    bool anchorRectIntersectsClipRect = inputItemClipRect.intersects(anchorRect);
    bool newAnchorRectIntersectsClipRect = anchorRectIntersectsClipRect != this->anchorRectIntersectsClipRect;

    bool cursorRectIntersectsClipRect = inputItemClipRect.intersects(cursorRect);
    bool newCursorRectIntersectsClipRect = cursorRectIntersectsClipRect != this->cursorRectIntersectsClipRect;

    // update
    this->inputMethodHints = inputMethodHints;
    this->surroundingText = surroundingText;
    this->selectedText = selectedText;
    this->anchorPosition = anchorPosition;
    this->cursorPosition = cursorPosition;
    this->anchorRectangle = anchorRectangle;
    this->cursorRectangle = cursorRectangle;
    this->selectionControlVisible = selectionControlVisible;
    this->anchorRectIntersectsClipRect = anchorRectIntersectsClipRect;
    this->cursorRectIntersectsClipRect = cursorRectIntersectsClipRect;

    // update input engine
    if ((newSurroundingText || newCursorPosition) &&
            !testState(State::InputMethodEvent)) {
        commit();
    }
    if (newInputMethodHints) {
        reset();
    }

    // notify
    if (newInputMethodHints) {
        emit q->inputMethodHintsChanged();
    }
    if (newSurroundingText) {
        emit q->surroundingTextChanged();
    }
    if (newSelectedText) {
        emit q->selectedTextChanged();
    }
    if (newAnchorPosition) {
        emit q->anchorPositionChanged();
    }
    if (newCursorPosition) {
        emit q->cursorPositionChanged();
    }
    if (newAnchorRectangle) {
        emit q->anchorRectangleChanged();
    }
    if (newCursorRectangle) {
        emit q->cursorRectangleChanged();
    }
    if (newSelectionControlVisible) {
        emit q->selectionControlVisibleChanged();
    }
    if (newAnchorRectIntersectsClipRect) {
        emit q->anchorRectIntersectsClipRectChanged();
    }
    if (newCursorRectIntersectsClipRect) {
        emit q->cursorRectIntersectsClipRectChanged();
    }

    // word reselection
    if (newInputMethodHints || newSurroundingText || newSelectedText)
        clearState(State::InputMethodClick);
    if ((newSurroundingText || newCursorPosition) && !newSelectedText && isEmptyState() &&
            !inputMethodHints.testFlag(Qt::ImhNoPredictiveText) &&
            cursorPosition > 0 && this->selectedText.isEmpty()) {
        QVirtualKeyboardScopedState reselectState(this, State::Reselect);
        if (inputEngine->reselect(cursorPosition, QVirtualKeyboardInputEngine::ReselectFlag::WordAtCursor))
            setState(State::InputMethodClick);
    }

    if (!testState(State::SyncShadowInput)) {
        QVirtualKeyboardScopedState syncShadowInputState(this, State::SyncShadowInput);
        _shadow.update(queries);
    }
}

void QVirtualKeyboardInputContextPrivate::invokeAction(QInputMethod::Action action, int cursorPosition)
{
    switch (action) {
    case QInputMethod::Click:
        if (isEmptyState()) {
            if (inputEngine->clickPreeditText(cursorPosition))
                break;

            bool reselect = !inputMethodHints.testFlag(Qt::ImhNoPredictiveText) && selectedText.isEmpty() && cursorPosition < preeditText.length();
            if (reselect) {
                QVirtualKeyboardScopedState reselectState(this, State::Reselect);
                _forceCursorPosition = this->cursorPosition + cursorPosition;
                commit();
                inputEngine->reselect(this->cursorPosition, QVirtualKeyboardInputEngine::ReselectFlag::WordBeforeCursor);
            } else if (!preeditText.isEmpty() && cursorPosition == preeditText.length()) {
                commit();
            }
        }
        clearState(State::InputMethodClick);
        break;

    case QInputMethod::ContextMenu:
        break;
    }
}

bool QVirtualKeyboardInputContextPrivate::filterEvent(const QEvent *event)
{
    QEvent::Type type = event->type();
    if (type == QEvent::KeyPress || type == QEvent::KeyRelease) {
        const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);

        // Keep track of pressed keys update key event state
        if (type == QEvent::KeyPress)
            activeKeys += keyEvent->nativeScanCode();
        else if (type == QEvent::KeyRelease)
            activeKeys -= keyEvent->nativeScanCode();

        if (activeKeys.isEmpty())
            clearState(State::KeyEvent);
        else
            setState(State::KeyEvent);

#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
        int key = keyEvent->key();
        if ((key >= Qt::Key_Left && key <= Qt::Key_Down) || key == Qt::Key_Return) {
            if (type == QEvent::KeyPress && platformInputContext->isInputPanelVisible()) {
                activeNavigationKeys += key;
                emit navigationKeyPressed(key, keyEvent->isAutoRepeat());
                return true;
            } else if (type == QEvent::KeyRelease && activeNavigationKeys.contains(key)) {
                activeNavigationKeys -= key;
                emit navigationKeyReleased(key, keyEvent->isAutoRepeat());
                return true;
            }
        }
#endif

        // Break composing text since the virtual keyboard does not support hard keyboard events
        if (!preeditText.isEmpty())
            commit();
    }
#ifdef QT_VIRTUALKEYBOARD_ARROW_KEY_NAVIGATION
    else if (type == QEvent::ShortcutOverride) {
        const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
        int key = keyEvent->key();
        if ((key >= Qt::Key_Left && key <= Qt::Key_Down) || key == Qt::Key_Return)
            return true;
    }
#endif

    return false;
}

void QVirtualKeyboardInputContextPrivate::addSelectionAttribute(QList<QInputMethodEvent::Attribute> &attributes)
{
    if (!testAttribute(attributes, QInputMethodEvent::Selection)) {
        // Convert Cursor attribute to Selection attribute.
        // In this case the cursor is set in pre-edit text, but
        // the cursor is not being forced to specific location.
        if (_forceCursorPosition == -1) {
            int cursorAttributeIndex = findAttribute(preeditTextAttributes, QInputMethodEvent::Cursor);
            if (cursorAttributeIndex != -1 && preeditTextAttributes[cursorAttributeIndex].length > 0)
                _forceCursorPosition = cursorPosition + preeditTextAttributes[cursorAttributeIndex].start;
            forceAnchorPosition = -1;
        }

        if (_forceCursorPosition != -1) {
            if (forceAnchorPosition != -1)
                attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, forceAnchorPosition, _forceCursorPosition - forceAnchorPosition, QVariant()));
            else
                attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, _forceCursorPosition, 0, QVariant()));
        }
    }
    forceAnchorPosition = -1;
    _forceCursorPosition = -1;
}

bool QVirtualKeyboardInputContextPrivate::testAttribute(const QList<QInputMethodEvent::Attribute> &attributes, QInputMethodEvent::AttributeType attributeType) const
{
    for (const QInputMethodEvent::Attribute &attribute : qAsConst(attributes)) {
        if (attribute.type == attributeType)
            return true;
    }
    return false;
}

int QVirtualKeyboardInputContextPrivate::findAttribute(const QList<QInputMethodEvent::Attribute> &attributes, QInputMethodEvent::AttributeType attributeType) const
{
    const int count = attributes.count();
    for (int i = 0; i < count; ++i) {
        if (attributes.at(i).type == attributeType)
            return i;
    }
    return -1;
}

QT_END_NAMESPACE
