/***************************************************************************
**
** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qqnxinputcontext_imf.h"
#include "qqnxabstractvirtualkeyboard.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
#include "qqnxscreeneventhandler.h"

#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethodEvent>
#include <QtGui/QTextCharFormat>

#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QVariant>
#include <QtCore/QVariantHash>
#include <QtCore/QWaitCondition>
#include <QtCore/QQueue>
#include <QtCore/QGlobalStatic>

#include <dlfcn.h>
#include "imf/imf_client.h"
#include "imf/input_control.h"
#include <process.h>
#include <sys/keycodes.h>

#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG)
#define qInputContextIMFRequestDebug qDebug
#else
#define qInputContextIMFRequestDebug QT_NO_QDEBUG_MACRO
#endif

#if defined(QQNXINPUTCONTEXT_DEBUG)
#define qInputContextDebug qDebug
#else
#define qInputContextDebug QT_NO_QDEBUG_MACRO
#endif

static QQnxInputContext *sInputContextInstance;
static QColor sSelectedColor(0,0xb8,0,85);

static const input_session_t *sSpellCheckSession = 0;
static const input_session_t *sInputSession = 0;
static bool isSessionOkay(input_session_t *ic)
{
    return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id;
}

enum ImfEventType
{
    ImfCommitText,
    ImfDeleteSurroundingText,
    ImfFinishComposingText,
    ImfGetCursorPosition,
    ImfGetTextAfterCursor,
    ImfGetTextBeforeCursor,
    ImfSendEvent,
    ImfSetComposingRegion,
    ImfSetComposingText,
    ImfIsTextSelected,
    ImfIsAllTextSelected,
};

struct SpellCheckInfo {
    SpellCheckInfo(void *_context, void (*_spellCheckDone)(void *, const QString &, const QList<int> &))
        : context(_context), spellCheckDone(_spellCheckDone) {}
    void *context;
    void (*spellCheckDone)(void *, const QString &, const QList<int> &);
};
Q_GLOBAL_STATIC(QQueue<SpellCheckInfo>, sSpellCheckQueue)

// IMF requests all arrive on IMF's own thread and have to be posted to the main thread to be processed.
class QQnxImfRequest
{
public:
    QQnxImfRequest(input_session_t *_session, ImfEventType _type)
        : session(_session), type(_type)
        { }
    ~QQnxImfRequest() { }

    input_session_t *session;
    ImfEventType type;
    union {
        struct {
            int32_t n;
            int32_t flags;
            bool before;
            spannable_string_t *result;
        } gtac; // ic_get_text_before_cursor/ic_get_text_after_cursor
        struct {
            int32_t result;
        } gcp; // ic_get_cursor_position
        struct {
            int32_t start;
            int32_t end;
            int32_t result;
        } scr; // ic_set_composing_region
        struct {
            spannable_string_t* text;
            int32_t new_cursor_position;
            int32_t result;
        } sct; // ic_set_composing_text
        struct {
            spannable_string_t* text;
            int32_t new_cursor_position;
            int32_t result;
        } ct; // ic_commit_text
        struct {
            int32_t result;
        } fct; // ic_finish_composing_text
        struct {
            int32_t left_length;
            int32_t right_length;
            int32_t result;
        } dst; // ic_delete_surrounding_text
        struct {
            event_t *event;
            int32_t result;
        } sae;  // ic_send_async_event/ic_send_event
        struct {
            int32_t *pIsSelected;
            int32_t result;
        } its;  // ic_is_text_selected/ic_is_all_text_selected
    };
};

// Invoke an IMF initiated request synchronously on Qt's main thread.  As describe below all
// IMF requests are made from another thread but need to be executed on the main thread.
static void executeIMFRequest(QQnxImfRequest *event)
{
    QMetaObject::invokeMethod(sInputContextInstance,
                              "processImfEvent",
                              Qt::BlockingQueuedConnection,
                              Q_ARG(QQnxImfRequest*, event));
}

// The following functions (ic_*) are callback functions called by the input system to query information
// about the text object that currently has focus or to make changes to it.  All calls are made from the
// input system's own thread.  The pattern for each callback function is to copy its parameters into
// a QQnxImfRequest structure and call executeIMFRequest to have it passed synchronously to Qt's main thread.
// Any return values should be pre-initialised with suitable default values as in some cases
// (e.g. a stale session) the call will return without having executed any request specific code.
//
// To make the correspondence more obvious, the names of these functions match those defined in the headers.
// They're in an anonymous namespace to avoid compiler conflicts with external functions defined with the
// same names.
namespace
{

// See comment at beginning of namespace declaration for general information
static int32_t ic_begin_batch_edit(input_session_t *ic)
{
    Q_UNUSED(ic);

    // Ignore silently.
    return 0;
}

// End composition, committing the supplied text.
// See comment at beginning of namespace declaration for general information
static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfCommitText);
    event.ct.text = text;
    event.ct.new_cursor_position = new_cursor_position;
    event.ct.result = -1;
    executeIMFRequest(&event);

    return event.ct.result;
}

// Delete left_length characters before and right_length characters after the cursor.
// See comment at beginning of namespace declaration for general information
static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfDeleteSurroundingText);
    event.dst.left_length = left_length;
    event.dst.right_length = right_length;
    event.dst.result = -1;
    executeIMFRequest(&event);

    return event.dst.result;
}

// See comment at beginning of namespace declaration for general information
static int32_t ic_end_batch_edit(input_session_t *ic)
{
    Q_UNUSED(ic);

    // Ignore silently.
    return 0;
}

// End composition, committing what's there.
// See comment at beginning of namespace declaration for general information
static int32_t ic_finish_composing_text(input_session_t *ic)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfFinishComposingText);
    event.fct.result = -1;
    executeIMFRequest(&event);

    return event.fct.result;
}

// Return the position of the cursor.
// See comment at beginning of namespace declaration for general information
static int32_t ic_get_cursor_position(input_session_t *ic)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfGetCursorPosition);
    event.gcp.result = -1;
    executeIMFRequest(&event);

    return event.gcp.result;
}

// Return the n characters after the cursor.
// See comment at beginning of namespace declaration for general information
static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfGetTextAfterCursor);
    event.gtac.n = n;
    event.gtac.flags = flags;
    event.gtac.result = 0;
    executeIMFRequest(&event);

    return event.gtac.result;
}

// Return the n characters before the cursor.
// See comment at beginning of namespace declaration for general information
static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfGetTextBeforeCursor);
    event.gtac.n = n;
    event.gtac.flags = flags;
    event.gtac.result = 0;
    executeIMFRequest(&event);

    return event.gtac.result;
}

// Process an event from IMF.  Primarily used for reflecting back keyboard events.
// See comment at beginning of namespace declaration for general information
static int32_t ic_send_event(input_session_t *ic, event_t *event)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest imfEvent(ic, ImfSendEvent);
    imfEvent.sae.event = event;
    imfEvent.sae.result = -1;
    executeIMFRequest(&imfEvent);

    return imfEvent.sae.result;
}

// Same as ic_send_event.
// See comment at beginning of namespace declaration for general information
static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
{
    qInputContextIMFRequestDebug();

    // There's no difference from our point of view between ic_send_event & ic_send_async_event
    QQnxImfRequest imfEvent(ic, ImfSendEvent);
    imfEvent.sae.event = event;
    imfEvent.sae.result = -1;
    executeIMFRequest(&imfEvent);

    return imfEvent.sae.result;
}

// Set the range of text between start and end as the composition range.
// See comment at beginning of namespace declaration for general information
static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfSetComposingRegion);
    event.scr.start = start;
    event.scr.end = end;
    event.scr.result = -1;
    executeIMFRequest(&event);

    return event.scr.result;
}

// Update the composition range with the supplied text.  This can be called when no composition
// range is in effect in which case one is started at the current cursor position.
// See comment at beginning of namespace declaration for general information
static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfSetComposingText);
    event.sct.text = text;
    event.sct.new_cursor_position = new_cursor_position;
    event.sct.result = -1;
    executeIMFRequest(&event);

    return event.sct.result;
}

// Indicate if any text is selected
// See comment at beginning of namespace declaration for general information
static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfIsTextSelected);
    event.its.pIsSelected = pIsSelected;
    event.its.result = -1;
    executeIMFRequest(&event);

    return event.its.result;
}

// Indicate if all text is selected
// See comment at beginning of namespace declaration for general information
static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
    qInputContextIMFRequestDebug();

    QQnxImfRequest event(ic, ImfIsAllTextSelected);
    event.its.pIsSelected = pIsSelected;
    event.its.result = -1;
    executeIMFRequest(&event);

    return event.its.result;
}

// LCOV_EXCL_START - exclude from code coverage analysis
// The following functions are defined in the IMF headers but are not currently called.

// Not currently used
static int32_t ic_perform_editor_action(input_session_t *ic, int32_t editor_action)
{
    Q_UNUSED(ic);
    Q_UNUSED(editor_action);

    qCritical("ic_perform_editor_action not implemented");
    return 0;
}

// Not currently used
static int32_t ic_report_fullscreen_mode(input_session_t *ic, int32_t enabled)
{
    Q_UNUSED(ic);
    Q_UNUSED(enabled);

    qCritical("ic_report_fullscreen_mode not implemented");
    return 0;
}

// Not currently used
static extracted_text_t *ic_get_extracted_text(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
{
    Q_UNUSED(ic);
    Q_UNUSED(request);
    Q_UNUSED(flags);

    qCritical("ic_get_extracted_text not implemented");
    return 0;
}

// Not currently used
static spannable_string_t *ic_get_selected_text(input_session_t *ic, int32_t flags)
{
    Q_UNUSED(ic);
    Q_UNUSED(flags);

    qCritical("ic_get_selected_text not implemented");
    return 0;
}

// Not currently used
static int32_t ic_get_cursor_caps_mode(input_session_t *ic, int32_t req_modes)
{
    Q_UNUSED(ic);
    Q_UNUSED(req_modes);

    qCritical("ic_get_cursor_caps_mode not implemented");
    return 0;
}

// Not currently used
static int32_t ic_clear_meta_key_states(input_session_t *ic, int32_t states)
{
    Q_UNUSED(ic);
    Q_UNUSED(states);

    qCritical("ic_clear_meta_key_states not implemented");
    return 0;
}

// Not currently used
static int32_t ic_set_selection(input_session_t *ic, int32_t start, int32_t end)
{
    Q_UNUSED(ic);
    Q_UNUSED(start);
    Q_UNUSED(end);

    qCritical("ic_set_selection not implemented");
    return 0;
}

// End of un-hittable code
// LCOV_EXCL_STOP


static connection_interface_t ic_funcs = {
    ic_begin_batch_edit,
    ic_clear_meta_key_states,
    ic_commit_text,
    ic_delete_surrounding_text,
    ic_end_batch_edit,
    ic_finish_composing_text,
    ic_get_cursor_caps_mode,
    ic_get_cursor_position,
    ic_get_extracted_text,
    ic_get_selected_text,
    ic_get_text_after_cursor,
    ic_get_text_before_cursor,
    ic_perform_editor_action,
    ic_report_fullscreen_mode,
    0, //ic_send_key_event
    ic_send_event,
    ic_send_async_event,
    ic_set_composing_region,
    ic_set_composing_text,
    ic_set_selection,
    0, //ic_set_candidates,
    0, //ic_get_cursor_offset,
    0, //ic_get_selection,
    ic_is_text_selected,
    ic_is_all_text_selected,
    0, //ic_get_max_cursor_offset_t
};

} // namespace

static void
initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId, int eventSize)
{
    static int s_transactionId;

    // Make sure structure is squeaky clean since it's not clear just what is significant.
    memset(pEvent, 0, eventSize);
    pEvent->event_type = eventType;
    pEvent->event_id = eventId;
    pEvent->pid = getpid();
    pEvent->component_id = pSession->component_id;
    pEvent->transaction_id = ++s_transactionId;
}

static spannable_string_t *toSpannableString(const QString &text)
{
    qInputContextDebug() << text;

    spannable_string_t *pString = static_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
    pString->str =  static_cast<wchar_t *>(malloc(sizeof(wchar_t) * text.length() + 1));
    pString->length = text.toWCharArray(pString->str);
    pString->spans = 0;
    pString->spans_count = 0;
    pString->str[pString->length] = 0;

    return pString;
}


static const input_session_t *(*p_ictrl_open_session)(connection_interface_t *) = 0;
static void (*p_ictrl_close_session)(input_session_t *) = 0;
static int32_t (*p_ictrl_dispatch_event)(event_t*) = 0;
static int32_t (*p_imf_client_init)() = 0;
static void (*p_imf_client_disconnect)() = 0;
static int32_t (*p_vkb_init_selection_service)() = 0;
static int32_t (*p_ictrl_get_num_active_sessions)() = 0;
static bool s_imfInitFailed = false;

static bool imfAvailable()
{
    static bool s_imfDisabled = getenv("DISABLE_IMF") != 0;
    static bool s_imfReady = false;

    if ( s_imfInitFailed || s_imfDisabled)
        return false;
    else if ( s_imfReady )
        return true;

    if ( p_imf_client_init == 0 ) {
        void *handle = dlopen("libinput_client.so.1", 0);
        if (Q_UNLIKELY(!handle)) {
            qCritical("libinput_client.so.1 is not present - IMF services are disabled.");
            s_imfDisabled = true;
            return false;
        }
        p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init");
        p_imf_client_disconnect = (void (*)()) dlsym(handle, "imf_client_disconnect");
        p_ictrl_open_session = (const input_session_t *(*)(connection_interface_t *))dlsym(handle, "ictrl_open_session");
        p_ictrl_close_session = (void (*)(input_session_t *))dlsym(handle, "ictrl_close_session");
        p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle, "ictrl_dispatch_event");
        p_vkb_init_selection_service = (int32_t (*)())dlsym(handle, "vkb_init_selection_service");
        p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle, "ictrl_get_num_active_sessions");

        if (Q_UNLIKELY(!p_imf_client_init || !p_ictrl_open_session || !p_ictrl_dispatch_event)) {
            p_ictrl_open_session = 0;
            p_ictrl_dispatch_event = 0;
            s_imfDisabled = true;
            qCritical("libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled.");
            return false;
        }

        s_imfReady = true;
    }

    return s_imfReady;
}

QT_BEGIN_NAMESPACE

QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
         QPlatformInputContext(),
         m_caretPosition(0),
         m_isComposing(false),
         m_isUpdatingText(false),
         m_inputPanelVisible(false),
         m_inputPanelLocale(QLocale::c()),
         m_focusObject(0),
         m_integration(integration),
         m_virtualKeyboard(keyboard)
{
    qInputContextDebug();

    if (!imfAvailable())
        return;

    // Save a pointer to ourselves so we can execute calls from IMF through executeIMFRequest
    // In practice there will only ever be a single instance.
    Q_ASSERT(sInputContextInstance == 0);
    sInputContextInstance = this;

    if (Q_UNLIKELY(p_imf_client_init() != 0)) {
        s_imfInitFailed = true;
        qCritical("imf_client_init failed - IMF services will be unavailable");
    }

    connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool)));
    connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale)));
    keyboardVisibilityChanged(keyboard.isVisible());
    keyboardLocaleChanged(keyboard.locale());
}

QQnxInputContext::~QQnxInputContext()
{
    qInputContextDebug();

    Q_ASSERT(sInputContextInstance == this);
    sInputContextInstance = 0;

    if (!imfAvailable())
        return;

    p_imf_client_disconnect();
}

bool QQnxInputContext::isValid() const
{
    return imfAvailable();
}

void QQnxInputContext::processImfEvent(QQnxImfRequest *imfEvent)
{
    // If input session is no longer current, just bail, imfEvent should already be set with the appropriate
    // return value.  The only exception is spell check events since they're not associated with the
    // object with focus.
    if (imfEvent->type != ImfSendEvent || imfEvent->sae.event->event_type != EVENT_SPELL_CHECK) {
        if (!isSessionOkay(imfEvent->session))
            return;
    }

    switch (imfEvent->type) {
    case ImfCommitText:
        imfEvent->ct.result = onCommitText(imfEvent->ct.text, imfEvent->ct.new_cursor_position);
        break;

    case ImfDeleteSurroundingText:
        imfEvent->dst.result = onDeleteSurroundingText(imfEvent->dst.left_length, imfEvent->dst.right_length);
        break;

    case ImfFinishComposingText:
        imfEvent->fct.result = onFinishComposingText();
        break;

    case ImfGetCursorPosition:
        imfEvent->gcp.result = onGetCursorPosition();
        break;

    case ImfGetTextAfterCursor:
        imfEvent->gtac.result = onGetTextAfterCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
        break;

    case ImfGetTextBeforeCursor:
        imfEvent->gtac.result = onGetTextBeforeCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
        break;

    case ImfSendEvent:
        imfEvent->sae.result = onSendEvent(imfEvent->sae.event);
        break;

    case ImfSetComposingRegion:
        imfEvent->scr.result = onSetComposingRegion(imfEvent->scr.start, imfEvent->scr.end);
        break;

    case ImfSetComposingText:
        imfEvent->sct.result = onSetComposingText(imfEvent->sct.text, imfEvent->sct.new_cursor_position);
        break;

    case ImfIsTextSelected:
        imfEvent->its.result = onIsTextSelected(imfEvent->its.pIsSelected);
        break;

    case ImfIsAllTextSelected:
        imfEvent->its.result = onIsAllTextSelected(imfEvent->its.pIsSelected);
        break;
    }; //switch
}

bool QQnxInputContext::filterEvent( const QEvent *event )
{
    qInputContextDebug() << event;

    switch (event->type()) {
    case QEvent::CloseSoftwareInputPanel:
        return dispatchCloseSoftwareInputPanel();

    case QEvent::RequestSoftwareInputPanel:
        return dispatchRequestSoftwareInputPanel();

    default:
        return false;
    }
}

QRectF QQnxInputContext::keyboardRect() const
{
    QRect screenGeometry = m_integration->primaryDisplay()->geometry();
    return QRectF(screenGeometry.x(), screenGeometry.height() - m_virtualKeyboard.height(),
                  screenGeometry.width(), m_virtualKeyboard.height());
}

void QQnxInputContext::reset()
{
    qInputContextDebug();
    endComposition();
}

void QQnxInputContext::commit()
{
    qInputContextDebug();
    endComposition();
}

void QQnxInputContext::update(Qt::InputMethodQueries queries)
{
    qInputContextDebug() << queries;

    if (queries & Qt::ImCursorPosition) {
        int lastCaret = m_caretPosition;
        updateCursorPosition();
        // If caret position has changed we need to inform IMF unless this is just due to our own action
        // such as committing text.
        if (hasSession() && !m_isUpdatingText && lastCaret != m_caretPosition) {
            caret_event_t caretEvent;
            initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED, sizeof(caretEvent));
            caretEvent.old_pos = lastCaret;
            caretEvent.new_pos = m_caretPosition;
            qInputContextDebug("ictrl_dispatch_event caret changed %d %d", lastCaret, m_caretPosition);
            p_ictrl_dispatch_event(&caretEvent.event);
        }
    }
}

void QQnxInputContext::closeSession()
{
    qInputContextDebug();
    if (!imfAvailable())
        return;

    if (sInputSession) {
        p_ictrl_close_session((input_session_t *)sInputSession);
        sInputSession = 0;
    }
    // These are likely already in the right state but this depends on the text control
    // having called reset or commit.  So, just in case, set them to proper values.
    m_isComposing = false;
    m_composingText.clear();
}

bool QQnxInputContext::openSession()
{
    if (!imfAvailable())
        return false;

    closeSession();
    sInputSession = p_ictrl_open_session(&ic_funcs);

    qInputContextDebug();

    return sInputSession != 0;
}

bool QQnxInputContext::hasSession()
{
    return sInputSession != 0;
}

bool QQnxInputContext::hasSelectedText()
{
    QObject *input = qGuiApp->focusObject();
    if (!input)
        return false;

    QInputMethodQueryEvent query(Qt::ImCurrentSelection);
    QCoreApplication::sendEvent(input, &query);

    return !query.value(Qt::ImCurrentSelection).toString().isEmpty();
}

bool QQnxInputContext::dispatchRequestSoftwareInputPanel()
{
    qInputContextDebug() << "requesting keyboard" << m_inputPanelVisible;
    m_virtualKeyboard.showKeyboard();

    return true;
}

bool QQnxInputContext::dispatchCloseSoftwareInputPanel()
{
    qInputContextDebug() << "hiding keyboard" << m_inputPanelVisible;
    m_virtualKeyboard.hideKeyboard();

    return true;
}

/**
 * IMF Event Dispatchers.
 */
