/****************************************************************************
**
** 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$
**
****************************************************************************/

import QtQuick 2.0
// Deliberately imported after QtQuick to avoid missing restoreMode property in Binding. Fix in Qt 6.
import QtQml 2.14
import QtQuick.Layouts 1.0
import QtQuick.Window 2.2
import QtQuick.VirtualKeyboard 2.3
import QtQuick.VirtualKeyboard.Styles 2.1
import QtQuick.VirtualKeyboard.Settings 2.2
import QtQuick.VirtualKeyboard.Plugins 2.3
import Qt.labs.folderlistmodel 2.0

Item {
    id: keyboard
    objectName: "keyboard"

    property alias style: styleLoader.item
    property alias wordCandidateView: wordCandidateView
    property alias shadowInputControl: shadowInputControl
    property var activeKey: null
    property TouchPoint activeTouchPoint
    property int localeIndex: -1
    property var availableLocaleIndices: []
    property var availableCustomLocaleIndices: []
    property string locale: localeIndex >= 0 && localeIndex < layoutsModel.count ? layoutsModel.get(localeIndex, "fileName") : ""
    property string inputLocale
    property int defaultLocaleIndex: -1
    readonly property bool latinOnly: InputContext.inputMethodHints & (Qt.ImhLatinOnly | Qt.ImhEmailCharactersOnly | Qt.ImhUrlCharactersOnly)
    readonly property bool preferNumbers: InputContext.inputMethodHints & Qt.ImhPreferNumbers
    readonly property bool dialableCharactersOnly: InputContext.inputMethodHints & Qt.ImhDialableCharactersOnly
    readonly property bool formattedNumbersOnly: InputContext.inputMethodHints & Qt.ImhFormattedNumbersOnly
    readonly property bool digitsOnly: InputContext.inputMethodHints & Qt.ImhDigitsOnly
    property string layout
    property string layoutType: {
        if (keyboard.handwritingMode) return "handwriting"
        if (keyboard.dialableCharactersOnly) return "dialpad"
        if (keyboard.formattedNumbersOnly) return "numbers"
        if (keyboard.digitsOnly) return "digits"
        if (keyboard.symbolMode) return "symbols"
        return "main"
    }
    property bool active: Qt.inputMethod.visible
    property bool handwritingMode
    property bool fullScreenHandwritingMode
    property bool symbolMode
    property bool fullScreenMode: VirtualKeyboardSettings.fullScreenMode
    property var defaultInputMethod: initDefaultInputMethod()
    property var plainInputMethod: PlainInputMethod {}
    property var customInputMethod: null
    property var customInputMethodSharedLayouts: []
    property int defaultInputMode: InputEngine.InputMode.Latin
    property bool inputMethodNeedsReset: true
    property bool inputModeNeedsReset: true
    property bool navigationModeActive: false
    readonly property bool languagePopupListActive: languagePopupList.enabled
    property alias soundEffect: soundEffect

    function initDefaultInputMethod() {
        try {
            return Qt.createQmlObject('import QtQuick 2.0; import QtQuick.VirtualKeyboard.Plugins 2.3; DefaultInputMethod {}', keyboard, "defaultInputMethod")
        } catch (e) { }
        return plainInputMethod
    }

    width: keyboardBackground.width
    height: keyboardBackground.height + (VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? wordCandidateView.height : 0)
    onActiveChanged: {
        hideLanguagePopup()
        if (active && symbolMode && !preferNumbers)
            symbolMode = false
        keyboardInputArea.reset()
        wordCandidateViewAutoHideTimer.stop()
    }
    onActiveKeyChanged: {
        if (InputContext.inputEngine.activeKey !== Qt.Key_unknown)
            InputContext.inputEngine.virtualKeyCancel()
    }
    Connections {
        target: VirtualKeyboardSettings
        onLocaleChanged: {
            updateDefaultLocale()
            localeIndex = defaultLocaleIndex
        }
        onActiveLocalesChanged: {
            updateDefaultLocale()
            if (!isValidLocale(localeIndex) || VirtualKeyboardSettings.locale)
                localeIndex = defaultLocaleIndex
        }
        onFullScreenModeChanged: {
            wordCandidateView.disableAnimation = VirtualKeyboardSettings.fullScreenMode
            keyboard.fullScreenMode = VirtualKeyboardSettings.fullScreenMode
        }
    }
    onAvailableLocaleIndicesChanged: hideLanguagePopup()
    onAvailableCustomLocaleIndicesChanged: hideLanguagePopup()
    onLocaleChanged: {
        hideLanguagePopup()
        inputMethodNeedsReset = true
        inputModeNeedsReset = true
        updateLayout()
    }
    onInputLocaleChanged: {
        if (Qt.locale(inputLocale).name !== "C")
            InputContext.priv.locale = inputLocale
    }
    onLayoutChanged: hideLanguagePopup()
    onLayoutTypeChanged: {
        updateAvailableLocaleIndices()
        updateLayout()
    }
    onLatinOnlyChanged: inputModeNeedsReset = true
    onPreferNumbersChanged: {
        keyboard.symbolMode = !keyboard.handwritingMode && preferNumbers
        inputModeNeedsReset = true
    }
    onDialableCharactersOnlyChanged: inputModeNeedsReset = true
    onFormattedNumbersOnlyChanged: inputModeNeedsReset = true
    onDigitsOnlyChanged: inputModeNeedsReset = true
    onHandwritingModeChanged: if (!keyboard.handwritingMode) keyboard.fullScreenHandwritingMode = false
    onFullScreenHandwritingModeChanged: if (keyboard.fullScreenHandwritingMode) keyboard.handwritingMode = true
    onLanguagePopupListActiveChanged: {
        if (languagePopupListActive && navigationModeActive)
            keyboardInputArea.initialKey = null
    }

    Connections {
        target: InputContext
        onInputMethodHintsChanged: {
            if (InputContext.priv.focus)
                updateInputMethod()
        }
    }
    Connections {
        target: InputContext.priv
        onInputItemChanged: {
            keyboard.hideLanguagePopup()
            if (active && symbolMode && !preferNumbers)
                symbolMode = false
        }
        onFocusChanged: {
            if (InputContext.priv.focus)
                updateInputMethod()
        }
        onNavigationKeyPressed: {
            var initialKey
            var direction = wordCandidateView.effectiveLayoutDirection == Qt.LeftToRight ? 1 : -1
            switch (key) {
            case Qt.Key_Left:
                if (keyboard.navigationModeActive && !keyboardInputArea.initialKey) {
                    if (languagePopupListActive) {
                        hideLanguagePopup()
                        keyboardInputArea.setActiveKey(null)
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                        break
                    }
                    if (alternativeKeys.active) {
                        if (alternativeKeys.listView.currentIndex > 0) {
                            alternativeKeys.listView.decrementCurrentIndex()
                        } else {
                            alternativeKeys.close()
                            keyboardInputArea.setActiveKey(null)
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                        }
                        break
                    }
                    if (wordCandidateContextMenu.active) {
                        hideWordCandidateContextMenu()
                        break
                    }
                    if (wordCandidateView.count) {
                        if (wordCandidateView.effectiveLayoutDirection == Qt.LeftToRight &&
                                wordCandidateView.currentIndex > 0) {
                            wordCandidateView.decrementCurrentIndex()
                        } else if (wordCandidateView.effectiveLayoutDirection == Qt.RightToLeft &&
                                   wordCandidateView.currentIndex + 1 < wordCandidateView.count) {
                            wordCandidateView.incrementCurrentIndex()
                        } else {
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                            initialKey = keyboardInputArea.initialKey
                            while (keyboardInputArea.navigateToNextKey(0, 1 * direction, false))
                                initialKey = keyboardInputArea.initialKey
                            while (keyboardInputArea.navigateToNextKey(1, 0, false))
                                initialKey = keyboardInputArea.initialKey
                            keyboardInputArea.initialKey = initialKey
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                        }
                        break
                    }
                }
                initialKey = keyboardInputArea.initialKey
                if (!keyboardInputArea.navigateToNextKey(-1, 0, false)) {
                    keyboardInputArea.initialKey = initialKey
                    if (!keyboardInputArea.navigateToNextKey(0, -1 * direction, false)) {
                        if (wordCandidateView.count) {
                            if (wordCandidateView.count) {
                                wordCandidateView.currentIndex =
                                        wordCandidateView.effectiveLayoutDirection == Qt.LeftToRight ?
                                            (wordCandidateView.count - 1) : 0
                                break
                            }
                            break
                        }
                        keyboardInputArea.initialKey = initialKey
                        keyboardInputArea.navigateToNextKey(0, -1 * direction, true)
                    }
                    keyboardInputArea.navigateToNextKey(-1, 0, true)
                }
                break
            case Qt.Key_Up:
                if (languagePopupListActive) {
                    if (languagePopupList.currentIndex > 0) {
                        languagePopupList.decrementCurrentIndex()
                    } else if (languagePopupList.keyNavigationWraps) {
                        languagePopupList.currentIndex = languagePopupList.count - 1
                    } else {
                        hideLanguagePopup()
                        keyboardInputArea.setActiveKey(null)
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                    }
                } else if (alternativeKeys.active) {
                    alternativeKeys.close()
                    keyboardInputArea.setActiveKey(null)
                    keyboardInputArea.navigateToNextKey(0, 0, false)
                } else if (wordCandidateContextMenu.active) {
                    if (wordCandidateContextMenuList.currentIndex > 0) {
                        wordCandidateContextMenuList.decrementCurrentIndex()
                    } else if (wordCandidateContextMenuList.keyNavigationWraps && wordCandidateContextMenuList.count > 1) {
                        wordCandidateContextMenuList.currentIndex = wordCandidateContextMenuList.count - 1
                    } else {
                        hideWordCandidateContextMenu()
                    }
                } else if (keyboard.navigationModeActive && !keyboardInputArea.initialKey && wordCandidateView.count) {
                    keyboardInputArea.navigateToNextKey(0, 0, false)
                    initialKey = keyboardInputArea.initialKey
                    if (!keyboardInputArea.navigateToNextKey(0, -1, false)) {
                        keyboardInputArea.initialKey = initialKey
                        keyboardInputArea.navigateToNextKey(0, -1, true)
                    } else {
                        keyboardInputArea.navigateToNextKey(0, 1, false)
                    }
                } else if (!keyboardInputArea.navigateToNextKey(0, -1, !keyboard.navigationModeActive || !keyboardInputArea.initialKey || wordCandidateView.count == 0)) {
                    if (wordCandidateView.currentIndex === -1)
                        wordCandidateView.incrementCurrentIndex()
                }
                break
            case Qt.Key_Right:
                if (keyboard.navigationModeActive && !keyboardInputArea.initialKey) {
                    if (languagePopupListActive) {
                        hideLanguagePopup()
                        keyboardInputArea.setActiveKey(null)
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                        break
                    }
                    if (alternativeKeys.active) {
                        if (alternativeKeys.listView.currentIndex + 1 < alternativeKeys.listView.count) {
                            alternativeKeys.listView.incrementCurrentIndex()
                        } else {
                            alternativeKeys.close()
                            keyboardInputArea.setActiveKey(null)
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                        }
                        break
                    }
                    if (wordCandidateContextMenu.active) {
                        hideWordCandidateContextMenu()
                        break
                    }
                    if (wordCandidateView.count) {
                        if (wordCandidateView.effectiveLayoutDirection == Qt.LeftToRight &&
                                wordCandidateView.currentIndex + 1 < wordCandidateView.count) {
                            wordCandidateView.incrementCurrentIndex()
                        } else if (wordCandidateView.effectiveLayoutDirection == Qt.RightToLeft &&
                                   wordCandidateView.currentIndex > 0) {
                            wordCandidateView.decrementCurrentIndex()
                        } else {
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                            initialKey = keyboardInputArea.initialKey
                            while (keyboardInputArea.navigateToNextKey(0, -1 * direction, false))
                                initialKey = keyboardInputArea.initialKey;
                            while (keyboardInputArea.navigateToNextKey(-1, 0, false))
                                initialKey = keyboardInputArea.initialKey;
                            keyboardInputArea.initialKey = initialKey
                            keyboardInputArea.navigateToNextKey(0, 0, false)
                        }
                        break
                    }
                }
                initialKey = keyboardInputArea.initialKey
                if (!keyboardInputArea.navigateToNextKey(1, 0, false)) {
                    keyboardInputArea.initialKey = initialKey
                    if (!keyboardInputArea.navigateToNextKey(0, 1 * direction, false)) {
                        if (wordCandidateView.count) {
                            wordCandidateView.currentIndex =
                                    wordCandidateView.effectiveLayoutDirection == Qt.LeftToRight ?
                                        0 : (wordCandidateView.count - 1)
                            break
                        }
                        keyboardInputArea.initialKey = initialKey
                        keyboardInputArea.navigateToNextKey(0, 1 * direction, true)
                    }
                    keyboardInputArea.navigateToNextKey(1, 0, true)
                }
                break
            case Qt.Key_Down:
                if (languagePopupListActive) {
                    if (languagePopupList.currentIndex + 1 < languagePopupList.count) {
                        languagePopupList.incrementCurrentIndex()
                    } else if (languagePopupList.keyNavigationWraps) {
                        languagePopupList.currentIndex = 0
                    } else {
                        hideLanguagePopup()
                        keyboardInputArea.setActiveKey(null)
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                    }
                } else if (alternativeKeys.active) {
                    alternativeKeys.close()
                    keyboardInputArea.setActiveKey(null)
                    keyboardInputArea.navigateToNextKey(0, 0, false)
                } else if (wordCandidateContextMenu.active) {
                    if (wordCandidateContextMenuList.currentIndex + 1 < wordCandidateContextMenuList.count) {
                        wordCandidateContextMenuList.incrementCurrentIndex()
                    } else if (wordCandidateContextMenuList.keyNavigationWraps && wordCandidateContextMenuList.count > 1) {
                        wordCandidateContextMenuList.currentIndex = 0
                    } else {
                        hideWordCandidateContextMenu()
                        keyboardInputArea.setActiveKey(null)
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                    }
                } else if (keyboard.navigationModeActive && !keyboardInputArea.initialKey && wordCandidateView.count) {
                    keyboardInputArea.navigateToNextKey(0, 0, false)
                    initialKey = keyboardInputArea.initialKey
                    if (!keyboardInputArea.navigateToNextKey(0, 1, false)) {
                        keyboardInputArea.initialKey = initialKey
                        keyboardInputArea.navigateToNextKey(0, 1, true)
                    } else {
                        keyboardInputArea.navigateToNextKey(0, -1, false)
                    }
                } else if (!keyboardInputArea.navigateToNextKey(0, 1, !keyboard.navigationModeActive || !keyboardInputArea.initialKey || wordCandidateView.count == 0)) {
                    if (wordCandidateView.currentIndex === -1)
                        wordCandidateView.incrementCurrentIndex()
                }
                break
            case Qt.Key_Return:
                if (!keyboard.navigationModeActive)
                    break
                if (languagePopupListActive) {
                    if (!isAutoRepeat) {
                        languagePopupList.model.selectItem(languagePopupList.currentIndex)
                        keyboardInputArea.reset()
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                    }
                } else if (keyboardInputArea.initialKey) {
                    if (!isAutoRepeat) {
                        pressAndHoldTimer.restart()
                        keyboardInputArea.setActiveKey(keyboardInputArea.initialKey)
                        keyboardInputArea.press(keyboardInputArea.initialKey, true)
                    }
                } else if (!wordCandidateContextMenu.active && wordCandidateView.count > 0) {
                    if (!isAutoRepeat) {
                        pressAndHoldTimer.restart()
                    }
                }
                break
            default:
                break
            }
        }
        onNavigationKeyReleased: {
            switch (key) {
            case Qt.Key_Return:
                if (!keyboard.navigationModeActive) {
                    if (languagePopupListActive)
                        languagePopupList.model.selectItem(languagePopupList.currentIndex)
                    break
                }
                if (isAutoRepeat)
                    break
                if (!languagePopupListActive && !alternativeKeys.active && !wordCandidateContextMenu.active && keyboard.activeKey) {
                    keyboardInputArea.release(keyboard.activeKey)
                    pressAndHoldTimer.stop()
                    alternativeKeys.close()
                    keyboardInputArea.setActiveKey(null)
                    if (!languagePopupListActive && keyboardInputArea.navigationCursor !== Qt.point(-1, -1))
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                } else if (wordCandidateContextMenu.active) {
                    if (!wordCandidateContextMenu.openedByNavigationKeyLongPress) {
                        wordCandidateContextMenu.selectCurrentItem()
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                    } else {
                        wordCandidateContextMenu.openedByNavigationKeyLongPress = false
                    }
                } else if (alternativeKeys.active) {
                    if (!alternativeKeys.openedByNavigationKeyLongPress) {
                        alternativeKeys.clicked()
                        alternativeKeys.close()
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                        keyboardInputArea.reset()
                    } else {
                        alternativeKeys.openedByNavigationKeyLongPress = false
                    }
                } else if (!wordCandidateContextMenu.active && wordCandidateView.count > 0) {
                    wordCandidateView.model.selectItem(wordCandidateView.currentIndex)
                    if (!InputContext.preeditText.length)
                        keyboardInputArea.navigateToNextKey(0, 1, true)
                }
                break
            default:
                break
            }
        }
    }
    Connections {
        target: InputContext.inputEngine
        onVirtualKeyClicked: {
            if (isAutoRepeat && keyboard.activeKey)
                soundEffect.play(keyboard.activeKey.soundEffect)
            if (key !== Qt.Key_unknown && keyboardInputArea.dragSymbolMode) {
                keyboardInputArea.dragSymbolMode = false
                keyboard.symbolMode = false
            } else if (key === Qt.Key_Space) {
                var surroundingText = InputContext.surroundingText.trim()
                if (InputContext.priv.shiftHandler.sentenceEndingCharacters.indexOf(surroundingText.charAt(surroundingText.length-1)) >= 0)
                    keyboard.symbolMode = false
            }
        }
    }
    FolderListModel {
        id: layoutsModel
        nameFilters: ["$"]
        folder: VirtualKeyboardSettings.layoutPath
    }
    Connections {
        target: layoutsModel
        onCountChanged: {
            updateDefaultLocale()
            localeIndex = defaultLocaleIndex
        }
    }
    AlternativeKeys {
        id: alternativeKeys
        objectName: "alternativeKeys"
        // Add some extra margin for decoration
        property real horizontalMargin: style.alternateKeysListItemWidth
        property real verticalMargin: style.alternateKeysListItemHeight
        property rect previewRect: Qt.rect(keyboard.x + alternativeKeys.listView.x - horizontalMargin,
                                           keyboard.y + alternativeKeys.listView.y - verticalMargin,
                                           alternativeKeys.listView.width + horizontalMargin * 2,
                                           alternativeKeys.listView.height + verticalMargin * 2)
        property bool openedByNavigationKeyLongPress
        onVisibleChanged: {
            if (visible)
                InputContext.priv.previewRectangle = Qt.binding(function() {return previewRect})
            else
                openedByNavigationKeyLongPress = false
            InputContext.priv.previewVisible = visible
        }
    }
    Timer {
        id: pressAndHoldTimer
        interval: 800
        onTriggered: {
            if (keyboard.activeKey && keyboard.activeKey === keyboardInputArea.initialKey) {
                var origin = keyboard.mapFromItem(activeKey, activeKey.width / 2, 0)
                if (alternativeKeys.open(keyboard.activeKey, origin.x, origin.y)) {
                    InputContext.inputEngine.virtualKeyCancel()
                    keyboardInputArea.initialKey = null
                    alternativeKeys.openedByNavigationKeyLongPress = keyboard.navigationModeActive
                } else if (keyboard.activeKey.key === Qt.Key_Context1) {
                    InputContext.inputEngine.virtualKeyCancel()
                    keyboardInputArea.dragSymbolMode = true
                    keyboard.symbolMode = true
                    keyboardInputArea.initialKey = null
                    if (keyboardInputArea.navigationCursor !== Qt.point(-1, -1))
                        keyboardInputArea.navigateToNextKey(0, 0, false)
                }
            } else if (keyboardInputArea.dragSymbolMode &&
                       keyboard.activeKey &&
                       keyboard.activeKey.functionKey &&
                       !keyboard.activeKey.repeat) {
                InputContext.inputEngine.virtualKeyCancel()
                keyboardInputArea.click(keyboard.activeKey)
                keyboardInputArea.initialKey = null
                if (keyboardInputArea.navigationCursor !== Qt.point(-1, -1))
                    keyboardInputArea.navigateToNextKey(0, 0, false)
            } else if (!wordCandidateContextMenu.active) {
                wordCandidateContextMenu.show(wordCandidateView.currentIndex)
                wordCandidateContextMenu.openedByNavigationKeyLongPress = keyboard.navigationModeActive
            }
        }
    }
    Timer {
        id: releaseInaccuracyTimer
        interval: 500
        onTriggered: {
            if (keyboardInputArea.pressed && activeTouchPoint && !alternativeKeys.active && !keyboardInputArea.dragSymbolMode) {
                var key = keyboardInputArea.keyOnPoint(activeTouchPoint.x, activeTouchPoint.y)
                if (key !== keyboard.activeKey) {
                    InputContext.inputEngine.virtualKeyCancel()
                    keyboardInputArea.setActiveKey(key)
                    keyboardInputArea.press(key, false)
                }
            }
        }
    }
    CharacterPreviewBubble {
        id: characterPreview
        objectName: "characterPreviewBubble"
        active: keyboardInputArea.pressed && !alternativeKeys.active
        property rect previewRect: Qt.rect(keyboard.x + characterPreview.x,
                                           keyboard.y + characterPreview.y,
                                           characterPreview.width,
                                           characterPreview.height)
    }
    Binding {
        target: InputContext.priv
        property: "previewRectangle"
        value: characterPreview.previewRect
        when: characterPreview.visible
        restoreMode: Binding.RestoreBinding
    }
    Binding {
        target: InputContext.priv
        property: "previewRectangle"
        value: languagePopupList.previewRect
        when: languagePopupListActive
        restoreMode: Binding.RestoreBinding
    }
    Binding {
        target: InputContext.priv
        property: "previewVisible"
        value: characterPreview.visible || languagePopupListActive
        restoreMode: Binding.RestoreBinding
    }
    Loader {
        id: styleLoader
        source: VirtualKeyboardSettings.style
        Binding {
            target: styleLoader.item
            property: "keyboardHeight"
            value: keyboardInnerContainer.height
            restoreMode: Binding.RestoreBinding
        }
    }
    Loader {
        id: naviationHighlight
        objectName: "naviationHighlight"
        property var highlightItem: {
            if (keyboard.navigationModeActive) {
                if (keyboardInputArea.initialKey) {
                    return keyboardInputArea.initialKey
                } else if (languagePopupListActive) {
                    return languagePopupList.highlightItem
                } else if (alternativeKeys.listView.count > 0) {
                    return alternativeKeys.listView.highlightItem
                } else if (wordCandidateContextMenu.active) {
                    return wordCandidateContextMenuList.highlightItem
                } else if (wordCandidateView.count > 0) {
                    return wordCandidateView.highlightItem
                }
            }
            return keyboard
        }
        // Note: without "highlightItem.x - highlightItem.x" the binding does not work for alternativeKeys
        property var highlightItemOffset: highlightItem ? keyboard.mapFromItem(highlightItem, highlightItem.x - highlightItem.x, highlightItem.y - highlightItem.y) : ({x:0, y:0})
        property int moveDuration: 200
        property int resizeDuration: 200
        property alias xAnimation: xAnimation
        property alias yAnimation: yAnimation
        property alias widthAnimation: widthAnimation
        property alias heightAnimation: heightAnimation
        z: 2
        x: highlightItemOffset.x
        y: highlightItemOffset.y
        width: highlightItem ? highlightItem.width : 0
        height: highlightItem ? highlightItem.height : 0
        visible: keyboard.navigationModeActive && highlightItem !== null && highlightItem !== keyboard
        sourceComponent: keyboard.style.navigationHighlight
        Behavior on x {
            NumberAnimation { id: xAnimation; duration: naviationHighlight.moveDuration; easing.type: Easing.OutCubic }
        }
        Behavior on y {
            NumberAnimation { id: yAnimation; duration: naviationHighlight.moveDuration; easing.type: Easing.OutCubic }
        }
        Behavior on width {
            NumberAnimation { id: widthAnimation; duration: naviationHighlight.resizeDuration; easing.type: Easing.OutCubic }
        }
        Behavior on height {
            NumberAnimation { id: heightAnimation; duration: naviationHighlight.resizeDuration; easing.type: Easing.OutCubic }
        }
    }

    ShadowInputControl {
        id: shadowInputControl
        objectName: "shadowInputControl"
        z: -3
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: wordCandidateView.top
        height: (keyboard.parent.parent ? keyboard.parent.parent.height : Screen.height) -
                keyboard.height - (wordCandidateView.visibleCondition && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? wordCandidateView.height : 0)
        visible: fullScreenMode && (shadowInputControlVisibleTimer.running || InputContext.animating)

        Connections {
            target: keyboard
            onActiveChanged: {
                if (keyboard.active)
                    shadowInputControlVisibleTimer.start()
                else
                    shadowInputControlVisibleTimer.stop()
            }
        }

        Timer {
            id: shadowInputControlVisibleTimer
            interval: 2147483647
            repeat: true
        }

        MouseArea {
            onPressed: keyboard.hideLanguagePopup()
            anchors.fill: parent
            enabled: languagePopupList.enabled
        }
    }

    SelectionControl {
        objectName: "fullScreenModeSelectionControl"
        inputContext: InputContext.priv.shadow
        anchors.top: shadowInputControl.top
        anchors.left: shadowInputControl.left
        enabled: keyboard.enabled && fullScreenMode
    }

    ListView {
        id: wordCandidateView
        objectName: "wordCandidateView"
        clip: true
        z: -2
        property bool disableAnimation: VirtualKeyboardSettings.fullScreenMode
        property bool empty: true
        readonly property bool visibleCondition: (((!wordCandidateView.empty || wordCandidateViewAutoHideTimer.running || shadowInputControl.visible) &&
                                                   InputContext.inputEngine.wordCandidateListVisibleHint) || VirtualKeyboardSettings.wordCandidateList.alwaysVisible) &&
                                                 (keyboard.active || shadowInputControl.visible)
        readonly property real visibleYOffset: VirtualKeyboardSettings.wordCandidateList.alwaysVisible ? 0 : -height
        readonly property real currentYOffset: visibleCondition || wordCandidateViewTransition.running ? visibleYOffset : 0
        height: Math.round(style.selectionListHeight)
        anchors.left: parent.left
        anchors.right: parent.right
        spacing: 0
        orientation: ListView.Horizontal
        snapMode: ListView.SnapToItem
        delegate: style.selectionListDelegate
        highlight: style.selectionListHighlight ? style.selectionListHighlight : defaultHighlight
        highlightMoveDuration: 0
        highlightResizeDuration: 0
        add: style.selectionListAdd
        remove: style.selectionListRemove
        keyNavigationWraps: true
        model: InputContext.inputEngine.wordCandidateListModel
        onCurrentItemChanged: if (currentItem) soundEffect.register(currentItem.soundEffect)
        Connections {
            target: wordCandidateView.model ? wordCandidateView.model : null
            onActiveItemChanged: wordCandidateView.currentIndex = index
            onItemSelected: if (wordCandidateView.currentItem) soundEffect.play(wordCandidateView.currentItem.soundEffect)
            onCountChanged: {
                var empty = wordCandidateView.model.count === 0
                if (empty)
                    wordCandidateViewAutoHideTimer.restart()
                else
                    wordCandidateViewAutoHideTimer.stop()
                wordCandidateView.empty = empty
                keyboard.hideWordCandidateContextMenu()
            }
        }
        Connections {
            target: InputContext.priv
            onInputItemChanged: wordCandidateViewAutoHideTimer.stop()
        }
        Connections {
            target: InputContext.inputEngine
            onWordCandidateListVisibleHintChanged: wordCandidateViewAutoHideTimer.stop()
        }
        Timer {
            id: wordCandidateViewAutoHideTimer
            interval: VirtualKeyboardSettings.wordCandidateList.autoHideDelay
        }
        Loader {
            sourceComponent: style.selectionListBackground
            anchors.fill: parent
            z: -1
        }
        Component {
            id: defaultHighlight
            Item {}
        }
        states: State {
            name: "visible"
            when: wordCandidateView.visibleCondition
            PropertyChanges {
                target: wordCandidateView
                y: wordCandidateView.visibleYOffset
            }
        }
        transitions: Transition {
            id: wordCandidateViewTransition
            to: "visible"
            enabled: !InputContext.animating && !VirtualKeyboardSettings.wordCandidateList.alwaysVisible && !wordCandidateView.disableAnimation
            reversible: true
            ParallelAnimation {
                NumberAnimation {
                    properties: "y"
                    duration: 250
                    easing.type: Easing.InOutQuad
                }
            }
        }

        function longPressItem(index) {
            return keyboard.showWordCandidateContextMenu(index)
        }
    }

    Item {
        id: soundEffect
        property var __sounds: ({})
        property bool available: false

        signal playingChanged(url source, bool playing)

        Connections {
            target: VirtualKeyboardSettings
            onStyleNameChanged: {
                soundEffect.__sounds = {}
                soundEffect.available = false
            }
        }

        function play(sound) {
            if (enabled && sound != Qt.resolvedUrl("")) {
                var soundId = Qt.md5(sound)
                var multiSoundEffect = __sounds[soundId]
                if (!multiSoundEffect)
                    multiSoundEffect = register(sound)
                if (multiSoundEffect)
                    multiSoundEffect.play()
            }
        }

        function register(sound) {
            var multiSoundEffect = null
            if (enabled && sound != Qt.resolvedUrl("")) {
                var soundId = Qt.md5(sound)
                multiSoundEffect = __sounds[soundId]
                if (!multiSoundEffect) {
                    multiSoundEffect = Qt.createQmlObject('import QtQuick 2.0; import QtQuick.VirtualKeyboard 2.1; MultiSoundEffect {}', soundEffect)
                    if (multiSoundEffect) {
                        multiSoundEffect.playingChanged.connect(soundEffect.playingChanged)
                        multiSoundEffect.source = sound
                        __sounds[soundId] = multiSoundEffect
                        available = true
                    }
                }
            }
            return multiSoundEffect
        }
    }

    Loader {
        id: keyboardBackground
        z: -1
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        height: keyboardInnerContainer.height
        sourceComponent: style.keyboardBackground

        Item {
            id: keyboardInnerContainer
            z: 1
            width: Math.round(keyboardBackground.width)
            height: Math.round(style.keyboardDesignHeight * width / style.keyboardDesignWidth)
            anchors.horizontalCenter: parent.horizontalCenter
            LayoutMirroring.enabled: false
            LayoutMirroring.childrenInherit: true

            Loader {
                id: keyboardLayoutLoader
                objectName: "keyboardLayoutLoader"

                anchors.fill: parent
                anchors.leftMargin: Math.round(style.keyboardRelativeLeftMargin * parent.width)
                anchors.rightMargin: Math.round(style.keyboardRelativeRightMargin * parent.width)
                anchors.topMargin: Math.round(style.keyboardRelativeTopMargin * parent.height)
                anchors.bottomMargin: Math.round(style.keyboardRelativeBottomMargin * parent.height)

                Binding {
                    target: keyboardLayoutLoader
                    property: "source"
                    value: keyboard.layout
                    when: keyboard.layout.length > 0
                    restoreMode: Binding.RestoreBinding
                }

                onItemChanged: {
                    // Reset input mode if the new layout wants to override it
                    if (item && item.inputMode !== -1)
                        inputModeNeedsReset = true
                }

                MultiPointTouchArea {
                    id: keyboardInputArea
                    objectName: "keyboardInputArea"

                    property var initialKey: null
                    property bool dragSymbolMode
                    property real releaseMargin: initialKey !== null ? Math.min(initialKey.width / 3, initialKey.height / 3) : 0
                    property point navigationCursor: Qt.point(-1, -1)

                    anchors.fill: keyboardLayoutLoader

                    Connections {
                        target: keyboardLayoutLoader
                        onStatusChanged: {
                            if (keyboardLayoutLoader.status == Loader.Ready &&
                                    keyboard.navigationModeActive &&
                                    keyboardInputArea.navigationCursor !== Qt.point(-1, -1))
                                keyboard.navigationModeActive = keyboardInputArea.navigateToNextKey(0, 0, false)
                        }
                    }
                    Connections {
                        target: keyboard
                        onNavigationModeActiveChanged: {
                            if (!keyboard.navigationModeActive) {
                                keyboardInputArea.navigationCursor = Qt.point(-1, -1)
                                keyboardInputArea.reset()
                            }
                        }
                    }

                    function press(key, isRealPress) {
                        if (key && key.enabled) {
                            if (!key.noKeyEvent)
                                InputContext.inputEngine.virtualKeyPress(key.key, key.uppercased ? key.text.toUpperCase() : key.text, key.uppercased ? Qt.ShiftModifier : 0, key.repeat && !dragSymbolMode)
                            if (isRealPress)
                                soundEffect.play(key.soundEffect)
                        }
                    }
                    function release(key) {
                        if (key && key.enabled) {
                            if (!key.noKeyEvent)
                                InputContext.inputEngine.virtualKeyRelease(key.key, key.uppercased ? key.text.toUpperCase() : key.text, key.uppercased ? Qt.ShiftModifier : 0)
                            key.clicked()
                        }
                    }
                    function click(key) {
                        if (key && key.enabled) {
                            if (!key.noKeyEvent)
                                InputContext.inputEngine.virtualKeyClick(key.key, InputContext.uppercase ? key.text.toUpperCase() : key.text, InputContext.uppercase ? Qt.ShiftModifier : 0)
                            key.clicked()
                        }
                    }
                    function setActiveKey(activeKey) {
                        if (keyboard.activeKey === activeKey)
                            return
                        if (keyboard.activeKey) {
                            keyboard.activeKey.active = false
                        }
                        keyboard.activeKey = activeKey
                        if (keyboard.activeKey) {
                            keyboard.activeKey.active = true
                        }
                    }
                    function keyOnPoint(px, py) {
                        var parentItem = keyboardLayoutLoader
                        var child = parentItem.childAt(px, py)
                        while (child !== null) {
                            var position = parentItem.mapToItem(child, px, py)
                            px = position.x; py = position.y
                            parentItem = child
                            child = parentItem.childAt(px, py)
                            if (child && child.key !== undefined)
                                return child
                        }
                        return null
                    }
                    function hitInitialKey(x, y, margin) {
                        if (!initialKey)
                            return false
                        var position = initialKey.mapFromItem(keyboardInputArea, x, y)
                        return (position.x > -margin
                                && position.y > -margin
                                && position.x < initialKey.width + margin
                                && position.y < initialKey.height + margin)
                    }
                    function containsPoint(touchPoints, point) {
                        if (!point)
                            return false
                        for (var i in touchPoints)
                            if (touchPoints[i].pointId == point.pointId)
                                return true
                        return false
                    }
                    function releaseActiveKey() {
                        if (alternativeKeys.active) {
                            alternativeKeys.clicked()
                        } else if (keyboard.activeKey) {
                            release(keyboard.activeKey)
                        }
                        reset()
                    }
                    function reset() {
                        releaseInaccuracyTimer.stop()
                        pressAndHoldTimer.stop()
                        setActiveKey(null)
                        activeTouchPoint = null
                        alternativeKeys.close()
                        if (dragSymbolMode) {
                            keyboard.symbolMode = false
                            dragSymbolMode = false
                        }
                    }
                    function nextKeyInNavigation(dX, dY, wrapEnabled) {
                        var nextKey = null, x, y, itemOffset
                        if (dX !== 0 || dY !== 0) {
                            var offsetX, offsetY
                            for (offsetX = dX, offsetY = dY;
                                 Math.abs(offsetX) < width && Math.abs(offsetY) < height;
                                 offsetX += dX, offsetY += dY) {
                                x = navigationCursor.x + offsetX
                                if (x < 0) {
                                    if (!wrapEnabled)
                                        break
                                    x += width
                                } else if (x >= width) {
                                    if (!wrapEnabled)
                                        break
                                    x -= width
                                }
                                y = navigationCursor.y + offsetY
                                if (y < 0) {
                                    if (!wrapEnabled)
                                        break
                                    y += height
                                } else if (y >= height) {
                                    if (!wrapEnabled)
                                        break
                                    y -= height
                                }
                                nextKey = keyOnPoint(x, y)
                                if (nextKey) {
                                    // Check if key is visible. Only the visible keys have keyPanelDelegate set.
                                    if (nextKey != initialKey && nextKey.hasOwnProperty("keyPanelDelegate") && nextKey.keyPanelDelegate)
                                        break
                                    // Jump over the item to reduce the number of iterations in this loop
                                    itemOffset = mapToItem(nextKey, x, y)
                                    if (dX > 0)
                                        offsetX += nextKey.width - itemOffset.x
                                    else if (dX < 0)
                                        offsetX -= itemOffset.x
                                    else if (dY > 0)
                                        offsetY += nextKey.height - itemOffset.y
                                    else if (dY < 0)
                                        offsetY -= itemOffset.y
                                }
                                nextKey = null
                            }
                        } else {
                            nextKey = keyOnPoint(navigationCursor.x, navigationCursor.y)
                        }
                        if (nextKey) {
                            itemOffset = mapFromItem(nextKey, nextKey.width / 2, nextKey.height / 2)
                            if (dX) {
                                x = itemOffset.x
                            } else if (dY) {
                                y = itemOffset.y
                            } else {
                                x = itemOffset.x
                                y = itemOffset.y
                            }
                            navigationCursor = Qt.point(x, y)
                        }
                        return nextKey
                    }
                    function navigateToNextKey(dX, dY, wrapEnabled) {
                        // Resolve initial landing point of the navigation cursor
                        if (!keyboard.navigationModeActive || keyboard.navigationCursor === Qt.point(-1, -1)) {
                            if (dX > 0)
                                navigationCursor = Qt.point(0, height / 2)
                            else if (dX < 0)
                                navigationCursor = Qt.point(width, height / 2)
                            else if (dY > 0)
                                navigationCursor = Qt.point(width / 2, 0)
                            else if (dY < 0)
                                navigationCursor = Qt.point(width / 2, height)
                            else
                                navigationCursor = Qt.point(width / 2, height / 2)
                            keyboard.navigationModeActive = true
                        }
                        if (dX && dY) {
                            initialKey = nextKeyInNavigation(dX, 0, wrapEnabled)
                            if (initialKey || wrapEnabled)
                                initialKey = nextKeyInNavigation(0, dY, wrapEnabled)
                        } else {
                            initialKey = nextKeyInNavigation(dX, dY, wrapEnabled)
                        }
                        return initialKey !== null
                    }

                    onPressed: {
                        keyboard.navigationModeActive = false

                        // Immediately release any pending key that the user might be
                        // holding (and about to release) when a second key is pressed.
                        if (activeTouchPoint)
                            releaseActiveKey();

                        for (var i in touchPoints) {
                            // Release any key pressed by a previous iteration of the loop.
                            if (containsPoint(touchPoints, activeTouchPoint))
                                releaseActiveKey();

                            releaseInaccuracyTimer.start()
                            pressAndHoldTimer.start()
                            initialKey = keyOnPoint(touchPoints[i].x, touchPoints[i].y)
                            activeTouchPoint = touchPoints[i]
                            setActiveKey(initialKey)
                            press(initialKey, true)
                        }
                    }
                    onUpdated: {
                        if (!containsPoint(touchPoints, activeTouchPoint))
                            return

                        if (alternativeKeys.active) {
                            alternativeKeys.move(mapToItem(alternativeKeys, activeTouchPoint.x, 0).x)
                        } else {
                            var key = null
                            if (releaseInaccuracyTimer.running) {
                                if (hitInitialKey(activeTouchPoint.x, activeTouchPoint.y, releaseMargin)) {
                                    key = initialKey
                                } else if (initialKey) {
                                    releaseInaccuracyTimer.stop()
                                    initialKey = null
                                }
                            }
                            if (key === null) {
                                key = keyOnPoint(activeTouchPoint.x, activeTouchPoint.y)
                            }
                            if (key !== keyboard.activeKey) {
                                InputContext.inputEngine.virtualKeyCancel()
                                setActiveKey(key)
                                press(key, false)
                                if (dragSymbolMode)
                                    pressAndHoldTimer.restart()
                            }
                        }
                    }
                    onReleased: {
                        if (containsPoint(touchPoints, activeTouchPoint))
                            releaseActiveKey();
                    }
                    onCanceled: {
                        if (containsPoint(touchPoints, activeTouchPoint))
                            reset()
                    }
                }
            }
        }
    }

    Item {
        id: languagePopup
        z: 1
        anchors.fill: parent
        LayoutMirroring.enabled: false
        LayoutMirroring.childrenInherit: true

        MouseArea {
            onPressed: keyboard.hideLanguagePopup()
            anchors.fill: parent
            enabled: languagePopupList.enabled
        }

        PopupList {
            id: languagePopupList
            objectName: "languagePopupList"
            z: 2
            anchors.left: parent.left
            anchors.top: parent.top
            enabled: false
            model: languageListModel
            delegate: keyboard.style ? keyboard.style.languageListDelegate : null
            highlight: keyboard.style ? keyboard.style.languageListHighlight : defaultHighlight
            add: keyboard.style ? keyboard.style.languageListAdd : null
            remove: keyboard.style ? keyboard.style.languageListRemove : null
            background: keyboard.style ? keyboard.style.languageListBackground : null
            property rect previewRect: Qt.rect(keyboard.x + languagePopupList.x,
                                               keyboard.y + languagePopupList.y,
                                               languagePopupList.width,
                                               languagePopupList.height)
        }

        ListModel {
            id: languageListModel

            function selectItem(index) {
                languagePopupList.currentIndex = index
                keyboard.soundEffect.play(languagePopupList.currentItem.soundEffect)
                changeLanguageTimer.newLocaleIndex = languageListModel.get(index).localeIndex
                changeLanguageTimer.start()
            }
        }

        Timer {
            id: changeLanguageTimer
            interval: 1
            property int newLocaleIndex
            onTriggered: {
                if (languagePopupListActive) {
                    hideLanguagePopup()
                    start()
                } else {
                    localeIndex = newLocaleIndex
                }
            }
        }

        function show(locales, parentItem, customLayoutsOnly) {
            if (!languagePopupList.enabled) {
                languageListModel.clear()
                for (var i = 0; i < locales.length; i++) {
                    languageListModel.append({localeName: locales[i].name, displayName: locales[i].locale.nativeLanguageName, localeIndex: locales[i].index})
                    if (locales[i].index === keyboard.localeIndex)
                        languagePopupList.currentIndex = i
                }
                languagePopupList.positionViewAtIndex(languagePopupList.currentIndex, ListView.Center)
                languagePopupList.anchors.leftMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, (parentItem.width - languagePopupList.width) / 2, 0).x)})
                languagePopupList.anchors.topMargin = Qt.binding(function() {return Math.round(keyboard.mapFromItem(parentItem, 0, -languagePopupList.height).y)})
            }
            languagePopupList.enabled = true
        }

        function hide() {
            if (languagePopupList.enabled) {
                languagePopupList.enabled = false
                languagePopupList.anchors.leftMargin = undefined
                languagePopupList.anchors.topMargin = undefined
                languageListModel.clear()
            }
        }
    }

    function showLanguagePopup(parentItem, customLayoutsOnly) {
        var locales = keyboard.listLocales(customLayoutsOnly, parent.externalLanguageSwitchEnabled)
        if (parent.externalLanguageSwitchEnabled) {
            var currentIndex = 0
            for (var i = 0; i < locales.length; i++) {
                if (locales[i] === keyboard.locale) {
                    currentIndex = i
                    break
                }
            }
            parent.externalLanguageSwitch(locales, currentIndex)
            return
        }
        languagePopup.show(locales, parentItem, customLayoutsOnly)
    }

    function hideLanguagePopup() {
        languagePopup.hide()
    }

    MouseArea {
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        height: keyboard.parent.parent ? keyboard.parent.parent.height : Screen.height
        onPressed: keyboard.hideWordCandidateContextMenu()
        enabled: wordCandidateContextMenuList.enabled
    }

    Item {
        id: wordCandidateContextMenu
        objectName: "wordCandidateContextMenu"
        z: 1
        anchors.fill: parent
        LayoutMirroring.enabled: false
        LayoutMirroring.childrenInherit: true
        property int previousWordCandidateIndex: -1
        readonly property bool active: wordCandidateContextMenuList.visible
        property bool openedByNavigationKeyLongPress

        PopupList {
            id: wordCandidateContextMenuList
            objectName: "wordCandidateContextMenuList"
            z: 2
            anchors.left: parent.left
            anchors.top: parent.top
            enabled: false
            model: wordCandidateContextMenuListModel
            property rect previewRect: Qt.rect(keyboard.x + wordCandidateContextMenuList.x,
                                               keyboard.y + wordCandidateContextMenuList.y,
                                               wordCandidateContextMenuList.width,
                                               wordCandidateContextMenuList.height)
        }

        ListModel {
            id: wordCandidateContextMenuListModel

            function selectItem(index) {
                wordCandidateContextMenu.previousWordCandidateIndex = -1
                wordCandidateContextMenuList.currentIndex = index
                keyboard.soundEffect.play(wordCandidateContextMenuList.currentItem.soundEffect)
                switch (get(index).action) {
                case "remove":
                    wordCandidateView.model.removeItem(wordCandidateView.currentIndex)
                    break
                }
                keyboard.hideWordCandidateContextMenu()
            }
        }

        function show(wordCandidateIndex) {
            if (wordCandidateContextMenu.enabled)
                wordCandidateContextMenu.hide()

            wordCandidateContextMenuListModel.clear()

            var canRemoveSuggestion = wordCandidateView.model.dataAt(wordCandidateIndex, SelectionListModel.Role.CanRemoveSuggestion)
            if (canRemoveSuggestion) {
                var dictionaryType = wordCandidateView.model.dataAt(wordCandidateIndex, SelectionListModel.Role.Dictionary)
                var removeItemText;
                switch (dictionaryType) {
                case SelectionListModel.DictionaryType.User:
                    //~ VirtualKeyboard Context menu for word suggestion if it can be removed from the user dictionary.
                    removeItemText = qsTr("Remove from dictionary")
                    break
                case SelectionListModel.DictionaryType.Default:
                    // Fallthrough
                default:
                    //~ VirtualKeyboard Context menu for word suggestion if it can be removed from the default dictionary.
                    removeItemText = qsTr("Block word")
                    break
                }
                wordCandidateContextMenuListModel.append({action: "remove", display: removeItemText, wordCompletionLength: 0})
            }

            if (wordCandidateContextMenuListModel.count === 0)
                return

            previousWordCandidateIndex = wordCandidateView.currentIndex
            wordCandidateView.currentIndex = wordCandidateIndex

            wordCandidateContextMenuList.anchors.leftMargin = Qt.binding(function() {
                var leftBorder = Math.round(wordCandidateView.mapFromItem(wordCandidateView.currentItem, (wordCandidateView.currentItem.width - wordCandidateContextMenuList.width) / 2, 0).x)
                var rightBorder = Math.round(wordCandidateContextMenuList.parent.width - wordCandidateContextMenuList.width)
                return Math.min(leftBorder, rightBorder)
            })

            wordCandidateContextMenuList.enabled = true
        }

        function hide() {
            if (wordCandidateContextMenuList.enabled) {
                if (previousWordCandidateIndex !== -1) {
                    wordCandidateView.currentIndex = previousWordCandidateIndex
                    previousWordCandidateIndex = -1
                }
                wordCandidateContextMenuList.enabled = false
                wordCandidateContextMenuList.anchors.leftMargin = undefined
                wordCandidateContextMenuListModel.clear()
            }
            openedByNavigationKeyLongPress = false
        }

        function selectCurrentItem() {
            if (active && wordCandidateContextMenuList.currentIndex !== -1)
                wordCandidateContextMenuListModel.selectItem(wordCandidateContextMenuList.currentIndex)
        }
    }

    function showWordCandidateContextMenu(wordCandidateIndex) {
        wordCandidateContextMenu.show(wordCandidateIndex)
    }

    function hideWordCandidateContextMenu() {
        wordCandidateContextMenu.hide()
    }

    function updateInputMethod() {
        if (!keyboardLayoutLoader.item)
            return
        if (!InputContext.priv.focus)
            return

        // Reset the custom input method if it is not included in the list of shared layouts
        if (customInputMethod && !inputMethodNeedsReset && customInputMethodSharedLayouts.indexOf(layoutType) === -1)
            inputMethodNeedsReset = true

        if (inputMethodNeedsReset) {
            if (customInputMethod) {
                customInputMethod.destroy()
                customInputMethod = null
            }
            customInputMethodSharedLayouts = []
            inputMethodNeedsReset = false
        }

        var inputMethod = null
        var inputMode = InputContext.inputEngine.inputMode

        // Use input method from keyboard layout
        if (keyboardLayoutLoader.item.inputMethod) {
            inputMethod = keyboardLayoutLoader.item.inputMethod
        } else if (!customInputMethod) {
            try {
                customInputMethod = keyboardLayoutLoader.item.createInputMethod()
                if (customInputMethod) {
                    // Pull the list of shared layouts from the keyboard layout
                    if (keyboardLayoutLoader.item.sharedLayouts)
                        customInputMethodSharedLayouts = customInputMethodSharedLayouts.concat(keyboardLayoutLoader.item.sharedLayouts)

                    // Make sure the current layout is included in the list
                    if (customInputMethodSharedLayouts.indexOf(layoutType) === -1)
                        customInputMethodSharedLayouts.push(layoutType)

                    // Reset input mode, since inputEngine.inputModes is updated
                    inputModeNeedsReset = true
                }
            } catch (e) {
                console.error(e.message)
            }
        }
        if (!inputMethod)
            inputMethod = customInputMethod ? customInputMethod : defaultInputMethod

        var inputMethodChanged = InputContext.inputEngine.inputMethod !== inputMethod
        if (inputMethodChanged) {
            InputContext.inputEngine.inputMethod = inputMethod
        }

        if (InputContext.inputEngine.inputMethod) {
            var inputModes = InputContext.inputEngine.inputModes
            if (inputModes.length > 0) {
                // Reset to default input mode if the input locale has changed
                if (inputModeNeedsReset) {
                    inputMode = inputModes[0]

                    // Check the current layout for input mode override
                    if (keyboardLayoutLoader.item.inputMode !== -1)
                        inputMode = keyboardLayoutLoader.item.inputMode

                    // Update input mode automatically in handwriting mode
                    if (keyboard.handwritingMode) {
                        if (keyboard.dialableCharactersOnly && inputModes.indexOf(InputEngine.InputMode.Dialable) !== -1)
                            inputMode = InputEngine.InputMode.Dialable
                        else if ((keyboard.formattedNumbersOnly || keyboard.digitsOnly) && inputModes.indexOf(InputEngine.InputMode.Numeric) !== -1)
                            inputMode = InputEngine.InputMode.Numeric
                        else if (keyboardLayoutLoader.item.inputMode === -1)
                            inputMode = inputModes[0]
                    }

                    // Check the input method hints for input mode overrides
                    if (latinOnly)
                        inputMode = InputEngine.InputMode.Latin
                    if (preferNumbers)
                        inputMode = InputEngine.InputMode.Numeric
                }

                // Make sure the input mode is supported by the current input method
                if (inputModes.indexOf(inputMode) === -1)
                    inputMode = inputModes[0]

                if (InputContext.inputEngine.inputMode !== inputMode || inputMethodChanged || inputModeNeedsReset)
                    InputContext.inputEngine.inputMode = inputMode

                inputModeNeedsReset = false
            }
        }

        // Clear the toggle shift timer
        InputContext.priv.shiftHandler.clearToggleShiftTimer()
    }

    function updateLayout() {
        var newLayout
        newLayout = findLayout(locale, layoutType)
        if (!newLayout.length) {
            newLayout = findLayout(locale, "main")
        }
        layout = newLayout
        inputLocale = locale
        updateInputMethod()
    }

    function updateDefaultLocale() {
        updateAvailableLocaleIndices()
        if (layoutsModel.count > 0) {
            var defaultLocales = []
            if (isValidLocale(VirtualKeyboardSettings.locale))
                defaultLocales.push(VirtualKeyboardSettings.locale)
            if (isValidLocale(InputContext.locale))
                defaultLocales.push(InputContext.locale)
            if (VirtualKeyboardSettings.activeLocales.length > 0 && isValidLocale(VirtualKeyboardSettings.activeLocales[0]))
                defaultLocales.push(VirtualKeyboardSettings.activeLocales[0])
            if (VirtualKeyboardSettings.availableLocales.indexOf("en_GB") !== -1)
                defaultLocales.push("en_GB")
            if (availableLocaleIndices.length > 0)
                defaultLocales.push(layoutsModel.get(availableLocaleIndices[0], "fileName"))
            var newDefaultLocaleIndex = -1
            for (var i = 0; i < defaultLocales.length; i++) {
                newDefaultLocaleIndex = findLocale(defaultLocales[i], -1)
                if (availableLocaleIndices.indexOf(newDefaultLocaleIndex) !== -1)
                    break;
                newDefaultLocaleIndex = -1
            }
            defaultLocaleIndex = newDefaultLocaleIndex
        } else {
            defaultLocaleIndex = -1
        }
    }

    function filterLocaleIndices(filterCb) {
        var localeIndices = []
        for (var i = 0; i < layoutsModel.count; i++) {
            if (localeIndices.indexOf(i) === -1) {
                var localeName = layoutsModel.get(i, "fileName")
                if (filterCb(localeName) && findLayout(localeName, "main"))
                    localeIndices.push(i)
            }
        }
        return localeIndices
    }

    function updateAvailableLocaleIndices() {
        // Update list of all available locales
        var fallbackIndex = findFallbackIndex()
        var newIndices = filterLocaleIndices(function(localeName) {
            return isValidLocale(localeName)
        })

        // Handle case where the VirtualKeyboardSettings.activeLocales contains no valid entries
        // Fetch all locales by ignoring active locales setting
        if (newIndices.length === 0) {
            newIndices = filterLocaleIndices(function(localeName) {
                return isValidLocale(localeName, true)
            })
        }

        // Fetch matching locale names
        var newAvailableLocales = []
        for (var i = 0; i < newIndices.length; i++) {
            newAvailableLocales.push(layoutsModel.get(newIndices[i], "fileName"))
        }

        newIndices.sort(function(a, b) { return a - b })
        availableLocaleIndices = newIndices
        newAvailableLocales.sort()
        InputContext.priv.updateAvailableLocales(newAvailableLocales)

        // Update list of custom locale indices
        newIndices = []
        for (i = 0; i < availableLocaleIndices.length; i++) {
            if (availableLocaleIndices[i] === localeIndex ||
                    layoutExists(layoutsModel.get(availableLocaleIndices[i], "fileName"), layoutType))
                newIndices.push(availableLocaleIndices[i])
        }
        availableCustomLocaleIndices = newIndices
    }

    function listLocales(customLayoutsOnly, localeNameOnly) {
        var locales = []
        var localeIndices = customLayoutsOnly ? availableCustomLocaleIndices : availableLocaleIndices
        for (var i = 0; i < localeIndices.length; i++) {
            var layoutFolder = layoutsModel.get(localeIndices[i], "fileName")
            if (localeNameOnly)
                locales.push(layoutFolder)
            else
                locales.push({locale:Qt.locale(layoutFolder), index:localeIndices[i], name:layoutFolder})
        }
        return locales
    }

    function nextLocaleIndex(customLayoutsOnly) {
        var newLocaleIndex = localeIndex
        var localeIndices = customLayoutsOnly ? availableCustomLocaleIndices : availableLocaleIndices
        var i = localeIndices.indexOf(localeIndex)
        if (i !== -1) {
            i = (i + 1) % localeIndices.length
            newLocaleIndex = localeIndices[i]
        }
        return newLocaleIndex
    }

    function changeInputLanguage(customLayoutsOnly) {
        var newLocaleIndex = nextLocaleIndex(customLayoutsOnly)
        if (newLocaleIndex !== -1 && newLocaleIndex !== localeIndex)
            localeIndex = newLocaleIndex
    }

    function canChangeInputLanguage(customLayoutsOnly) {
        if (customLayoutsOnly)
            return availableCustomLocaleIndices.length > 1
        return availableLocaleIndices.length > 1
    }

    function findLocale(localeName, defaultValue) {
        var languageCode = localeName.substring(0, 3) // Including the '_' delimiter
        var languageMatch = -1
        for (var i = 0; i < layoutsModel.count; i++) {
            if (!layoutsModel.isFolder(i))
                continue
            var layoutFolder = layoutsModel.get(i, "fileName")
            if (layoutFolder === localeName)
                return i
            if (languageMatch == -1 && layoutFolder.substring(0, 3) === languageCode)
                languageMatch = i
        }
        return (languageMatch != -1) ? languageMatch : defaultValue
    }

    function findFallbackIndex() {
        for (var i = 0; i < layoutsModel.count; i++) {
            var layoutFolder = layoutsModel.get(i, "fileName")
            if (layoutFolder === "fallback")
                return i
        }
        return -1
    }

    function isValidLocale(localeNameOrIndex, ignoreActiveLocales) {
        var localeName
        if (typeof localeNameOrIndex == "number") {
            if (localeNameOrIndex < 0 || localeNameOrIndex >= layoutsModel.count)
                return false
            localeName = layoutsModel.get(localeNameOrIndex, "fileName")
        } else {
            localeName = localeNameOrIndex
        }

        if (!localeName)
            return false

        if (localeName === "fallback")
            return false

        if (Qt.locale(localeName).name === "C")
            return false

        if (ignoreActiveLocales !== true &&
                VirtualKeyboardSettings.activeLocales.length > 0 &&
                VirtualKeyboardSettings.activeLocales.indexOf(localeName) === -1)
            return false

        return true
    }

    function getLayoutFile(localeName, layoutType) {
        if (localeName === "" || layoutType === "")
            return ""
        return layoutsModel.folder + "/" + localeName + "/" + layoutType + ".qml"
    }

    function getFallbackFile(localeName, layoutType) {
        if (localeName === "" || layoutType === "")
            return ""
        return layoutsModel.folder + "/" + localeName + "/" + layoutType + ".fallback"
    }

    function layoutExists(localeName, layoutType) {
        var result = InputContext.priv.fileExists(getLayoutFile(localeName, layoutType))
        if (!result && layoutType === "handwriting")
            result = InputContext.priv.fileExists(getFallbackFile(localeName, layoutType))
        return result
    }

    function findLayout(localeName, layoutType) {
        var layoutFile = getLayoutFile(localeName, layoutType)
        if (InputContext.priv.fileExists(layoutFile))
            return layoutFile
        var fallbackFile = getFallbackFile(localeName, layoutType)
        if (InputContext.priv.fileExists(fallbackFile)) {
            layoutFile = getLayoutFile("fallback", layoutType)
            if (InputContext.priv.fileExists(layoutFile))
                return layoutFile
        }
        return ""
    }

    function isHandwritingAvailable() {
        return InputContext.priv.inputMethods.indexOf("HandwritingInputMethod") !== -1 && layoutExists(locale, "handwriting")
    }

    function setHandwritingMode(enabled, resetInputMode) {
        if (enabled && resetInputMode)
            inputModeNeedsReset = true
        handwritingMode = enabled
    }
}
