/***************************************************************************
           publichubsmodel.cpp  -  Public Hubs Model implementation
                             -------------------
    begin                : Mon Nov 5 2007
    copyright            : (C) 2007 by Edward Sheldrake
    email                : ejs1920@yahoo.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <QtAlgorithms>

// for byte size strings
#include <dclib/cutils.h>
#include "../dcconfig.h"

#include "publichubsmodel.h"

/** Sets values */
PublicHubItem::PublicHubItem( const QString n, const QString addr, const QString desc, const ulonglong u, const QString c, const ulonglong s, const ulonglong ms, const QString e )
{
	name = n;
	server = addr;
	description = desc;
	users = u;
	country = c;
	shared = s;
	minshare = ms;
	extra = e;
}

/** */
PublicHubItem::~PublicHubItem()
{

}

/** */
PublicHubsModel::PublicHubsModel() : QAbstractItemModel()
{
	sortColumn = 0;
	sortOrder = Qt::AscendingOrder;
}

/** delete all items in model */
PublicHubsModel::~PublicHubsModel()
{
	clear();
}

/** */
int PublicHubsModel::rowCount( const QModelIndex & /* index */ ) const
{
	return itemList.size();
}

/** */
int PublicHubsModel::columnCount( const QModelIndex & /* index */ ) const
{
	return 8;
}

/** */
QVariant PublicHubsModel::data( const QModelIndex & index, int role ) const
{
	if ( !index.isValid() )
	{
		return QVariant();
	}
	
	PublicHubItem * item = itemList[index.row()];
	
	if ( item != 0 )
	{
		if ( role == Qt::DisplayRole )
		{
			switch ( index.column() )
			{
				case 0:	return item->name;
				case 1: return item->server;
				case 2: return item->description;
				case 3: return item->users;
				case 4: return item->country;
				case 5: return QString( CUtils::GetSizeString(item->shared,g_pConfig->GetUnit()).Data() );
				case 6: return QString( CUtils::GetSizeString(item->minshare,g_pConfig->GetUnit()).Data() );
				case 7: return item->extra;
				default: return QVariant();
			}
		}
		else if ( role == Qt::ToolTipRole ) // tooltip
		{
			if ( index.column() == 5 )
			{
				return QString().setNum(item->shared);
			}
			else if ( index.column() == 6 )
			{
				return QString().setNum(item->minshare);
			}
			else
			{
				return data( index, Qt::DisplayRole );
			}
		}
		else if ( role == Qt::TextAlignmentRole )
		{
			if ( (index.column() == 3) || (index.column() == 5) || (index.column() == 6) )
			{
				return Qt::AlignRight;
			}
		}
	}
	
	return QVariant();
}

/** */
QVariant PublicHubsModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
	if ( (orientation == Qt::Horizontal) && (role == Qt::DisplayRole) )
	{
		switch ( section )
		{
			case 0:	return tr("Name");
			case 1: return tr("Server");
			case 2: return tr("Description");
			case 3: return tr("Users");
			case 4: return tr("Country");
			case 5: return tr("Shared");
			case 6: return tr("Minimum share");
			case 7: return tr("Extra");
		}
	}
	
	return QVariant();
}

/** */
bool PublicHubItemNameLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->name < r->name );
}

/** */
bool PublicHubItemServerLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->server < r->server );
}

/** */
bool PublicHubItemDescriptionLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->description < r->description );
}

/** */
bool PublicHubItemUsersLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->users < r->users );
}

/** */
bool PublicHubItemCountryLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->country < r->country );
}

/** */
bool PublicHubItemSharedLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->shared < r->shared );
}

/** */
bool PublicHubItemMinshareLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->minshare < r->minshare );
}

bool PublicHubItemExtraLessThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->extra < r->extra );
}

/** */
bool PublicHubItemNameGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->name > r->name );
}

/** */
bool PublicHubItemServerGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->server > r->server );
}

/** */
bool PublicHubItemDescriptionGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->description > r->description );
}

/** */
bool PublicHubItemUsersGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->users > r->users );
}

/** */
bool PublicHubItemCountryGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->country > r->country );
}

/** */
bool PublicHubItemSharedGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->shared > r->shared );
}

/** */
bool PublicHubItemMinshareGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->minshare > r->minshare );
}