bool QQnxInputContext::dispatchFocusGainEvent(int inputHints)
{
    if (hasSession())
        dispatchFocusLossEvent();

    QObject *input = qGuiApp->focusObject();

    if (!input || !openSession())
        return false;

    // Set the last caret position to 0 since we don't really have one and we don't
    // want to have the old one.
    m_caretPosition = 0;

    QInputMethodQueryEvent query(Qt::ImHints);
    QCoreApplication::sendEvent(input, &query);

    focus_event_t focusEvent;
    initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_GAINED, sizeof(focusEvent));
    focusEvent.style = DEFAULT_STYLE;

    if (inputHints & Qt::ImhNoPredictiveText)
        focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION;
    if (inputHints & Qt::ImhNoAutoUppercase)
        focusEvent.style |= NO_AUTO_TEXT;

    // Following styles are mutually exclusive
    if (inputHints & Qt::ImhHiddenText) {
        focusEvent.style |= IMF_PASSWORD_TYPE;
    } else if (inputHints & Qt::ImhDialableCharactersOnly) {
        focusEvent.style |= IMF_PHONE_TYPE;
    } else if (inputHints & Qt::ImhUrlCharactersOnly) {
        focusEvent.style |= IMF_URL_TYPE;
    } else if (inputHints & Qt::ImhEmailCharactersOnly) {
        focusEvent.style |= IMF_EMAIL_TYPE;
    }

    qInputContextDebug() << "ictrl_dispatch_event focus gain style:" << focusEvent.style;

    p_ictrl_dispatch_event((event_t *)&focusEvent);

    return true;
}

