/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module 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$
**
****************************************************************************/

/*
    A simple model that uses a QStringList as its data source.
*/

#include "qstringlistmodel.h"

#include <QtCore/qvector.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
    \class QStringListModel
    \inmodule QtCore
    \brief The QStringListModel class provides a model that supplies strings to views.

    \ingroup model-view

    QStringListModel is an editable model that can be used for simple
    cases where you need to display a number of strings in a view
    widget, such as a QListView or a QComboBox.

    The model provides all the standard functions of an editable
    model, representing the data in the string list as a model with
    one column and a number of rows equal to the number of items in
    the list.

    Model indexes corresponding to items are obtained with the
    \l{QAbstractListModel::index()}{index()} function, and item flags
    are obtained with flags().  Item data is read with the data()
    function and written with setData().  The number of rows (and
    number of items in the string list) can be found with the
    rowCount() function.

    The model can be constructed with an existing string list, or
    strings can be set later with the setStringList() convenience
    function. Strings can also be inserted in the usual way with the
    insertRows() function, and removed with removeRows(). The contents
    of the string list can be retrieved with the stringList()
    convenience function.

    An example usage of QStringListModel:

    \snippet qstringlistmodel/main.cpp 0

    \sa QAbstractListModel, QAbstractItemModel, {Model Classes}
*/

/*!
    Constructs a string list model with the given \a parent.
*/

QStringListModel::QStringListModel(QObject *parent)
    : QAbstractListModel(parent)
{
}

/*!
    Constructs a string list model containing the specified \a strings
    with the given \a parent.
*/

QStringListModel::QStringListModel(const QStringList &strings, QObject *parent)
    : QAbstractListModel(parent), lst(strings)
{
}

/*!
    Returns the number of rows in the model. This value corresponds to the
    number of items in the model's internal string list.

    The optional \a parent argument is in most models used to specify
    the parent of the rows to be counted. Because this is a list if a
    valid parent is specified, the result will always be 0.

    \sa insertRows(), removeRows(), QAbstractItemModel::rowCount()
*/

int QStringListModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return lst.count();
}

/*!
  \reimp
*/
QModelIndex QStringListModel::sibling(int row, int column, const QModelIndex &idx) const
{
    if (!idx.isValid() || column != 0 || row >= lst.count() || row < 0)
        return QModelIndex();

    return createIndex(row, 0);
}

/*!
  \reimp
  \since 5.13
*/
QMap<int, QVariant> QStringListModel::itemData(const QModelIndex &index) const
{
    if (!checkIndex(index, CheckIndexOption::IndexIsValid | CheckIndexOption::ParentIsInvalid))
        return QMap<int, QVariant>{};
    const QVariant displayData = lst.at(index.row());
    return QMap<int, QVariant>{{
        std::make_pair<int>(Qt::DisplayRole, displayData),
        std::make_pair<int>(Qt::EditRole, displayData)
    }};
}

/*!
  \reimp
  \since 5.13
  If \a roles contains both Qt::DisplayRole and Qt::EditRole, the latter will take precedence
*/
bool QStringListModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
{
    if (roles.isEmpty())
        return false;
    if (std::any_of(roles.keyBegin(), roles.keyEnd(), [](int role) -> bool {
        return role != Qt::DisplayRole && role != Qt::EditRole;
    })) {
        return false;
    }
    auto roleIter = roles.constFind(Qt::EditRole);
    if (roleIter == roles.constEnd())
        roleIter = roles.constFind(Qt::DisplayRole);
    Q_ASSERT(roleIter != roles.constEnd());
    return setData(index, roleIter.value(), roleIter.key());
}

/*!
    Returns data for the specified \a role, from the item with the
    given \a index.

    If the view requests an invalid index, an invalid variant is returned.

    \sa setData()
*/

QVariant QStringListModel::data(const QModelIndex &index, int role) const
{
    if (index.row() < 0 || index.row() >= lst.size())
        return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole)
        return lst.at(index.row());

    return QVariant();
}

/*!
    Returns the flags for the item with the given \a index.

    Valid items are enabled, selectable, editable, drag enabled and drop enabled.

    \sa QAbstractItemModel::flags()
*/

Qt::ItemFlags QStringListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return QAbstractListModel::flags(index) | Qt::ItemIsDropEnabled;

    return QAbstractListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}

/*!
    Sets the data for the specified \a role in the item with the given
    \a index in the model, to the provided \a value.

    The dataChanged() signal is emitted if the item is changed.
    Returns \c true after emitting the dataChanged() signal.

    \sa Qt::ItemDataRole, data()
*/

bool QStringListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (index.row() >= 0 && index.row() < lst.size()
        && (role == Qt::EditRole || role == Qt::DisplayRole)) {
        const QString valueString = value.toString();
        if (lst.at(index.row()) == valueString)
            return true;
        lst.replace(index.row(), valueString);
        emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
        return true;
    }
    return false;
}

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
    \reimp
    \since 6.0
 */
