/**************************************************************************
** Piperka Client
** Copyright (C) 2019  Kari Pahula
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License along
** with this program; if not, write to the Free Software Foundation, Inc.,
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
**************************************************************************/

#include <QtNetwork/QNetworkReply>
#include <QJsonDocument>

#include "browse.h"
#include "sortmanager.h"

BrowseModel::BrowseModel(const SortManager &mgr, QObject *parent)
    : QSortFilterProxyModel(parent)
    , m_mgr(mgr)
{
    sort(0);
}

void BrowseModel::setFilterSubscribed(bool filter)
{
    if (filter != m_filterSubscribed) {
        m_filterSubscribed = filter;
        sort(0);
        invalidateFilter();
        invalidate();
        emit filterSubscribedChanged();
    }
}

void BrowseModel::setSortType(int sortType)
{
    if (sortType == m_sortType) {
        return;
    } else if (sortType == 0 || sortType == 2) {
        m_sortType = sortType;
        emit sortTypeChanged();
        sort(0);
        invalidateFilter();
        invalidate();
    } else if (sortType == 1 || sortType == 3) {
        emit sortTypeChangePrepare(sortType);
    }
}

void BrowseModel::setSearch(const QString &search)
{
    m_search = search;
    invalidateFilter();
}

void BrowseModel::setSource(QAbstractItemModel *model)
{
    connect(model, &QAbstractItemModel::rowsInserted,
            this, &QSortFilterProxyModel::invalidate);
    setSourceModel(model);
}

void BrowseModel::sortDownloaded(const int &sortType, const QJsonDocument &doc)
{
    Q_UNUSED(doc);
    m_sortType = sortType;
    emit sortTypeChanged();
    invalidateFilter();
    invalidate();
}

bool BrowseModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    QVariant subs = sourceModel()->data(index, ComicModel::SubscribedRole);
    if (!subs.isValid()) {
        return false;
    }
    if (!m_search.isEmpty()) {
        QString title = sourceModel()->data(index, ComicModel::TitleRole).toString().toLower();
        if (!title.contains(m_search.toLower()))
            return false;
    }
    if (m_filterSubscribed)
        return subs.toBool();
    return true;
}

bool BrowseModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
    int cid1;
    int cid2;
    const QHash<int, int> *target = NULL;
    switch (m_sortType) {
    case 2:
        cid1 = sourceModel()->data(source_left, ComicModel::CidRole).toInt();
        cid2 = sourceModel()->data(source_right, ComicModel::CidRole).toInt();
        return (cid1 > cid2);
    case 1:
        target = &m_mgr.sortPopular();
        break;
    case 3:
        target = &m_mgr.sortUpdated();
        break;
    }
    if (target) {
        cid1 = sourceModel()->data(source_left, ComicModel::CidRole).toInt();
        cid2 = sourceModel()->data(source_right, ComicModel::CidRole).toInt();
        int prio1 = target->value(cid1);
        int prio2 = target->value(cid2);
        if (prio1 != prio2)
            return prio1 > prio2;
        // Default to ordering from the server
    }
    return sourceModel()->data(source_left, ComicModel::NativeOrderRole).toInt() <
            sourceModel()->data(source_right, ComicModel::NativeOrderRole).toInt();
}