void QQnxInputContext::dispatchFocusLossEvent()
{
    if (hasSession()) {
        qInputContextDebug("ictrl_dispatch_event focus lost");

        focus_event_t focusEvent;
        initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST, sizeof(focusEvent));
        p_ictrl_dispatch_event((event_t *)&focusEvent);
        closeSession();
    }
}

bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId)
{
    Q_UNUSED(scan);

    if (!hasSession())
        return false;

    int key = (flags & KEY_SYM_VALID) ? sym : cap;
    bool navigationKey = false;
    switch (key) {
    case KEYCODE_RETURN:
         /* In a single line edit we should end composition because enter might be used by something.
            endComposition();
            return false;*/
        break;

    case KEYCODE_BACKSPACE:
    case KEYCODE_DELETE:
        // If there is a selection range, then we want a delete key to operate on that (by
        // deleting the contents of the select range) rather than operating on the composition
        // range.
        if (hasSelectedText())
            return false;
        break;
    case  KEYCODE_LEFT:
        key = NAVIGATE_LEFT;
        navigationKey = true;
        break;
    case  KEYCODE_RIGHT:
        key = NAVIGATE_RIGHT;
        navigationKey = true;
        break;
    case  KEYCODE_UP:
        key = NAVIGATE_UP;
        navigationKey = true;
        break;
    case  KEYCODE_DOWN:
        key = NAVIGATE_DOWN;
        navigationKey = true;
        break;
    case  KEYCODE_LEFT_CTRL:
    case  KEYCODE_RIGHT_CTRL:
    case  KEYCODE_MENU:
    case  KEYCODE_LEFT_HYPER:
    case  KEYCODE_RIGHT_HYPER:
    case  KEYCODE_INSERT:
    case  KEYCODE_HOME:
    case  KEYCODE_PG_UP:
    case  KEYCODE_END:
    case  KEYCODE_PG_DOWN:
        // Don't send these
        key = 0;
        break;
    }

    // Pass the keys we don't know about on through
    if ( key == 0 )
        return false;

    if (navigationKey) {
        // Even if we're forwarding up events, we can't do this for
        // navigation keys.
        if ( flags & KEY_DOWN ) {
            navigation_event_t navEvent;
            initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key, sizeof(navEvent));
            navEvent.magnitude = 1;
            qInputContextDebug("ictrl_dispatch_even navigation %d", key);
            p_ictrl_dispatch_event(&navEvent.event);
        }
    } else {
        key_event_t keyEvent;
        initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP,
                  sizeof(keyEvent));
        keyEvent.key_code = cap;
        keyEvent.character = sym;
        keyEvent.meta_key_state = mod;
        keyEvent.sequence_id = sequenceId;

        p_ictrl_dispatch_event(&keyEvent.event);
        qInputContextDebug("ictrl_dispatch_even key %d", key);
    }

    return true;
}

