/*
    Copyright (c) 2006 Volker Krause <vkrause@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 as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    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 "collectionstatisticsmodel.h"

#include "collection.h"
#include "collectionmodel_p.h"
#include "collectionstatistics.h"

#include <kdebug.h>
#include <KGlobal>
#include <klocale.h>
#include <klocalizedstring.h>


using namespace Akonadi;

namespace Akonadi {

class CollectionStatisticsModelPrivate : public CollectionModelPrivate
{
  public:
    enum CountType { Total, Unread, Size };
    Q_DECLARE_PUBLIC( CollectionStatisticsModel )
    CollectionStatisticsModelPrivate( CollectionStatisticsModel *parent )
        : CollectionModelPrivate( parent )
    {}

    qint64 countRecursive( Collection::Id collection, CountType type ) const;
};

}

qint64 CollectionStatisticsModelPrivate::countRecursive( Collection::Id collection,
                                                         CountType type ) const
{
  qint64 result = -1;
  switch ( type ) {
    case Unread: result = collections.value( collection ).statistics().unreadCount();
                 break;
    case Total: result = collections.value( collection ).statistics().count();
                break;
    case Size: result = collections.value( collection ).statistics().size();
                break;
    default: Q_ASSERT( false );
             break;
  }

  const QVector<Collection::Id> children = childCollections.value( collection );
  foreach ( Collection::Id currentCollection, children ) {
    result += countRecursive( currentCollection, type );
  }
  return result;
}

CollectionStatisticsModel::CollectionStatisticsModel( QObject * parent ) :
    CollectionModel( new CollectionStatisticsModelPrivate( this ), parent )
{
  fetchCollectionStatistics( true );
}

int CollectionStatisticsModel::columnCount( const QModelIndex & parent ) const
{
  if ( parent.isValid() && parent.column() != 0 ) {
    return 0;
  }
  return 4;
}

QVariant CollectionStatisticsModel::data( const QModelIndex & index, int role ) const
{
  Q_D( const CollectionStatisticsModel );
  if ( !index.isValid() ) {
    return QVariant();
  }

  Collection col = collectionForId( CollectionModel::data( index, CollectionIdRole ).toLongLong() );
  if ( !col.isValid() ) {
    return QVariant();
  }
  CollectionStatistics statistics = col.statistics();

  qint64 total = statistics.count();
  qint64 unread = statistics.unreadCount();
  qint64 size = statistics.size();
  qint64 totalRecursive = d->countRecursive( col.id(),
                                             CollectionStatisticsModelPrivate::Total );
  qint64 unreadRecursive = d->countRecursive( col.id(),
                                              CollectionStatisticsModelPrivate::Unread );
  qint64 sizeRecursive = d->countRecursive( col.id(),
                                            CollectionStatisticsModelPrivate::Size );

  if ( role == TotalRole ) {
    return total;
  } else if ( role == UnreadRole ) {
    return unread;
  } else if ( role == SizeRole ) {
    return size;
  } else if ( role == RecursiveUnreadRole ) {
    return unreadRecursive;
  } else if ( role == RecursiveTotalRole ) {
    return totalRecursive;
  } else if ( role == RecursiveSizeRole ) {
    return sizeRecursive;
  } else if ( role == StatisticsRole ) {
    QVariant var;
    var.setValue( statistics );
    return var;
  } else if ( role == RecursiveStatisticsRole ) {
    QVariant var;
    var.setValue( statistics ); //FIXME:(tmg) returns a recursive statistic object here
    return var;
  }

  if ( role == Qt::DisplayRole &&
       ( index.column() == 1 || index.column() == 2 || index.column() == 3 ) ) {

    qint64 value = -1;
    switch ( index.column() ) {
      case 1 : value = unread; break;
      case 2 : value = total; break;
      case 3 : value = size; break;
    }
    if ( value < 0 ) {
      return QString();
    } else if ( value == 0 ) {
      return QLatin1String( "-" );
    } else if ( index.column() == 3 ) {
      return KGlobal::locale()->formatByteSize( value );
    } else {
      return QString::number( value );
    }
  }

  if ( role == Qt::TextAlignmentRole && ( index.column() == 1 || index.column() == 2 || index.column() == 3 ) ) {
    return Qt::AlignRight;
  }

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

QVariant CollectionStatisticsModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
  if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) {
    switch ( section ) {
      case 1: return i18nc( "@title:column, number of unread messages", "Unread" );
      case 2: return i18nc( "@title:column, total number of messages", "Total" );
      case 3: return i18nc( "@title:column, total size (in bytes) of the collection", "Size" );
    }
  }

  return CollectionModel::headerData( section, orientation, role );
}

