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

#include <QtVirtualKeyboard/qvirtualkeyboardselectionlistmodel.h>
#include <QtVirtualKeyboard/qvirtualkeyboardabstractinputmethod.h>
#include <QtVirtualKeyboard/private/settings_p.h>
#include <QtCore/private/qabstractitemmodel_p.h>
#include <QtCore/qpointer.h>

QT_BEGIN_NAMESPACE

using namespace QtVirtualKeyboard;

class QVirtualKeyboardSelectionListModelPrivate : public QAbstractItemModelPrivate
{
public:
    QVirtualKeyboardSelectionListModelPrivate() :
        QAbstractItemModelPrivate(),
        dataSource(nullptr),
        type(QVirtualKeyboardSelectionListModel::Type::WordCandidateList),
        rowCount(0),
        wclAutoCommitWord(false)
    {
    }

    QHash<int, QByteArray> roles;
    QPointer<QVirtualKeyboardAbstractInputMethod> dataSource;
    QVirtualKeyboardSelectionListModel::Type type;
    int rowCount;
    bool wclAutoCommitWord;
};

/*!
    \qmltype SelectionListModel
    \instantiates QVirtualKeyboardSelectionListModel
    \inqmlmodule QtQuick.VirtualKeyboard
    \ingroup qtvirtualkeyboard-qml
    \brief Provides a data model for the selection lists.

    The SelectionListModel is a data model for word candidates
    provided by the input method.

    An instance of a SelectionListModel cannot be created directly.
    Instead, the InputEngine manages the instances and provides
    access to the model by InputEngine::wordCandidateListModel
    property.

    The model exposes the following data roles for the list delegate:
    \list
        \li \c display Display text for item.
        \li \c wordCompletionLength Word completion length for item.
        \li \c dictionaryType Dictionary type of the word, see QVirtualKeyboardSelectionListModel::DictionaryType.
        \li \c canRemoveSuggestion A boolean indicating if the word can be removed from the dictionary.
    \endlist

    The activeItemChanged signal indicates which item is currently
    highlighted by the input method. The view should respond to this
    signal by highlighting the corresponding item in the list.

    The user selection is handled by the selectItem() method. The view
    should be invoke this method when the user selects an item from the
    list.
*/

/*!
    \class QVirtualKeyboardSelectionListModel

    \inmodule QtVirtualKeyboard

    \brief List model for selection lists.

    This class acts as a bridge between the UI and the
    input method that provides the data for selection
    lists.
*/

/*!
    \enum QVirtualKeyboardSelectionListModel::Type

    This enum specifies the type of selection list.

    \value WordCandidateList
           Shows list of word candidates.
*/

/*!
    \enum QVirtualKeyboardSelectionListModel::Role

    This enum specifies a role of the data requested.

    \value Display
           The data to be rendered in form of text.
    \value DisplayRole
           \c obsolete Use Role::Display.
    \value WordCompletionLength
           An integer specifying the length of the word
           the completion part expressed as the
           number of characters counted from the
           end of the string.
    \value WordCompletionLengthRole
           \c obsolete Use Role::WordCompletionLength.
    \value Dictionary
           An integer specifying \ l {QVirtualKeyboardSelectionListModel::DictionaryType}{dictionary type}.
    \value CanRemoveSuggestion
           A boolean value indicating if the word candidate
           can be removed from the dictionary.
*/

/*!
    \enum QVirtualKeyboardSelectionListModel::DictionaryType

    This enum specifies the dictionary type of a word.

    \value Default
           The word candidate is from the default dictionary.
    \value User
           The word candidate is from the user dictionary.
*/

QVirtualKeyboardSelectionListModel::QVirtualKeyboardSelectionListModel(QObject *parent) :
    QAbstractListModel(*new QVirtualKeyboardSelectionListModelPrivate(), parent)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    d->roles =
        {{static_cast<int>(Role::Display), "display"},
         {static_cast<int>(Role::WordCompletionLength), "wordCompletionLength"},
         {static_cast<int>(Role::Dictionary), "dictionary"},
         {static_cast<int>(Role::CanRemoveSuggestion), "canRemoveSuggestion"}};
}

/*!
    \internal
*/
QVirtualKeyboardSelectionListModel::~QVirtualKeyboardSelectionListModel()
{
}

/*!
    \internal
*/
void QVirtualKeyboardSelectionListModel::setDataSource(QVirtualKeyboardAbstractInputMethod *dataSource, Type type)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    if (d->dataSource) {
        disconnect(this, SLOT(selectionListChanged(Type)));
        disconnect(this, SLOT(selectionListActiveItemChanged(Type, int)));
    }
    d->type = type;
    if (d->dataSource) {
        d->dataSource = nullptr;
        selectionListChanged(type);
        selectionListActiveItemChanged(type, -1);
    }
    d->dataSource = dataSource;
    if (d->dataSource) {
        QObject::connect(d->dataSource.data(), &QVirtualKeyboardAbstractInputMethod::selectionListChanged, this, &QVirtualKeyboardSelectionListModel::selectionListChanged);
        QObject::connect(d->dataSource.data(), &QVirtualKeyboardAbstractInputMethod::selectionListActiveItemChanged, this, &QVirtualKeyboardSelectionListModel::selectionListActiveItemChanged);
    }
}