bool QStringListModel::clearItemData(const QModelIndex &index)
{
    return setData(index, QVariant(), Qt::EditRole);
}
#endif

/*!
    Inserts \a count rows into the model, beginning at the given \a row.

    The \a parent index of the rows is optional and is only used for
    consistency with QAbstractItemModel. By default, a null index is
    specified, indicating that the rows are inserted in the top level of
    the model.

    Returns \c true if the insertion was successful.

    \sa QAbstractItemModel::insertRows()
*/

bool QStringListModel::insertRows(int row, int count, const QModelIndex &parent)
{
    if (count < 1 || row < 0 || row > rowCount(parent))
        return false;

    beginInsertRows(QModelIndex(), row, row + count - 1);

    for (int r = 0; r < count; ++r)
        lst.insert(row, QString());

    endInsertRows();

    return true;
}

/*!
    Removes \a count rows from the model, beginning at the given \a row.

    The \a parent index of the rows is optional and is only used for
    consistency with QAbstractItemModel. By default, a null index is
    specified, indicating that the rows are removed in the top level of
    the model.

    Returns \c true if the row removal was successful.

    \sa QAbstractItemModel::removeRows()
*/

bool QStringListModel::removeRows(int row, int count, const QModelIndex &parent)
{
    if (count <= 0 || row < 0 || (row + count) > rowCount(parent))
        return false;

    beginRemoveRows(QModelIndex(), row, row + count - 1);

    const auto it = lst.begin() + row;
    lst.erase(it, it + count);

    endRemoveRows();

    return true;
}

/*!
    \since 5.13
    \reimp
*/
bool QStringListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
{
    if (sourceRow < 0
        || sourceRow + count - 1 >= rowCount(sourceParent)
        || destinationChild <= 0
        || destinationChild > rowCount(destinationParent)
        || sourceRow == destinationChild - 1
        || count <= 0) {
        return false;
    }
    if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild))
        return false;
    /*
    QList::move assumes that the second argument is the index where the item will end up to
    i.e. the valid range for that argument is from 0 to QList::size()-1
    QAbstractItemModel::moveRows when source and destinations have the same parent assumes that
    the item will end up being in the row BEFORE the one indicated by destinationChild
    i.e. the valid range for that argument is from 1 to QList::size()
    For this reason we remove 1 from destinationChild when using it inside QList
    */
    destinationChild--;
    const int fromRow = destinationChild < sourceRow ? (sourceRow + count - 1) : sourceRow;
    while (count--)
        lst.move(fromRow, destinationChild);
    endMoveRows();
    return true;
}

static bool ascendingLessThan(const QPair<QString, int> &s1, const QPair<QString, int> &s2)
{
    return s1.first < s2.first;
}

static bool decendingLessThan(const QPair<QString, int> &s1, const QPair<QString, int> &s2)
{
    return s1.first > s2.first;
}

/*!
  \reimp
*/
void QStringListModel::sort(int, Qt::SortOrder order)
{
    emit layoutAboutToBeChanged(QList<QPersistentModelIndex>(), VerticalSortHint);

    QVector<QPair<QString, int> > list;
    const int lstCount = lst.count();
    list.reserve(lstCount);
    for (int i = 0; i < lstCount; ++i)
        list.append(QPair<QString, int>(lst.at(i), i));

    if (order == Qt::AscendingOrder)
        std::sort(list.begin(), list.end(), ascendingLessThan);
    else
        std::sort(list.begin(), list.end(), decendingLessThan);

    lst.clear();
    QVector<int> forwarding(lstCount);
    for (int i = 0; i < lstCount; ++i) {
        lst.append(list.at(i).first);
        forwarding[list.at(i).second] = i;
    }

    QModelIndexList oldList = persistentIndexList();
    QModelIndexList newList;
    const int numOldIndexes = oldList.count();
    newList.reserve(numOldIndexes);
    for (int i = 0; i < numOldIndexes; ++i)
        newList.append(index(forwarding.at(oldList.at(i).row()), 0));
    changePersistentIndexList(oldList, newList);

    emit layoutChanged(QList<QPersistentModelIndex>(), VerticalSortHint);
}

/*!
    Returns the string list used by the model to store data.
*/
QStringList QStringListModel::stringList() const
{
    return lst;
}

/*!
    Sets the model's internal string list to \a strings. The model will
    notify any attached views that its underlying data has changed.

    \sa dataChanged()
*/
void QStringListModel::setStringList(const QStringList &strings)
{
    beginResetModel();
    lst = strings;
    endResetModel();
}

/*!
  \reimp
*/
Qt::DropActions QStringListModel::supportedDropActions() const
{
    return QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
}

QT_END_NAMESPACE

#include "moc_qstringlistmodel.cpp"
