/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */

#include "searchhitmodel.h"

#include <QtCore/QUrl>
#include <QtCore/QList>

#include <nepomuk/resource.h>
#include <nepomuk/class.h>

#include <kcategorizedsortfilterproxymodel.h>
#include <KLocale>
#include <KDebug>
#include <KUrl>

#include <Soprano/Vocabulary/RDFS>


class Nepomuk::SearchHitModel::Private
{
public:
    QList<Nepomuk::Search::Result> resources;
};


Nepomuk::SearchHitModel::SearchHitModel( QObject* parent )
    : ResourceModel( parent ),
      d( new Private() )
{
}


Nepomuk::SearchHitModel::~SearchHitModel()
{
    delete d;
}


QModelIndex Nepomuk::SearchHitModel::indexForResource( const QUrl& uri ) const
{
    Q_ASSERT( uri.isValid() );
    // FIXME: performance
    int i = 0;
    QList<Search::Result>::const_iterator end = d->resources.constEnd();
    for ( QList<Search::Result>::const_iterator it = d->resources.constBegin(); it != end; ++it ) {
        if ( it->resourceUri() == uri ) {
            return index( i, 0 );
        }
        ++i;
    }

    return QModelIndex();
}


QUrl Nepomuk::SearchHitModel::resourceForIndex( const QModelIndex& index ) const
{
    if ( index.isValid() && index.row() < d->resources.count() ) {
        return d->resources[index.row()].resourceUri();
    }
    else {
        return QUrl();
    }
}


double Nepomuk::SearchHitModel::scoreForIndex( const QModelIndex& index ) const
{
    if ( index.isValid() && index.row() < d->resources.count() ) {
        return d->resources[index.row()].score();
    }
    else {
        return 0.0;
    }
}


int Nepomuk::SearchHitModel::rowCount( const QModelIndex& parent ) const
{
    if ( parent.isValid() ) {
        return 0;
    }
    else {
        return d->resources.count();
    }
}


QModelIndex Nepomuk::SearchHitModel::index( int row, int column, const QModelIndex& parent ) const
{
    if ( row < rowCount( parent ) && column == 0 ) {
        return createIndex( row, column, 0 );
    }
    else {
        return QModelIndex();
    }
}


QVariant Nepomuk::SearchHitModel::data( const QModelIndex& index, int role ) const
{
    if ( index.row() < 0 || index.row() >= d->resources.count() ) {
        kDebug() << "Invalid index:" << index;
        return QVariant();
    }

    switch( role ) {
    case Qt::ToolTipRole:
        return KUrl( resourceForIndex( index ) ).prettyUrl();

    case ResourceRole:
        return resourceForIndex( index );

    case ScoreRole:
        return scoreForIndex( index );

    case KCategorizedSortFilterProxyModel::CategorySortRole:
        // FIXME: sort files before other stuff and so on

    case KCategorizedSortFilterProxyModel::CategoryDisplayRole: {
        QUrl url = resourceForIndex( index );
        Q_ASSERT( !url.isEmpty() );
        Nepomuk::Resource res( url );
        Q_ASSERT( !res.resourceType().isEmpty() );
        Nepomuk::Types::Class c( res.resourceType() );
        QString cat = c.label();
        if ( cat.isEmpty() ) {
            cat = c.name();
        }
        if ( c.uri() == Soprano::Vocabulary::RDFS::Resource() || cat.isEmpty() ) {
            cat = i18n( "Miscellaneous" );
        }

        return cat;
    }
    }

    return ResourceModel::data( index, role );
}


void Nepomuk::SearchHitModel::setResources( const QList<Search::Result>& resources )
{
    d->resources = resources;
    reset();
}


void Nepomuk::SearchHitModel::updateResource( const Search::Result& resource )
{
    Q_ASSERT( resource.resourceUri().isValid() );

    for ( int i = 0; i < d->resources.count(); ++i ) {
        if ( d->resources[i].resourceUri() == resource.resourceUri() ) {
            d->resources[i].setScore( resource.score() );
            emit dataChanged( index( i, 1 ), index( i, 1 ) );
            return;
        }
    }

    // new value
    beginInsertRows( QModelIndex(), d->resources.count(), d->resources.count() );
    d->resources.append( resource );
    endInsertRows();
}

#include "searchhitmodel.moc"