/** */
bool PublicHubItemExtraGreaterThan( const PublicHubItem * l, const PublicHubItem * r )
{
	return ( l->extra > r->extra );
}

void PublicHubsModel::sort( int column, Qt::SortOrder order )
{
	emit layoutAboutToBeChanged();
	
	sortColumn = column;
	sortOrder = order;
	
	if ( order == Qt::AscendingOrder )
	{
		switch ( column )
		{
			case 0:	qSort( itemList.begin(), itemList.end(), PublicHubItemNameLessThan );
				break;
			case 1: qSort( itemList.begin(), itemList.end(), PublicHubItemServerLessThan );
				break;
			case 2: qSort( itemList.begin(), itemList.end(), PublicHubItemDescriptionLessThan );
				break;
			case 3: qSort( itemList.begin(), itemList.end(), PublicHubItemUsersLessThan );
				break;
			case 4: qSort( itemList.begin(), itemList.end(), PublicHubItemCountryLessThan );
				break;
			case 5: qSort( itemList.begin(), itemList.end(), PublicHubItemSharedLessThan );
				break;
			case 6: qSort( itemList.begin(), itemList.end(), PublicHubItemMinshareLessThan );
				break;
			case 7: qSort( itemList.begin(), itemList.end(), PublicHubItemExtraLessThan );
				break;
		}
	}
	else if ( order == Qt::DescendingOrder )
	{
		switch ( column )
		{
			case 0:	qSort( itemList.begin(), itemList.end(), PublicHubItemNameGreaterThan );
				break;
			case 1: qSort( itemList.begin(), itemList.end(), PublicHubItemServerGreaterThan );
				break;
			case 2: qSort( itemList.begin(), itemList.end(), PublicHubItemDescriptionGreaterThan );
				break;
			case 3: qSort( itemList.begin(), itemList.end(), PublicHubItemUsersGreaterThan );
				break;
			case 4: qSort( itemList.begin(), itemList.end(), PublicHubItemCountryGreaterThan );
				break;
			case 5: qSort( itemList.begin(), itemList.end(), PublicHubItemSharedGreaterThan );
				break;
			case 6: qSort( itemList.begin(), itemList.end(), PublicHubItemMinshareGreaterThan );
				break;
			case 7: qSort( itemList.begin(), itemList.end(), PublicHubItemExtraGreaterThan );
				break;
		}
	}
	
	emit layoutChanged();
}

/** */
QModelIndex PublicHubsModel::index( int row, int column, const QModelIndex & parent ) const
{
	if ( !hasIndex( row, column, parent ) )
	{
		return QModelIndex();
	}
	
	return createIndex( row, column );
}

/** */
QModelIndex PublicHubsModel::parent( const QModelIndex & /* parent */ ) const
{
	return QModelIndex();
}

/** add hub */
void PublicHubsModel::addHub( const QString name, const QString address, const QString desc, const ulonglong users, const QString country, const ulonglong shared, const ulonglong minshare, const QString extra )
{
	PublicHubItem * item = new PublicHubItem( name, address, desc, users, country, shared, minshare, extra );
	
	itemList.append(item);
}

/** delete all hubs */
void PublicHubsModel::clear()
{
	emit layoutAboutToBeChanged();
	
	for ( int i = 0; i < itemList.size(); i++ )
	{
		delete itemList.at(i);
	}
	
	itemList.clear();
	
	emit layoutChanged();
}

/** delete a hub */
bool PublicHubsModel::deleteHub( const QString name )
{
	bool res = FALSE;
	
	for ( int i = 0; i < itemList.size(); i++ )
	{
		if ( itemList.at(i)->name == name )
		{
			emit layoutAboutToBeChanged();
			delete itemList.takeAt(i);
			emit layoutChanged();
			res = TRUE;
		}
	}
	
	return res;
}

/** */
QList<PublicHubItem*> PublicHubsModel::getAll()
{
	return itemList;
}

/** */
PublicHubItem * PublicHubsModel::getItem( int row )
{
	if ( (row >= 0) && (row < itemList.size()) )
	{
		return itemList.at( row );
	}
	
	return 0;
}

/** */
void PublicHubsModel::getSorting( int & column, Qt::SortOrder & order ) const
{
	column = sortColumn;
	order = sortOrder;
}
