/*
 * TagTreeModel.cpp
 *
 *  Created on: 22.10.2009
 *      Author: stefan.detter
 */

#include "TagTreeModel.h"
#include <QFont>

#include "../data/RootItem.h"
#include "../data/ReaderEntry.h"
#include "../data/TagEntry.h"


TagTreeModel::TagTreeModel(QObject* parent)
	: QAbstractItemModel(parent)
{
	m_selected = m_rootItem = new RootItem();

	connect(m_rootItem, SIGNAL(beginInsertRows(TreeItem*,int,int)),
			this, 		SLOT(itemBeginInsertRows(TreeItem*,int,int)) );

	connect(m_rootItem, SIGNAL(endInsertRows()),
			this, 		SLOT(itemendInsertRows()) );

	connect(m_rootItem, SIGNAL(beginRemoveRows(TreeItem*,int,int)),
			this, 		SLOT(itemBeginRemoveRows(TreeItem*,int,int)) );

	connect(m_rootItem, SIGNAL(endRemoveRows()),
			this, 		SLOT(itemEndRemoveRows()) );

	connect(m_rootItem, SIGNAL(requestToExpand(TreeItem*)),
			this, 		SLOT(itemRequestsToExpand(TreeItem*)) );

	connect(m_rootItem, SIGNAL(dataChanged(TreeItem*,int,int)),
			this, 		SLOT(itemDataChanged(TreeItem*,int,int)) );

	connect(m_rootItem, SIGNAL(aboutToBeRemoved(TreeItem*)),
			this, 		SLOT(itemAboutToBeRemoved(TreeItem*)) );
}

TagTreeModel::~TagTreeModel()
{
	delete m_rootItem;
}


QModelIndex TagTreeModel::index(int row, int column, const QModelIndex &parent) const
{
	if (!hasIndex(row, column, parent))
		return QModelIndex();

	TreeItem *parentItem;

	if (!parent.isValid())
		parentItem = m_rootItem;
	else
		parentItem = static_cast<TreeItem*>(parent.internalPointer());

	TreeItem *childItem = parentItem->child(row);
	if (childItem)
		return createIndex(row, column, childItem);
	else
		return QModelIndex();
}


QModelIndex TagTreeModel::parent(const QModelIndex &index) const
{
	if (!index.isValid())
		return QModelIndex();

	TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
	TreeItem *parentItem = childItem->parent();

	if (parentItem == m_rootItem)
		return QModelIndex();

	return createIndex(parentItem->row(), 0, parentItem);
}


int TagTreeModel::rowCount(const QModelIndex &parent) const
{
	if (parent.column() > 0)
		return 0;

	TreeItem *parentItem;

	if (!parent.isValid())
		parentItem = m_rootItem;
	else
		parentItem = static_cast<TreeItem*>(parent.internalPointer());

	return parentItem->childCount();
}

int TagTreeModel::columnCount(const QModelIndex & /*parent*/ ) const
{
	return 6;
}

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

	TreeItem* i = static_cast<TreeItem*>(index.internalPointer());
	return i->data(index.column(), role);
}


Qt::ItemFlags TagTreeModel::flags(const QModelIndex &index) const
{
	if (!index.isValid())
		return 0;

	return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}


QVariant TagTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (orientation == Qt::Horizontal)
		return m_rootItem->data(section, role);

	return QVariant();
}


RootItem* TagTreeModel::rootItem() const
{
	return m_rootItem;
}

TreeItem* TagTreeModel::selectedItem() const
{
	return m_selected;
}

void TagTreeModel::readerAttached ( Reader* reader )
{
	restoreRootIndex();

	ReaderEntry* r = m_rootItem->addReader(reader);

	QModelIndex readerIndex = index( r->row(), 0, QModelIndex() );
	emit expand(readerIndex);
	emit setCurrentIndex(readerIndex);
	emit itemClicked(r);
	m_selected = r;
}


void TagTreeModel::itemBeginInsertRows ( TreeItem* parent, int first, int last )
{
	QModelIndex parentIndex;
	if(parent == m_rootItem)
		parentIndex = QModelIndex();
	else
		parentIndex = createIndex(parent->row(), 0, parent);

	emit beginInsertRows(parentIndex, first, last);
}

void TagTreeModel::itemendInsertRows ( )
{
	emit endInsertRows();
}

void TagTreeModel::itemBeginRemoveRows ( TreeItem* parent, int first, int last )
{
	QModelIndex parentIndex;
	if(parent == m_rootItem)
		parentIndex = QModelIndex();
	else
		parentIndex = createIndex(parent->row(), 0, parent);

	emit beginRemoveRows(parentIndex, first, last);
}

void TagTreeModel::itemEndRemoveRows ( )
{
	emit endRemoveRows();
}

void TagTreeModel::itemRequestsToExpand ( TreeItem* t )
{
	QModelIndex parentIndex;
	if(t == m_rootItem)
		parentIndex = QModelIndex();
	else
		parentIndex = createIndex(t->row(), 0, t);

	emit expand(parentIndex);
}


void TagTreeModel::itemDataChanged ( TreeItem* t, int leftCol, int rightCol )
{
	QModelIndex parentIndex;
	if(t == m_rootItem)
		parentIndex = QModelIndex();
	else
		parentIndex = createIndex(t->parent()->row(), 0, t->parent());

	QModelIndex topLeft =			index( t->row(), leftCol,  parentIndex );
	QModelIndex bottomRight = 		index( t->row(), rightCol, parentIndex );
	emit dataChanged(topLeft, bottomRight);

}

void TagTreeModel::itemAboutToBeRemoved ( TreeItem* t )
{
	if(t != m_selected)
		return;

	m_selected = t->parent();
	emit itemClicked(m_selected);

	QModelIndex parentIndex;
	if(t->parent() == m_rootItem)
		parentIndex = QModelIndex();
	else
		parentIndex = createIndex(t->parent()->row(), 0, t->parent());

	emit setCurrentIndex(parentIndex);
}




void TagTreeModel::clicked ( const QModelIndex & index )
{
	m_selected = static_cast<TreeItem*>(index.internalPointer());
	emit itemClicked(m_selected);
}

void TagTreeModel::doubleClicked ( const QModelIndex & index )
{
	if(static_cast<TreeItem*>(index.internalPointer())->itemType() != TreeItem::READER)
		return;

	emit setRootIndex(index);
	emit itemSetRoot(static_cast<TreeItem*>(index.internalPointer()));
}

void TagTreeModel::clickedIntoFreeSpace ( ) 
{
	m_selected = m_rootItem;
	emit itemClicked(m_selected);
}

void TagTreeModel::restoreRootIndex()
{
	emit setRootIndex(QModelIndex());
	emit restoredRootIndex();
}

void TagTreeModel::clearTags()
{
	m_rootItem->clearTags();
}