void QQnxInputContext::updateCursorPosition()
{
    QObject *input = qGuiApp->focusObject();
    if (!input)
        return;

    QInputMethodQueryEvent query(Qt::ImCursorPosition);
    QCoreApplication::sendEvent(input, &query);
    m_caretPosition = query.value(Qt::ImCursorPosition).toInt();

    qInputContextDebug("%d", m_caretPosition);
}

void QQnxInputContext::endComposition()
{
    if (!m_isComposing)
        return;

    finishComposingText();

    if (hasSession()) {
        action_event_t actionEvent;
        initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION, sizeof(actionEvent));
        qInputContextDebug("ictrl_dispatch_even end composition");
        p_ictrl_dispatch_event(&actionEvent.event);
    }
}

void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_cursor_position)
{
   QObject *input = qGuiApp->focusObject();
   if (!input)
       return;

   if (new_cursor_position > 0)
       new_cursor_position += text->length - 1;

    m_composingText = QString::fromWCharArray(text->str, text->length);
    m_isComposing = true;

    qInputContextDebug() << m_composingText << new_cursor_position;

    QList<QInputMethodEvent::Attribute> attributes;
    attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
                                                   new_cursor_position,
                                                   1,
                                                   QVariant()));

    for (unsigned int i = 0; i < text->spans_count; ++i) {
        QColor highlightColor;
        bool underline = false;

        if ((text->spans[i].attributes_mask & COMPOSED_TEXT_ATTRIB) != 0)
            underline = true;

        if ((text->spans[i].attributes_mask & ACTIVE_REGION_ATTRIB) != 0) {
            underline = true;
            highlightColor = m_highlightColor[ActiveRegion];
        } else if ((text->spans[i].attributes_mask & AUTO_CORRECTION_ATTRIB) != 0) {
            highlightColor = m_highlightColor[AutoCorrected];
        } else if ((text->spans[i].attributes_mask & REVERT_CORRECTION_ATTRIB) != 0) {
            highlightColor = m_highlightColor[Reverted];
        }

        if (underline || highlightColor.isValid()) {
            QTextCharFormat format;
            if (underline)
                format.setFontUnderline(true);
            if (highlightColor.isValid())
                format.setBackground(QBrush(highlightColor));
            qInputContextDebug() << "    attrib:  " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
            attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
                                                           text->spans[i].end - text->spans[i].start + 1, QVariant(format)));

        }
    }
    QInputMethodEvent event(m_composingText, attributes);
    m_isUpdatingText = true;
    QCoreApplication::sendEvent(input, &event);
    m_isUpdatingText = false;

    updateCursorPosition();
}