/*!
    \internal
*/
QVirtualKeyboardAbstractInputMethod *QVirtualKeyboardSelectionListModel::dataSource() const
{
    Q_D(const QVirtualKeyboardSelectionListModel);
    return d->dataSource;
}

/*!
    \internal
*/
int QVirtualKeyboardSelectionListModel::rowCount(const QModelIndex &parent) const
{
    Q_D(const QVirtualKeyboardSelectionListModel);
    Q_UNUSED(parent)
    return d->rowCount;
}

/*!
    \internal
*/
QVariant QVirtualKeyboardSelectionListModel::data(const QModelIndex &index, int role) const
{
    Q_D(const QVirtualKeyboardSelectionListModel);
    return d->dataSource ? d->dataSource->selectionListData(d->type, index.row(), static_cast<Role>(role)) : QVariant();
}

/*!
    \internal
*/
QHash<int,QByteArray> QVirtualKeyboardSelectionListModel::roleNames() const
{
    Q_D(const QVirtualKeyboardSelectionListModel);
    return d->roles;
}

/*!
    \property QVirtualKeyboardSelectionListModel::count
    \internal
*/
/*
    \internal
*/
int QVirtualKeyboardSelectionListModel::count() const
{
    Q_D(const QVirtualKeyboardSelectionListModel);
    return d->rowCount;
}

/*! \qmlmethod void SelectionListModel::selectItem(int index)

    This method should be called when the user selects an item at position
    \a index from the list.
    The selection is forwarded to the input method for further processing.
*/
/*!
    This method should be called when the user selects an item at position
    \a index from the list.
    The selection is forwarded to the input method for further processing.
*/
void QVirtualKeyboardSelectionListModel::selectItem(int index)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    if (index >= 0 && index < d->rowCount && d->dataSource) {
        emit itemSelected(index);
        d->dataSource->selectionListItemSelected(d->type, index);
    }
}

/*!
    \qmlmethod void SelectionListModel::removeItem(int index)

    This method should be called when the user removes an item at position
    \a index from the list.
    The removal is forwarded to the input method for further processing.
*/
/*!
    This method should be called when the user removes an item at position
    \a index from the list.
    The removal is forwarded to the input method for further processing.
*/
void QVirtualKeyboardSelectionListModel::removeItem(int index)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    if (index >= 0 && index < d->rowCount && d->dataSource) {
        d->dataSource->selectionListRemoveItem(d->type, index);
    }
}

/*!
 * \internal
 */
QVariant QVirtualKeyboardSelectionListModel::dataAt(int index, QVirtualKeyboardSelectionListModel::Role role) const
{
    return data(this->index(index, 0), static_cast<int>(role));
}

/*!
    \internal
*/
void QVirtualKeyboardSelectionListModel::selectionListChanged(QVirtualKeyboardSelectionListModel::Type type)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    if (static_cast<Type>(type) == d->type) {
        int oldCount = d->rowCount;
        int newCount = d->dataSource ? d->dataSource->selectionListItemCount(d->type) : 0;
        if (newCount) {
            int changedCount = qMin(oldCount, newCount);
            if (changedCount)
                emit dataChanged(index(0), index(changedCount - 1));
            if (oldCount > newCount) {
                beginRemoveRows(QModelIndex(), newCount, oldCount - 1);
                d->rowCount = newCount;
                endRemoveRows();
            } else if (oldCount < newCount) {
                beginInsertRows(QModelIndex(), oldCount, newCount - 1);
                d->rowCount = newCount;
                endInsertRows();
            }
        } else {
            beginResetModel();
            d->rowCount = 0;
            endResetModel();
        }
        if (static_cast<QVirtualKeyboardSelectionListModel::Type>(type) == QVirtualKeyboardSelectionListModel::Type::WordCandidateList)
            d->wclAutoCommitWord = ((oldCount > 1 || (oldCount == 1 && d->wclAutoCommitWord)) && newCount == 1 &&
                                 Settings::instance()->wclAutoCommitWord() &&
                                 dataAt(0).toString().length() > 1);
        if (d->rowCount != oldCount)
            emit countChanged();
    }
}

/*!
    \internal
*/
void QVirtualKeyboardSelectionListModel::selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type type, int index)
{
    Q_D(QVirtualKeyboardSelectionListModel);
    if (static_cast<Type>(type) == d->type && index < d->rowCount) {
        emit activeItemChanged(index);
        if (index == 0 && d->wclAutoCommitWord)
            selectItem(0);
    }
}

/*!
    \qmlsignal void SelectionListModel::activeItemChanged(int index)

    This signal is emitted when the active item in the list changes. The
    UI should react to this signal by highlighting the item at \a index in
    the list.
*/
/*!
    \fn void QVirtualKeyboardSelectionListModel::activeItemChanged(int index)

    This signal is emitted when the active item in the list changes. The
    UI should react to this signal by highlighting the item at \a index in
    the list.
*/

/*!
    \qmlsignal void SelectionListModel::itemSelected(int index)

    This signal is emitted when an item at \a index is selected by the user.
*/
/*!
    \fn void QVirtualKeyboardSelectionListModel::itemSelected(int index)

    This signal is emitted when an item at \a index is selected by the user.
*/

QT_END_NAMESPACE
