/*
 * Copyright 2010  Jonas Emanuel Müller <zanoi@zanoi.net>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include "channelmodel.h"

#include <QtSql/QSqlRecord>
#include <QtCore/QModelIndex>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlTableModel>

#include <KDE/KIcon>

namespace Videocatcher {

struct ChannelModel::ChannelModelPrivate
{
    ChannelModelPrivate() 
    {
    }
    QString m_tableName;
    QMap<int, QVariant> m_lastLoading;
};

	ChannelModel::ChannelModel(QObject* parent) : QSqlRelationalTableModel(parent), d(new ChannelModelPrivate())
{
    d->m_tableName = "channels";
    QSqlQuery query(QString("CREATE TABLE IF NOT EXISTS %1 (\
        id INTEGER PRIMARY KEY AUTOINCREMENT,\
        title   TEXT,\
        author  TEXT,\
        url TEXT,\
        path TEXT, \
        website_url TEXT\
        )").arg(d->m_tableName));

    setEditStrategy(QSqlTableModel::OnManualSubmit);
    setTable(d->m_tableName);
    setSort(Channel_Title, Qt::AscendingOrder);
    select();
}

ChannelModel::~ChannelModel()
{
    delete d;
}

QVariant ChannelModel::data(const QModelIndex &index, int role) const
{
    LastLoading lastLoadingResult;

    if(!index.isValid()) {
        return QVariant();
    }

    switch(role)
    {
        case Qt::EditRole:
        case Qt::DisplayRole:
             return QSqlRelationalTableModel::data(index, role);
        case Qt::DecorationRole:
            lastLoadingResult = (LastLoading) d->m_lastLoading.value(index.row(), Last_Loading_Success).toInt();
            if(lastLoadingResult == Last_Loading_Success) {
                return QVariant();
            } else if (lastLoadingResult == Last_Loading_Started) {
                return KIcon("view-refresh");
            } else if (lastLoadingResult == Last_Loading_Failed) {
                return KIcon("process-stop");
            } else {
                return QVariant();
            }
        case LastLoadingRole:
            return d->m_lastLoading.value(index.row());
    }
    return QVariant();
}

bool ChannelModel::setData(const QModelIndex &index, const QVariant &data, int role)
{
    if(!index.isValid()) {
        return false;
    }

    switch(role)
    {
        case LastLoadingRole:
            d->m_lastLoading[index.row()] = data;
        default:
            return QSqlRelationalTableModel::setData(index, data, role);
    }
}


bool ChannelModel::addChannel(const QString &title, const QString &url, const QString &author, const QString &websiteUrl, const QString &directory)
{
    QModelIndex modelIndex;
    
    int row = rowCount();
    bool success = insertRow(row);
    if(!success) {
        return false;
    }

    modelIndex = index(row, Channel_Title);
    setData(modelIndex, title);

    modelIndex = index(row, Channel_Url);
    setData(modelIndex, url);

    modelIndex = index(row, Channel_Path);
    setData(modelIndex, directory);

    modelIndex = index(row, Channel_Author);
    setData(modelIndex, author);

    modelIndex = index(row, Channel_Web_Link);
    setData(modelIndex, websiteUrl);

    return true;
}

QModelIndex ChannelModel::findByTitle(const QString &title) const
{
    QList<QModelIndex> result = match(index(0, Channel_Title), Qt::DisplayRole, title,  1, Qt::MatchExactly);
    return (result.empty() ? QModelIndex() : result.first());
}

QModelIndex ChannelModel::findByUrl(const QString &url) const
{
    QList<QModelIndex> result = match(index(0, Channel_Url), Qt::DisplayRole, url,  1, Qt::MatchExactly);
    return (result.empty() ? QModelIndex() : result.first());
}

QModelIndex ChannelModel::findById(int id) const
{
    QList<QModelIndex> result = match(index(0, Channel_Id), Qt::DisplayRole, id,  1, Qt::MatchExactly);
    return (result.empty() ? QModelIndex() : result.first());
}

QModelIndexList ChannelModel::findAllByTitle(const QString &title) const
{
    return match(index(0, Channel_Title), Qt::DisplayRole, title, -1, Qt::MatchExactly);
}

QModelIndexList ChannelModel::findAllByUrl(const QString &url) const
{
    return match(index(0, Channel_Url), Qt::DisplayRole, url,  -1, Qt::MatchExactly);
}

bool ChannelModel::remove(const QModelIndex &modelIndex)
{
    if (!modelIndex.isValid()) {
        qDebug("invalid model index");
        return false;
    }
    
    bool success = removeRow(modelIndex.row());
    if(!success) {
      qDebug() << "removeRow returned false";
      return false;
    }

    return true;
}

int ChannelModel::id(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Id);
    return data(modelIndex).toInt();
}

QString ChannelModel::title(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Title);
    return data(modelIndex).toString();
}

QString ChannelModel::author(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Author);
    return data(modelIndex).toString();
}

QString ChannelModel::url(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Url);
    return data(modelIndex).toString();
}

QString ChannelModel::path(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Path);
    return data(modelIndex).toString();
}

QString ChannelModel::webLink(const QModelIndex &row) const
{
    QModelIndex modelIndex = index(row.row(), Channel_Web_Link);
    return data(modelIndex).toString();
}

bool ChannelModel::setPath(const QModelIndex &row, const QString &path)
{
    QModelIndex modelIndex = index(row.row(), Channel_Path);
    return setData(modelIndex, path);
}

bool ChannelModel::exists(const QString &url) const
{
    QModelIndex index = findByUrl(url);
    return index.isValid();
}

} //namespace Videocatcher