void QQnxInputContext::finishComposingText()
{
    QObject *input = qGuiApp->focusObject();

    if (input) {
        qInputContextDebug() << m_composingText;

        QInputMethodEvent event;
        event.setCommitString(m_composingText);
        m_isUpdatingText = true;
        QCoreApplication::sendEvent(input, &event);
        m_isUpdatingText = false;
    }
    m_composingText = QString();
    m_isComposing = false;

    updateCursorPosition();
}

// Return the index relative to a UTF-16 sequence of characters for a index that is relative to the
// corresponding UTF-32 character string given a starting index in the UTF-16 string and a count
// of the number of lead surrogates prior to that index.  Updates the highSurrogateCount to reflect the
// new surrogate characters encountered.
static int adjustIndex(const QChar *text, int utf32Index, int utf16StartIndex, int *highSurrogateCount)
{
    int utf16Index = utf32Index + *highSurrogateCount;
    while (utf16StartIndex <  utf16Index) {
        if (text[utf16StartIndex].isHighSurrogate()) {
            ++utf16Index;
            ++*highSurrogateCount;
        }
        ++utf16StartIndex;
    }
    return utf16StartIndex;
}

int QQnxInputContext::handleSpellCheck(spell_check_event_t *event)
{
    // These should never happen.
    if (sSpellCheckQueue->isEmpty() || event->event.event_id != NOTIFY_SP_CHECK_MISSPELLINGS)
        return -1;

    SpellCheckInfo callerInfo = sSpellCheckQueue->dequeue();
    spannable_string_t* spellCheckData = *event->data;
    QString text = QString::fromWCharArray(spellCheckData->str, spellCheckData->length);
    // Generate the list of indices indicating misspelled words in the text.  We use end + 1
    // since it's more conventional to have the end index point just past the string.  We also
    // can't use the indices directly since they are relative to UTF-32 encoded data and the
    // conversion to Qt's UTF-16 internal format might cause lengthening.
    QList<int> indices;
    int adjustment = 0;
    int index = 0;
    for (unsigned int i = 0; i < spellCheckData->spans_count; ++i) {
        if (spellCheckData->spans[i].attributes_mask & MISSPELLED_WORD_ATTRIB) {
            index = adjustIndex(text.data(), spellCheckData->spans[i].start, index, &adjustment);
            indices.push_back(index);
            index = adjustIndex(text.data(), spellCheckData->spans[i].end + 1, index, &adjustment);
            indices.push_back(index);
        }
    }
    callerInfo.spellCheckDone(callerInfo.context, text, indices);

    return 0;
}

