/*
    Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
    Copyright (c) 2012 Laurent Montel <montel@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 "recursivecollectionfilterproxymodel.h"

#include "entitytreemodel.h"
#include "mimetypechecker.h"

#include <kdebug.h>

using namespace Akonadi;

namespace Akonadi
{

class RecursiveCollectionFilterProxyModelPrivate
{
  Q_DECLARE_PUBLIC(RecursiveCollectionFilterProxyModel)
  RecursiveCollectionFilterProxyModel *q_ptr;
public:
  RecursiveCollectionFilterProxyModelPrivate(RecursiveCollectionFilterProxyModel *model)
      : q_ptr(model), checkOnlyChecked( false )
  {

  }

  QSet<QString> includedMimeTypes;
  Akonadi::MimeTypeChecker checker;
  QString pattern;
  bool checkOnlyChecked;
};

}

RecursiveCollectionFilterProxyModel::RecursiveCollectionFilterProxyModel( QObject* parent )
    : KRecursiveFilterProxyModel(parent), d_ptr(new RecursiveCollectionFilterProxyModelPrivate( this ) )
{

}

RecursiveCollectionFilterProxyModel::~RecursiveCollectionFilterProxyModel()
{
  delete d_ptr;
}

bool RecursiveCollectionFilterProxyModel::acceptRow( int sourceRow, const QModelIndex &sourceParent ) const
{
  Q_D( const RecursiveCollectionFilterProxyModel );

  const QModelIndex rowIndex = sourceModel()->index( sourceRow, 0, sourceParent );
  const Akonadi::Collection collection = rowIndex.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
  if ( !collection.isValid() )
    return false;
  const bool checked = ( rowIndex.data(Qt::CheckStateRole).toInt()==Qt::Checked );
  const bool isCheckable = sourceModel()->flags( rowIndex ) & Qt::ItemIsUserCheckable;
  if ( isCheckable && (d->checkOnlyChecked && !checked) ) {
    return false;
  }

  const bool collectionWanted =  d->checker.isWantedCollection( collection );
  if ( collectionWanted )
  {
    if (  !d->pattern.isEmpty() ) {
      const QString text = rowIndex.data(Qt::DisplayRole).toString();
      return text.contains( d->pattern, Qt::CaseInsensitive );
    }
  }
  return collectionWanted;
}

void RecursiveCollectionFilterProxyModel::addContentMimeTypeInclusionFilter(const QString& mimeType)
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->includedMimeTypes << mimeType;
  d->checker.setWantedMimeTypes( d->includedMimeTypes.toList() );
  invalidateFilter();
}

void RecursiveCollectionFilterProxyModel::addContentMimeTypeInclusionFilters(const QStringList& mimeTypes)
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->includedMimeTypes.unite(mimeTypes.toSet());
  d->checker.setWantedMimeTypes( d->includedMimeTypes.toList() );
  invalidateFilter();
}

void RecursiveCollectionFilterProxyModel::clearFilters()
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->includedMimeTypes.clear();
  d->checker.setWantedMimeTypes( QStringList() );
  invalidateFilter();
}

void RecursiveCollectionFilterProxyModel::setContentMimeTypeInclusionFilters(const QStringList& mimeTypes)
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->includedMimeTypes = mimeTypes.toSet();
  d->checker.setWantedMimeTypes( d->includedMimeTypes.toList() );
  invalidateFilter();
}

QStringList RecursiveCollectionFilterProxyModel::contentMimeTypeInclusionFilters() const
{
  Q_D(const RecursiveCollectionFilterProxyModel);
  return d->includedMimeTypes.toList();
}

int Akonadi::RecursiveCollectionFilterProxyModel::columnCount( const QModelIndex& index ) const
{
  // Optimization: we know that we're not changing the number of columns, so skip QSortFilterProxyModel
  return sourceModel()->columnCount( mapToSource( index ) );
}

void Akonadi::RecursiveCollectionFilterProxyModel::setSearchPattern( const QString &pattern )
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->pattern = pattern;
  invalidate();
}

void Akonadi::RecursiveCollectionFilterProxyModel::setIncludeCheckedOnly( bool checked )
{
  Q_D(RecursiveCollectionFilterProxyModel);
  d->checkOnlyChecked = checked;
  invalidate();
}
