//
// C++ Implementation: unselectedtagsview
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "unselectedtagsview.h"

#include <cassert>

#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>
#include <QDebug>

// NTagModel
#include "debtagsplugincontainer.h"
#include "vocabularymodelrole.h"
#include "emptytagfilter.h"

#include "treefiltermodel.h"
#ifdef __DEBUG
#	include <modeltest.h>
#endif
#include <helpers.h>




namespace NTagModel
{

/** @brief A filter which accepts all facets and tags only if they match the active filter.
  *
  *
  * @author Benjamin Mesing
  */
class TextFilter : public QSortFilterProxyModel
{ 
public:
	TextFilter(QObject * pParent = 0) : QSortFilterProxyModel(pParent)
	{}
	virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
	{
		// if we have a facet (i.e. a root item)
		if (!sourceParent.isValid()) {
			return true;
		}
		return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
	}
};

UnselectedTagsView::UnselectedTagsView(const NPlugin::DebtagsPluginContainer* pContainer, QWidget * parent)
 : QTreeView(parent), _filterSelectedProxyModel(false, this), _hiddenFilterProxyModel(false, this)
{
	connect(this, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(onItemDoubleClicked(const QModelIndex&)));
	
	// build up ProxyModel/Filter chain -> see class documentation for the order of the chain
	_hiddenFilterProxyModel.setDynamicSortFilter(true);

	_pTagFilter = new EmptyTagFilter(pContainer->vocabularyModel(), pContainer->xapian(), this);
	_pTagFilter->setDynamicSortFilter(true);

	_filterSelectedProxyModel.setDynamicSortFilter(true);
	
	
	_pTextFilter = new TextFilter(this);
	_pTextFilter->setFilterKeyColumn(-1);
	_pTextFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
	_pTextFilter->setDynamicSortFilter(true);
	
// TODO _ commented for debugging
	_filterChain.push_back(&_hiddenFilterProxyModel);
 	_filterChain.push_back(_pTagFilter);
  	_filterChain.push_back(&_filterSelectedProxyModel);
 	_filterChain.push_back(_pTextFilter);
	QSortFilterProxyModel* pTreeFilter = new TreeFilterModel(this);
	pTreeFilter->setDynamicSortFilter(true);
	_filterChain.push_back(pTreeFilter);
 	
 	vector<QAbstractProxyModel*>::iterator it = _filterChain.begin();
 	vector<QAbstractProxyModel*>::iterator oldIt = _filterChain.begin();
 	++it;
 	for (; it != _filterChain.end(); ++it )
 	{
 		(*it)->setSourceModel(*oldIt);
 		oldIt = it;
 	}
 	setToolTip(tr("select a tag by double-clicking"));
 	setWhatsThis(tr("This list shows the tags that can be searched for. "
 		"The tags are organised in a tree beneath their facets (groups of tags). "
 		"To search for packages with a tag, double-click the tag. Multiple tags can be selected like this. Facets cannot be selected."));
}


UnselectedTagsView::~UnselectedTagsView()
{
}


void UnselectedTagsView::setModel(QAbstractItemModel* pModel)
{
	_pDataModel = pModel;
	_filterChain.front()->setSourceModel(pModel);
#ifdef __DEBUG
// this is for debugging purposes, Modeltest are some really convenient classes to 
// detect problems in ones model
//	for (	vector<QAbstractProxyModel*>::iterator it = _filterChain.begin(); it != _filterChain.end(); ++it )
//	{
//  		new ModelTest(*it, this);
//	}
#endif
 	QTreeView::setModel(_filterChain.back());
 	resizeColumnToContents(0);
}


void UnselectedTagsView::onItemDoubleClicked(const QModelIndex& index )
{
	//_pDataModel->setData(_pTextFilter->mapToSource(index), true, SelectedRole);
	model()->setData(index, true, SelectedRole);
}

void UnselectedTagsView::contextMenuEvent(QContextMenuEvent* pEvent)
{
	QMenu menu(this);
	QModelIndex index = indexAt(pEvent->pos());
	QAction* pSelectAsWanted = 0;
	// if the context menu was requested for a tag
	if ( index.isValid() && (model()->data(index, TypeRole).toInt() == TagTypeItem) )
	{
		pSelectAsWanted = menu.addAction(tr("Add"));
	// not yet
	// 	QAction* pSelectAsUnwanted = menu.addAction("Select as unwanted");
	}
	menu.addSeparator();
	QAction* pCollapseAll = menu.addAction(tr("Collapse all"));
	QAction* pExpandAll = menu.addAction(tr("Expand all"));
	QAction* pAction = menu.exec(pEvent->globalPos());
	if (pAction)
	{
		if (pAction == pCollapseAll)
			collapseAll();
		else if  (pAction == pExpandAll)
			expandAll();
		else if  (pAction == pSelectAsWanted)
		// the index is definitely valid here
			model()->setData(index, true, SelectedRole);
	}
}


void UnselectedTagsView::setFilterFixedString(const QString& string)
{
	_pTextFilter->setFilterFixedString(string);
	// invalidate the TextFilter, so that the following filters are reevaluated.
	// This is required, because the TreeFilter changes depending on the tags in the filter
	_pTextFilter->invalidate();
}

}