int32_t QQnxInputContext::processEvent(event_t *event)
{
    int32_t result = -1;
    switch (event->event_type) {
    case EVENT_SPELL_CHECK: {
        qInputContextDebug("EVENT_SPELL_CHECK");
        result = handleSpellCheck(reinterpret_cast<spell_check_event_t *>(event));
        break;
    }

    case EVENT_NAVIGATION: {
        qInputContextDebug("EVENT_NAVIGATION");

        int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP :
            event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN :
            event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT :
            event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0;

        QQnxScreenEventHandler::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
        QQnxScreenEventHandler::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
        result = 0;
        break;
    }

    case EVENT_KEY: {
        key_event_t *kevent = reinterpret_cast<key_event_t *>(event);
        int keySym = kevent->character != 0 ? kevent->character : kevent->key_code;
        int keyCap = kevent->key_code;
        int modifiers = 0;
        if (kevent->meta_key_state & META_SHIFT_ON)
            modifiers |= KEYMOD_SHIFT;
        int flags = KEY_SYM_VALID | KEY_CAP_VALID;
        if (event->event_id == IMF_KEY_DOWN)
            flags |= KEY_DOWN;
        qInputContextDebug("EVENT_KEY %d %d", flags, keySym);
        QQnxScreenEventHandler::injectKeyboardEvent(flags, keySym, modifiers, 0, keyCap);
        result = 0;
        break;
    }

    case EVENT_ACTION:
            // Don't care, indicates that IMF is done.
        break;

    case EVENT_CARET:
    case EVENT_NOTHING:
    case EVENT_FOCUS:
    case EVENT_USER_ACTION:
    case EVENT_STROKE:
    case EVENT_INVOKE_LATER:
        qCritical() << "Unsupported event type: " << event->event_type;
        break;
    default:
        qCritical() << "Unknown event type: " << event->event_type;
    }
    return result;
}

