/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativeplacecontentmodel_p.h"
#include "qdeclarativeplace_p.h"
#include "qdeclarativegeoserviceprovider_p.h"
#include "qdeclarativeplaceuser_p.h"
#include "error_messages_p.h"

#include <QtQml/QQmlInfo>
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QPlaceManager>
#include <QtLocation/QPlaceContentRequest>

QT_BEGIN_NAMESPACE

QDeclarativePlaceContentModel::QDeclarativePlaceContentModel(QPlaceContent::Type type,
                                                             QObject *parent)
:   QAbstractListModel(parent), m_place(0), m_type(type), m_batchSize(1), m_contentCount(-1),
    m_reply(0), m_complete(false)
{
}

QDeclarativePlaceContentModel::~QDeclarativePlaceContentModel()
{
}

/*!
    \internal
*/
QDeclarativePlace *QDeclarativePlaceContentModel::place() const
{
    return m_place;
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::setPlace(QDeclarativePlace *place)
{
    if (m_place != place) {
        beginResetModel();

        int initialCount = m_contentCount;
        clearData();
        m_place = place;
        endResetModel();

        emit placeChanged();
        if (initialCount != -1)
            emit totalCountChanged();

        fetchMore(QModelIndex());
    }
}

/*!
    \internal
*/
int QDeclarativePlaceContentModel::batchSize() const
{
    return m_batchSize;
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::setBatchSize(int batchSize)
{
    if (m_batchSize != batchSize) {
        m_batchSize = batchSize;
        emit batchSizeChanged();
    }
}

/*!
    \internal
*/
int QDeclarativePlaceContentModel::totalCount() const
{
    return m_contentCount;
}

/*!
    \internal
    Clears the model data but does not reset it.
*/
void QDeclarativePlaceContentModel::clearData()
{
    qDeleteAll(m_users);
    m_users.clear();

    qDeleteAll(m_suppliers);
    m_suppliers.clear();

    m_content.clear();

    m_contentCount = -1;

    if (m_reply) {
        m_reply->abort();
        m_reply->deleteLater();
        m_reply = 0;
    }

    m_nextRequest.clear();
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::initializeCollection(int totalCount, const QPlaceContent::Collection &collection)
{
    beginResetModel();

    int initialCount = m_contentCount;
    clearData();

    for (auto i = collection.cbegin(), end = collection.cend(); i != end; ++i) {
        const QPlaceContent &content = i.value();
        if (content.type() != m_type)
            continue;

        m_content.insert(i.key(), content);
        if (!m_suppliers.contains(content.supplier().supplierId())) {
            m_suppliers.insert(content.supplier().supplierId(),
                               new QDeclarativeSupplier(content.supplier(), m_place->plugin(), this));
        }
        if (!m_users.contains(content.user().userId())) {
            m_users.insert(content.user().userId(),
                               new QDeclarativePlaceUser(content.user(), this));
        }
    }

    m_contentCount = totalCount;

    if (initialCount != totalCount)
        emit totalCountChanged();

    endResetModel();
}

/*!
    \internal
*/
int QDeclarativePlaceContentModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return m_content.count();
}

/*!
    \internal
*/
QVariant QDeclarativePlaceContentModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (index.row() >= rowCount(index.parent()) || index.row() < 0)
        return QVariant();

    const QPlaceContent &content = m_content.value(index.row());

    switch (role) {
    case SupplierRole:
        return QVariant::fromValue(static_cast<QObject *>(m_suppliers.value(content.supplier().supplierId())));
    case PlaceUserRole:
        return QVariant::fromValue(static_cast<QObject *>(m_users.value(content.user().userId())));
    case AttributionRole:
        return content.attribution();
    default:
        return QVariant();
    }
}

QHash<int, QByteArray> QDeclarativePlaceContentModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
    roles.insert(SupplierRole, "supplier");
    roles.insert(PlaceUserRole, "user");
    roles.insert(AttributionRole, "attribution");
    return roles;
}