/**
 * IMF Event Handlers
 */

int32_t QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cursor_position)
{
    Q_UNUSED(new_cursor_position);

    updateComposition(text, new_cursor_position);
    finishComposingText();

    return 0;
}

int32_t QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
{
    qInputContextDebug("L: %d R: %d", int(left_length), int(right_length));

    QObject *input = qGuiApp->focusObject();
    if (!input)
        return 0;

    int replacementLength = left_length + right_length;
    int replacementStart = -left_length;

    finishComposingText();

    QInputMethodEvent event;
    event.setCommitString(QString(), replacementStart, replacementLength);
    m_isUpdatingText = true;
    QCoreApplication::sendEvent(input, &event);
    m_isUpdatingText = false;

    updateCursorPosition();

    return 0;
}

int32_t QQnxInputContext::onFinishComposingText()
{
    finishComposingText();

    return 0;
}

int32_t QQnxInputContext::onGetCursorPosition()
{
    qInputContextDebug();

    QObject *input = qGuiApp->focusObject();
    if (!input)
        return 0;

    updateCursorPosition();

    return m_caretPosition;
}

spannable_string_t *QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
{
    Q_UNUSED(flags);
    qInputContextDebug();

    QObject *input = qGuiApp->focusObject();
    if (!input)
        return toSpannableString("");

    QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
    QCoreApplication::sendEvent(input, &query);
    QString text = query.value(Qt::ImSurroundingText).toString();
    m_caretPosition = query.value(Qt::ImCursorPosition).toInt();

    return toSpannableString(text.mid(m_caretPosition, n));
}

spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
{
    Q_UNUSED(flags);
    qInputContextDebug();

    QObject *input = qGuiApp->focusObject();
    if (!input)
        return toSpannableString("");

    QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
    QCoreApplication::sendEvent(input, &query);
    QString text = query.value(Qt::ImSurroundingText).toString();
    m_caretPosition = query.value(Qt::ImCursorPosition).toInt();

    if (n < m_caretPosition)
        return toSpannableString(text.mid(m_caretPosition - n, n));
    else
        return toSpannableString(text.mid(0, m_caretPosition));
}

int32_t QQnxInputContext::onSendEvent(event_t *event)
{
    qInputContextDebug();

    return processEvent(event);
}

int32_t QQnxInputContext::onSetComposingRegion(int32_t start, int32_t end)
{
    QObject *input = qGuiApp->focusObject();
    if (!input)
        return 0;

    QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
    QCoreApplication::sendEvent(input, &query);
    QString text = query.value(Qt::ImSurroundingText).toString();
    m_caretPosition = query.value(Qt::ImCursorPosition).toInt();

    qInputContextDebug() << text;

    m_isUpdatingText = true;

    // Delete the current text.
    QInputMethodEvent deleteEvent;
    deleteEvent.setCommitString(QString(), start - m_caretPosition, end - start);
    QCoreApplication::sendEvent(input, &deleteEvent);

    m_composingText = text.mid(start, end - start);
    m_isComposing = true;

    QList<QInputMethodEvent::Attribute> attributes;
    QTextCharFormat format;
    format.setFontUnderline(true);
    attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, m_composingText.length(), format));

    QInputMethodEvent setTextEvent(m_composingText, attributes);
    QCoreApplication::sendEvent(input, &setTextEvent);

    m_isUpdatingText = false;

    return 0;
}