/*!
    \internal
*/
bool QDeclarativePlaceContentModel::canFetchMore(const QModelIndex &parent) const
{
    if (parent.isValid())
        return false;

    if (!m_place)
        return false;

    if (m_contentCount == -1)
        return true;

    return m_content.count() != m_contentCount;
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::fetchMore(const QModelIndex &parent)
{
    if (parent.isValid())
        return;

    if (!m_place)
        return;

    if (m_reply)
        return;

    if (!m_place->plugin())
        return;

    QDeclarativeGeoServiceProvider *plugin = m_place->plugin();

    QGeoServiceProvider *serviceProvider = plugin->sharedGeoServiceProvider();
    if (!serviceProvider)
        return;

    QPlaceManager *placeManager = serviceProvider->placeManager();
    if (!placeManager)
        return;

    if (m_nextRequest == QPlaceContentRequest()) {
        QPlaceContentRequest request;
        request.setContentType(m_type);
        request.setPlaceId(m_place->place().placeId());
        request.setLimit(m_batchSize);

        m_reply = placeManager->getPlaceContent(request);
    } else {
        m_reply = placeManager->getPlaceContent(m_nextRequest);
    }

    connect(m_reply, SIGNAL(finished()), this, SLOT(fetchFinished()), Qt::QueuedConnection);
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::classBegin()
{
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::componentComplete()
{
    m_complete = true;
    fetchMore(QModelIndex());
}

/*!
    \internal
*/
void QDeclarativePlaceContentModel::fetchFinished()
{
    if (!m_reply)
        return;

    QPlaceContentReply *reply = m_reply;
    m_reply = 0;

    m_nextRequest = reply->nextPageRequest();

    if (m_contentCount != reply->totalCount()) {
        m_contentCount = reply->totalCount();
        emit totalCountChanged();
    }

    if (!reply->content().isEmpty()) {
        QPlaceContent::Collection contents = reply->content();

        //find out which indexes are new and which ones have changed.
        QList<int> changedIndexes;
        QList<int> newIndexes;
        for (auto it = contents.cbegin(), end = contents.cend(); it != end; ++it) {
            if (!m_content.contains(it.key()))
                newIndexes.append(it.key());
            else if (it.value() != m_content.value(it.key()))
                changedIndexes.append(it.key());
        }

        //insert new indexes in blocks where within each
        //block, the indexes are consecutive.
        int startIndex = -1;
        for (auto it = newIndexes.cbegin(), end = newIndexes.cend(); it != end; ++it) {
            int currentIndex = *it;
            if (startIndex == -1)
                startIndex = currentIndex;

            auto next = std::next(it);
            if (next == end || *next > (currentIndex + 1)) {
                beginInsertRows(QModelIndex(),startIndex,currentIndex);
                for (int i = startIndex; i <= currentIndex; ++i) {
                    const QPlaceContent &content = contents.value(i);

                    m_content.insert(i, content);
                    if (!m_suppliers.contains(content.supplier().supplierId())) {
                        m_suppliers.insert(content.supplier().supplierId(),
                                           new QDeclarativeSupplier(content.supplier(), m_place->plugin(), this));
                    }
                    if (!m_users.contains(content.user().userId())) {
                        m_users.insert(content.user().userId(),
                                           new QDeclarativePlaceUser(content.user(), this));
                    }
                }
                endInsertRows();
                startIndex = -1;
            }
        }

        //modify changed indexes in blocks where within each
        //block, the indexes are consecutive.
        startIndex = -1;
        for (auto it = changedIndexes.cbegin(), end = changedIndexes.cend(); it != end; ++it) {
            int currentIndex = *it;
            if (startIndex == -1)
                startIndex = currentIndex;

            auto next = std::next(it);
            if (next == end || *next > (currentIndex + 1)) {
                for (int i = startIndex; i <= currentIndex; ++i) {
                    const QPlaceContent &content = contents.value(i);
                    m_content.insert(i, content);
                    if (!m_suppliers.contains(content.supplier().supplierId())) {
                        m_suppliers.insert(content.supplier().supplierId(),
                                           new QDeclarativeSupplier(content.supplier(), m_place->plugin(), this));
                    }
                    if (!m_users.contains(content.user().userId())) {
                        m_users.insert(content.user().userId(),
                                           new QDeclarativePlaceUser(content.user(), this));
                    }
                }
                emit dataChanged(index(startIndex),index(currentIndex));
                startIndex = -1;
            }
        }

        // The fetch didn't add any new content and we haven't fetched all content yet. This is
        // likely due to the model being prepopulated by Place::getDetails(). Keep fetching more
        // data until new content is available.
        if (newIndexes.isEmpty() && m_content.count() != m_contentCount)
            fetchMore(QModelIndex());
    }

    reply->deleteLater();
}

QT_END_NAMESPACE