int32_t QQnxInputContext::onSetComposingText(spannable_string_t *text, int32_t new_cursor_position)
{
    if (text->length > 0) {
        updateComposition(text, new_cursor_position);
    } else {
        // If the composing text is empty we can simply end composition, the visual effect is the same.
        // However, sometimes one wants to display hint text in an empty text field and for this to work
        // QQuickTextEdit.inputMethodComposing has to be false if the composition string is empty.
        m_composingText.clear();
        finishComposingText();
    }
    return 0;
}

int32_t QQnxInputContext::onIsTextSelected(int32_t* pIsSelected)
{
    *pIsSelected = hasSelectedText();

    qInputContextDebug() << *pIsSelected;

    return 0;
}

int32_t QQnxInputContext::onIsAllTextSelected(int32_t* pIsSelected)
{
    QObject *input = qGuiApp->focusObject();
    if (!input)
        return -1;

    QInputMethodQueryEvent query(Qt::ImCurrentSelection | Qt::ImSurroundingText);
    QCoreApplication::sendEvent(input, &query);

    *pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();

    qInputContextDebug() << *pIsSelected;

    return 0;
}

void QQnxInputContext::showInputPanel()
{
    qInputContextDebug();
    dispatchRequestSoftwareInputPanel();
}

void QQnxInputContext::hideInputPanel()
{
    qInputContextDebug();
    dispatchCloseSoftwareInputPanel();
}

bool QQnxInputContext::isInputPanelVisible() const
{
    return m_inputPanelVisible;
}

QLocale QQnxInputContext::locale() const
{
    return m_inputPanelLocale;
}

void QQnxInputContext::keyboardVisibilityChanged(bool visible)
{
    qInputContextDebug() << "visible=" << visible;
    if (m_inputPanelVisible != visible) {
        m_inputPanelVisible = visible;
        emitInputPanelVisibleChanged();
    }
}

void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
{
    qInputContextDebug() << "locale=" << locale;
    if (m_inputPanelLocale != locale) {
        m_inputPanelLocale = locale;
        emitLocaleChanged();
    }
}

void QQnxInputContext::setHighlightColor(int index, const QColor &color)
{
    qInputContextDebug() << "setHighlightColor" << index << color << qGuiApp->focusObject();

    if (!sInputContextInstance)
        return;

    // If the focus has changed, revert all colors to the default.
    if (sInputContextInstance->m_focusObject != qGuiApp->focusObject()) {
        QColor invalidColor;
        sInputContextInstance->m_highlightColor[ActiveRegion] = sSelectedColor;
        sInputContextInstance->m_highlightColor[AutoCorrected] = invalidColor;
        sInputContextInstance->m_highlightColor[Reverted] = invalidColor;
        sInputContextInstance->m_focusObject = qGuiApp->focusObject();
    }
    if (index >= 0 && index <= Reverted)
        sInputContextInstance->m_highlightColor[index] = color;
}

void QQnxInputContext::setFocusObject(QObject *object)
{
    qInputContextDebug() << "input item=" << object;

    // Ensure the colors are reset if we've a change in focus object
    setHighlightColor(-1, QColor());

    if (!inputMethodAccepted()) {
        if (m_inputPanelVisible)
            hideInputPanel();
        if (hasSession())
            dispatchFocusLossEvent();
    } else {
        QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType);
        QCoreApplication::sendEvent(object, &query);
        int inputHints = query.value(Qt::ImHints).toInt();
        Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt());

        dispatchFocusGainEvent(inputHints);

        m_virtualKeyboard.setInputHints(inputHints);
        m_virtualKeyboard.setEnterKeyType(
            QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType)
        );

        if (!m_inputPanelVisible)
            showInputPanel();
    }
}

bool QQnxInputContext::checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices))
{
    qInputContextDebug() << "text" << text;

    if (!imfAvailable())
        return false;

    if (!sSpellCheckSession)
        sSpellCheckSession = p_ictrl_open_session(&ic_funcs);

    action_event_t spellEvent;
    initEvent(&spellEvent.event, sSpellCheckSession, EVENT_ACTION, ACTION_CHECK_MISSPELLINGS, sizeof(spellEvent));
    int len = text.length();
    spellEvent.event_data = alloca(sizeof(wchar_t) * (len + 1));
    spellEvent.length_data = text.toWCharArray(static_cast<wchar_t*>(spellEvent.event_data)) * sizeof(wchar_t);

    int rc = p_ictrl_dispatch_event(reinterpret_cast<event_t*>(&spellEvent));

    if (rc == 0) {
        sSpellCheckQueue->enqueue(SpellCheckInfo(context, spellCheckDone));
        return true;
    }
    return false;
}

QT_END_NAMESPACE
