/***************************************************************************
                          dchublistmanager.cpp  -  description
                             -------------------
    begin                : Mon Oct 1 2001
    copyright            : (C) 2001-2004 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <stdlib.h>

#include <qapplication.h>
#include <qobject.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qlineedit.h>
#include <qcursor.h>
#include <qtabwidget.h>
#include <qinputdialog.h>
#include <qcombobox.h>
#include <qcheckbox.h>
#include <qmessagebox.h>
#include <qclipboard.h>
//Added by qt3to4:
#include <QResizeEvent>
#include <QEvent>
#include <QMdiArea>
#include <QMdiSubWindow>

#include "dcmenuhandler.h"
#include "dchubprofile.h"
#include "dchubfilter.h"
#include "dciconloader.h"
#include "dcconnectionmanager.h"

#include "dchublistmanager.h"

#include <dclib/dcos.h>
#include <dclib/cutils.h>

#include "dceditserver.h"
#include "cdialogmessage.h"

DCHubListManager * g_pHubListManager = 0;

/** */
DCHubListManager::DCHubListManager(QWidget* parent, const char *name, Qt::WindowFlags wflags) : QWidget(parent, name, wflags)
{
	setupUi(this);

	// set default icon
	setIcon( g_pIconLoader->GetPixmap(eiSERVER) );

	if ( (parent != 0) && (qobject_cast<QMdiArea*>(parent) != 0) )
	{
		m_pContainerWindow = new QMdiSubWindow();
		m_pContainerWindow->setWidget(this);
		(qobject_cast<QMdiArea*>(parent))->addSubWindow(m_pContainerWindow);
		m_pContainerWindow->setIcon( g_pIconLoader->GetPixmap(eiSERVER) );
	}
	else
	{
		m_pContainerWindow = 0;
	}

	model = new PublicHubsModel();
	TreeView_PUBLIC->setModel( model );
	
	m_pMessageList = new CList<CObject>();

	InitDocument();

	g_pHubListManager = this;
}

/** */
DCHubListManager::~DCHubListManager()
{
	g_pHubListManager = NULL;

	m_HLMThread.Lock();

	if ( m_pMessageList )
	{
		delete m_pMessageList;
		m_pMessageList = 0;
	}

	m_HLMThread.UnLock();
	
	delete model;
	
	// we might have removed public hubs
	if ( g_pConfig->GetRemovePublicHubEnabled() )
	{
		g_pConfig->SaveDCPublicHub();
	}
}

/** current tab widget change slot */
void DCHubListManager::slotTabWidgetCurrentChange(QWidget*)
{
	ResizeListViewColumn();
}

/** overridden so that the columns are resized on show() */
void DCHubListManager::show()
{
	QWidget::show();

	ResizeListViewColumn();
}

/** resize event handler */
void DCHubListManager::resizeEvent( QResizeEvent * )
{
	ResizeListViewColumn();
}

/** resize the ListView columns */
void DCHubListManager::ResizeListViewColumn()
{
	int width;

	if ( TreeView_PUBLIC->isVisible() )
	{
		width = TreeView_PUBLIC->width();

		TreeView_PUBLIC->setColumnWidth( 0, ((width*3)/18) );
		TreeView_PUBLIC->setColumnWidth( 1, ((width*3)/18) );
		TreeView_PUBLIC->setColumnWidth( 2, ((width*3)/18) );
		TreeView_PUBLIC->setColumnWidth( 3, ((width*1)/18) );
		TreeView_PUBLIC->setColumnWidth( 4, ((width*3)/18) );
		TreeView_PUBLIC->setColumnWidth( 5, ((width*1)/18) );
		TreeView_PUBLIC->setColumnWidth( 6, ((width*1)/18) );
		TreeView_PUBLIC->setColumnWidth( 7, ((width*3)/18) );
	}

	if ( TreeWidget_BOOKMARKS->isVisible() )
	{
		width = TreeWidget_BOOKMARKS->width();

		TreeWidget_BOOKMARKS->setColumnWidth( 0, ((width*10)/30) );
		TreeWidget_BOOKMARKS->setColumnWidth( 1, ((width*10)/30) );
		TreeWidget_BOOKMARKS->setColumnWidth( 2, ((width*10)/30) );
	}
}

/** */
void DCHubListManager::SetToolBar( QFrame * frame1, QFrame * frame2, bool vis )
{
	if ( vis )
	{
		frame1->hide();
		frame1->setEnabled(FALSE);
		frame2->show();
		frame2->setEnabled(TRUE);
	}
	else
	{
		frame2->hide();
		frame2->setEnabled(FALSE);
		frame1->show();
		frame1->setEnabled(TRUE);
	}
}

/** */
void DCHubListManager::InitDocument()
{
	StringMap * map;
	bool btb1=TRUE,btb2=TRUE;
	bool bfilter=FALSE;

	DC_HubFilterObject * HubFilterObject;

	// hide progressbar
	ProgressBar_LOADHUBLIST->setMinimum(0);
	ProgressBar_LOADHUBLIST->hide();

	// set bookmark icon
	TabWidget_SERVERLIST->setTabIconSet( TabWidget_SERVERLIST->page(1), QIcon( g_pIconLoader->GetPixmap(eiBOOKMARK_FOLDER) ) );

	// init the toolbars
	Frame_TOOLBAR1_HIDE->installEventFilter(this);
	Frame_TOOLBAR1_SHOW->installEventFilter(this);
	Frame_TOOLBAR2_HIDE->installEventFilter(this);
	Frame_TOOLBAR2_SHOW->installEventFilter(this);
	
	// restore settings
	if ( g_pConfig->GetMap("HUBVIEW",map) == TRUE )
	{
		if ( ((*map)["WIDTH"].toInt() > 0) && ((*map)["HEIGHT"].toInt() > 0) )
		{
			if ( m_pContainerWindow != 0 )
			{
				m_pContainerWindow->setGeometry( (*map)["X"].toInt(), (*map)["Y"].toInt(), (*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt() );
			}
		}

		if ( ((*map)["TOOLBAR1"] != "") && ((*map)["TOOLBAR1"].toInt() == 0) )
		{
			btb1 = FALSE;
		}

		if ( ((*map)["TOOLBAR2"] != "") && ((*map)["TOOLBAR2"].toInt() == 0) )
		{
			btb2 = FALSE;
		}

		// restore active page
		TabWidget_SERVERLIST->setCurrentPage((*map)["ACTIVEPAGE"].toInt());
		// restore linedit
		LineEdit_SERVER->setText((*map)["LE_SERVER"]);
	}

	SetToolBar( Frame_TOOLBAR1_HIDE, Frame_TOOLBAR1_SHOW, btb1 );
	SetToolBar( Frame_TOOLBAR2_HIDE, Frame_TOOLBAR2_SHOW, btb2 );

	connect( LineEdit_SERVER, SIGNAL(returnPressed()), this, SLOT(slotConnect()) );
	connect( LineEdit_SERVER, SIGNAL(returnPressed()), this, SLOT(slotConnect()) );
	connect( ToolButton_RELOADPUBLICHUBLIST, SIGNAL(clicked()), this, SLOT(slotReloadPublicHubList()) );
	connect( ToolButton_UPDATEPUBLICHUBLIST, SIGNAL(clicked()), this, SLOT(slotUpdatePublicHubList()) );
	connect( ToolButton_CONNECT, SIGNAL(clicked()), this, SLOT(slotConnect()) );

	// public list
	connect( TreeView_PUBLIC,SIGNAL(activated( const QModelIndex & )), this, SLOT(slotItemActivatedPublic( const QModelIndex & )) );
	connect( TreeView_PUBLIC,SIGNAL(customContextMenuRequested( const QPoint & )), this, SLOT(slotContextMenuPublicList( const QPoint & )) );

	// bookmark list
	connect( TreeWidget_BOOKMARKS,SIGNAL(itemActivated( QTreeWidgetItem *, int )), this, SLOT(slotItemActivatedBookmarks( QTreeWidgetItem *, int)) );
	connect( TreeWidget_BOOKMARKS,SIGNAL(customContextMenuRequested( const QPoint & )), this, SLOT(slotContextMenuBookmarkList( const QPoint & )) );

	connect( TabWidget_SERVERLIST,SIGNAL(currentChanged(QWidget*)), this, SLOT(slotTabWidgetCurrentChange(QWidget*)) );

	// filter
	connect( ToolButton_ADDFILTER, SIGNAL(clicked()), this, SLOT(slotAddFilter()) );
	connect( ToolButton_EDITFILTER, SIGNAL(clicked()), this, SLOT(slotEditFilter()) );
	connect( ToolButton_DELFILTER, SIGNAL(clicked()), this, SLOT(slotDelFilter()) );
	connect( ComboBox_FILTER, SIGNAL(activated( const QString & )), this, SLOT(slotFilterChange( const QString &)) );

	connect( &m_Timer, SIGNAL(timeout()), this, SLOT(timerDone()) );

	// load filter
	g_pConfig->LoadDCHubFilter(&m_HubFilterList);

	// create default
	if ( m_HubFilterList.Count() == 0 )
	{
		HubFilterObject = new DC_HubFilterObject();

		HubFilterObject->m_sFilterName = "Default";

		m_HubFilterList.Add( HubFilterObject->m_sFilterName, HubFilterObject );

		g_pConfig->SaveDCHubFilter(&m_HubFilterList);
	}

	HubFilterObject = 0;

	while ( m_HubFilterList.Next( (CObject*&)HubFilterObject) == 1 )
	{
		ComboBox_FILTER->insertItem( HubFilterObject->m_sFilterName.Data() );

		if ( (*map)["FILTER"] == HubFilterObject->m_sFilterName.Data() )
		{
			bfilter = TRUE;
		}
	}

	// restore filter
	if ( bfilter )
	{
		ComboBox_FILTER->setCurrentText((*map)["FILTER"]);
	}
	else
	{
		ComboBox_FILTER->setCurrentText("Default");
	}

	ShowBookmarkList();
	ShowPublicHubList();

	m_Timer.start( 500, TRUE );
}

/** */
void DCHubListManager::DeInitDocument()
{
	StringMap * map;

	// save hub view settings
	g_pConfig->GetMap("HUBVIEW",map);

	if ( m_pContainerWindow != 0 )
	{
		(*map)["X"]          = QString().setNum(m_pContainerWindow->x());
		(*map)["Y"]          = QString().setNum(m_pContainerWindow->y());
		(*map)["WIDTH"]      = QString().setNum(m_pContainerWindow->width());
		(*map)["HEIGHT"]     = QString().setNum(m_pContainerWindow->height());
		(*map)["VISIBLE"]    = QString().setNum(m_pContainerWindow->isVisible());
		(*map)["MAXIMIZED"]  = QString().setNum(m_pContainerWindow->isMaximized());
		(*map)["MINIMIZED"]  = QString().setNum(m_pContainerWindow->isMinimized());
		(*map)["ENABLED"]    = QString().setNum(m_pContainerWindow->isEnabled());
	}
	(*map)["ACTIVEPAGE"] = QString().setNum(TabWidget_SERVERLIST->currentPageIndex());
	(*map)["LE_SERVER"]  = LineEdit_SERVER->text();
	(*map)["FILTER"]     = ComboBox_FILTER->currentText();

	if ( !isEnabled() )
	{
		setEnabled(TRUE);
	}

	(*map)["TOOLBAR1"]  = QString().setNum(Frame_TOOLBAR1_SHOW->isEnabled());
	(*map)["TOOLBAR2"]  = QString().setNum(Frame_TOOLBAR2_SHOW->isEnabled());
}

/** event filter */
bool DCHubListManager::eventFilter(QObject* object, QEvent* event)
{
	if ( event->type() == QEvent::MouseButtonDblClick )
	{
		if ( object == Frame_TOOLBAR1_HIDE )
		{
			SetToolBar( Frame_TOOLBAR1_HIDE, Frame_TOOLBAR1_SHOW, TRUE );
		}
		else if ( object == Frame_TOOLBAR1_SHOW )
		{
			SetToolBar( Frame_TOOLBAR1_HIDE, Frame_TOOLBAR1_SHOW, FALSE );
		}
		else if ( object == Frame_TOOLBAR2_HIDE )
		{
			SetToolBar( Frame_TOOLBAR2_HIDE, Frame_TOOLBAR2_SHOW, TRUE );

			// show progressbar
			if ( m_pHubListUrl != 0 )
				ProgressBar_LOADHUBLIST->show();
		}
		else if ( object == Frame_TOOLBAR2_SHOW )
		{
			SetToolBar( Frame_TOOLBAR2_HIDE, Frame_TOOLBAR2_SHOW, FALSE );
		}
	}

	return QWidget::eventFilter( object, event );    // standard event processing
}

/** callback function */
int DCHubListManager::DC_CallBack( CObject * Object )
{
	int err;

	m_HLMThread.Lock();

	if ( Object != NULL )
	{
		if ( m_pMessageList != NULL )
		{
			m_pMessageList->Add(Object);
			err = 0;
		}
		else
		{
			err = -1;
		}
	}
	else
	{
		err = -1;
	}

	m_HLMThread.UnLock();

	return err;
}

/** */
void DCHubListManager::timerDone()
{
	CObject * Object;
	CDCMessage *DCMsg;
	int i;

	for(i=0;i<50;i++)
	{
		if ( m_HLMThread.TryLock() == FALSE )
		{
			break;
		}

		if ( m_pMessageList != 0 )
		{
			Object = m_pMessageList->Next(0);

			if ( Object != 0 )
			{
				m_pMessageList->Remove(Object);
			}
		}
		else
		{
			Object = 0;
		}

		m_HLMThread.UnLock();

		if ( Object == 0 )
		{
			break;
		}

		DCMsg = (CDCMessage*) Object;

		switch ( DCMsg->m_eType )
		{
			case DC_MESSAGE_GETHUBLIST:
			{
				DCMessageGetHubList * msg = (DCMessageGetHubList*) Object;

				if ( msg->m_bRun == FALSE )
				{
					// enable buttons
					ToolButton_RELOADPUBLICHUBLIST->setEnabled(TRUE);
					ToolButton_UPDATEPUBLICHUBLIST->setEnabled(TRUE);

					// hide progressbar
					ProgressBar_LOADHUBLIST->hide();

					ShowPublicHubList();
				}
				else
				{
					// disable buttons
					ToolButton_RELOADPUBLICHUBLIST->setEnabled(FALSE);
					ToolButton_UPDATEPUBLICHUBLIST->setEnabled(FALSE);

					// show progressbar
					ProgressBar_LOADHUBLIST->show();
				}

				break;
			}

			case DC_MESSAGE_TRANSFER:
			{
				CMessageTransfer *msg = (CMessageTransfer*)Object;

				ProgressBar_LOADHUBLIST->setMaximum(msg->m_nLength);
				ProgressBar_LOADHUBLIST->setValue(msg->m_nTransfered);

				break;
			}

			default:
			{
				break;
			}
		}

		if ( Object )
		{
			delete Object;
		}
	}

	m_Timer.start( 500, TRUE );
}

/** */
void DCHubListManager::ShowPublicHubList()
{
	DCConfigHubItem * hubitem;
	CList<DCConfigHubItem> PublicHubList;
	unsigned int minuser;
	DC_HubFilterObject * HubFilterObject = 0;
	CString s;
	bool bshow;
	QString AllFields,Pattern,Contains;
	int i,x=0;
	int sortColumn=0;
	Qt::SortOrder sortOrder = Qt::AscendingOrder;

	// disable filter combo box
	ComboBox_FILTER->setEnabled(FALSE);

	TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(0), tr("Public")+" (0/0)" );

	TreeView_PUBLIC->setUpdatesEnabled(FALSE);
	TreeView_PUBLIC->clearSelection();
	model->getSorting( sortColumn, sortOrder );
	model->clear();

	g_pConfig->GetPublicHubList(&PublicHubList);

	hubitem     = 0;
	minuser     = 0;
	
	// get the hubfilter
	s = ComboBox_FILTER->currentText().toAscii().data();

	if ( s != "" )
	{
		m_HubFilterList.Get( s, (CObject *&)HubFilterObject );

		if ( HubFilterObject &&
		     !HubFilterObject->m_bName &&
		     !HubFilterObject->m_bServer &&
		     !HubFilterObject->m_bDescription &&
		     (HubFilterObject->m_nUser==0) )
		{
			HubFilterObject = 0;
		}
	}

	while( (hubitem=PublicHubList.Next(hubitem)) != 0 )
	{
		bshow = TRUE;

		x++;

		if ( x == 100 )
		{
			qApp->processEvents();
			x = 0;
		}

		// use the filter
		if ( HubFilterObject )
		{
			if ( hubitem->m_sUserCount.asULL() < HubFilterObject->m_nUser )
			{
				bshow = FALSE;
			}
			else
			{
				AllFields = QString::null;

				if ( HubFilterObject->m_bName )
					AllFields += hubitem->m_sName.Data();
				if ( HubFilterObject->m_bServer )
					AllFields += hubitem->m_sHost.Data();
				if ( HubFilterObject->m_bDescription )
					AllFields += hubitem->m_sDescription.Data();

				Contains = HubFilterObject->m_sContains.Data();

				if ( AllFields != Contains )
				{
					i = 0;
					while ( !(Pattern=Contains.section(" ",i,i,QString::SectionSkipEmpty)).isEmpty())
					{
						i++;
						if ( AllFields.contains(Pattern,FALSE) == 0 )
						{
							bshow = FALSE;
							break;
						}
					}
				}
			}
		}

		if ( bshow )
		{
			model->addHub(
				QString::fromAscii(hubitem->m_sName.Data()),
				QString::fromAscii(hubitem->m_sHost.Data()),
				QString::fromAscii(hubitem->m_sDescription.Data()),
				hubitem->m_sUserCount.asULL(),
				QString::fromAscii(hubitem->m_sCountry.Data()),
				hubitem->m_nShared,
				hubitem->m_nMinShare,
				QString::fromAscii(hubitem->m_sExtra.Data())
			);
		}
	}

	TreeView_PUBLIC->setUpdatesEnabled(TRUE);
	TreeView_PUBLIC->sortByColumn( sortColumn, sortOrder );
	TreeView_PUBLIC->update();

	TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(0), tr("Public")+" ("+QString().setNum(model->rowCount( QModelIndex() ))+"/"+QString().setNum(PublicHubList.Count())+")");

	// enable filter combo box
	ComboBox_FILTER->setEnabled(TRUE);
}

/** */
void DCHubListManager::ShowBookmarkList()
{
	int x = 0;
	DCConfigHubItem * hubitem = 0;
	CList<DCConfigHubItem> list;
	DCConfigHubProfile ConfigHubProfile;

	g_pConfig->GetBookmarkHubList(&list);

	TreeWidget_BOOKMARKS->setUpdatesEnabled(FALSE);
	TreeWidget_BOOKMARKS->clear();

	while( (hubitem=list.Next(hubitem)) != 0 )
	{
		QTreeWidgetItem * item = new QTreeWidgetItem( TreeWidget_BOOKMARKS );
		item->setText( 0, hubitem->m_sName.Data() );
		item->setText( 1, hubitem->m_sHost.Data() );
		item->setText( 2, hubitem->m_sDescription.Data() );

		x++;

		if ( x == 100 )
		{
			qApp->processEvents();
			x = 0;
		}
	}

	TreeWidget_BOOKMARKS->setUpdatesEnabled(TRUE);
	TreeWidget_BOOKMARKS->sortItems( 0, Qt::AscendingOrder );
	TreeWidget_BOOKMARKS->update();

	TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(1), tr("Bookmarks")+" ("+QString().setNum(TreeWidget_BOOKMARKS->model()->rowCount())+")" );
}

/** */
void DCHubListManager::slotReloadPublicHubList()
{
	g_pConfig->ClearPublicHubList();

	GetPublicHubList();
}

/** update public hub list */
void DCHubListManager::slotUpdatePublicHubList()
{
	GetPublicHubList();
}

/** */
void DCHubListManager::slotItemActivatedPublic( const QModelIndex & index )
{
	PublicHubItem * item = model->getItem( index.row() );
	
	if ( item )
		g_pConnectionManager->Connect( item->name.toAscii().data(), item->server.toAscii().data() );
}

/** */
void DCHubListManager::slotItemActivatedBookmarks( QTreeWidgetItem * item, int /* column */ )
{
	if ( item )
		g_pConnectionManager->Connect( item->text(0).toAscii().data(), item->text(1).toAscii().data() );
}

/** */
void DCHubListManager::slotConnect()
{
	g_pConnectionManager->Connect( "", LineEdit_SERVER->text().toAscii().data() );
}

/** */
void DCHubListManager::slotAddFilter()
{
	CString s;
	DC_HubFilterObject * HubFilterObject, * HubFilterObject1 ;
	DCHubFilter * hf;

	hf = new DCHubFilter(this);

	if ( hf->exec() == QDialog::Accepted )
	{
		HubFilterObject = new  DC_HubFilterObject();

		// get the new data
		hf->Get( HubFilterObject );

		if ( HubFilterObject->m_sFilterName == "" )
		{
			// todo: error message

			delete HubFilterObject;
		}
		else if ( m_HubFilterList.Get( HubFilterObject->m_sFilterName, (CObject *&)HubFilterObject1 ) == 0 )
		{
			// todo: error message already exist

			delete HubFilterObject;
		}
		else
		{
			m_HubFilterList.Add( HubFilterObject->m_sFilterName, HubFilterObject );

			ComboBox_FILTER->insertItem( HubFilterObject->m_sFilterName.Data() );
		}

		g_pConfig->SaveDCHubFilter(&m_HubFilterList);

		delete hf;
	}
}

/** */
void DCHubListManager::slotEditFilter()
{
	CString s;
	DC_HubFilterObject * HubFilterObject, * HubFilterObject1;
	DCHubFilter * hf;

	s = ComboBox_FILTER->currentText().toAscii().data();

	if ( (s != "") && (s != "Default") )
	{
		if ( m_HubFilterList.Get( s, (CObject *&)HubFilterObject ) == 0 )
		{
			hf = new DCHubFilter(this);

			hf->Edit( HubFilterObject );

			if ( hf->exec() == QDialog::Accepted )
			{
				// get the new data
				hf->Get( HubFilterObject );

				if ( HubFilterObject->m_sFilterName == "" )
				{
					HubFilterObject->m_sFilterName = s;

					// todo: error message
				}
				else if ( s != HubFilterObject->m_sFilterName )
				{
					if ( m_HubFilterList.Get( HubFilterObject->m_sFilterName, (CObject *&)HubFilterObject1 ) == 0 )
					{
						// todo: error message already exist
					}
					else
					{
						m_HubFilterList.Remove(s);
						m_HubFilterList.Add( HubFilterObject->m_sFilterName, HubFilterObject );

						ComboBox_FILTER->changeItem( HubFilterObject->m_sFilterName.Data(), ComboBox_FILTER->currentItem() );
					}
				}

				// update view
				slotFilterChange( HubFilterObject->m_sFilterName.Data() );

				g_pConfig->SaveDCHubFilter(&m_HubFilterList);
			}

			delete hf;
		}
	}
}

/** */
void DCHubListManager::slotDelFilter()
{
	CString s;

	s = ComboBox_FILTER->currentText().toAscii().data();

	if ( (s != "") && (s != "Default") )
	{
		ComboBox_FILTER->removeItem(ComboBox_FILTER->currentItem());

		m_HubFilterList.Del(s);

		g_pConfig->SaveDCHubFilter(&m_HubFilterList);
	}
}

/** */
void DCHubListManager::slotFilterChange( const QString & s )
{
	if ( s != "" )
	{
		ShowPublicHubList();
	}
}

/** */
void DCHubListManager::RemoveBookmark( QTreeWidgetItem * item )
{
	if ( g_pConfig->RemoveBookmarkHub( item->text(0).toAscii().data(), item->text(1).toAscii().data(), item->text(2).toAscii().data() ) == TRUE )
	{
		g_pConfig->SaveDCBookHub();

		delete item;

		// update tabbar
		TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(1), tr("Bookmarks")+" ("+QString().setNum(TreeWidget_BOOKMARKS->model()->rowCount())+")" );
	}
}

/** */
void DCHubListManager::AddBookmark( QString hubname, QString hubhost, QString description )
{
	if ( g_pConfig->AddBookmarkHub( hubname.toAscii().data(), hubhost.toAscii().data(), description.toAscii().data() ) == TRUE )
	{
		g_pConfig->SaveDCBookHub();

		QTreeWidgetItem * item = new QTreeWidgetItem( TreeWidget_BOOKMARKS );
		item->setText( 0, hubname );
		item->setText( 1, hubhost );
		item->setText( 2, description );

		// update tabbar
		TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(1), tr("Bookmarks")+" ("+QString().setNum(TreeWidget_BOOKMARKS->model()->rowCount())+")" );
	}
}

/** */
void DCHubListManager::UpdateBookmark( QString hubname, QString hubhost, QString description )
{
	if ( g_pConfig->UpdateBookmarkHub( hubname.toAscii().data(), hubhost.toAscii().data(), description.toAscii().data() ) == TRUE )
	{
		g_pConfig->SaveDCBookHub();
	}
}

/** */
CStringList * DCHubListManager::GetFilteredHubList()
{
	CStringList * list = 0;
	CObject * object;

	list = new CStringList();

	QList<PublicHubItem*> items = model->getAll();
	
	for ( int i = 0; i < items.size(); i++ )
	{
		CString addr = (items.at(i))->server.toAscii().data();
		
		if ( list->Get( addr, (CObject *&)object ) != 0 )
		{
			list->Add( addr, new CString( addr ) );
		}
	}

	if ( list->Count() == 0 )
	{
		delete list;
		list = 0;
	}

	return list;
}

/** */
void DCHubListManager::slotContextMenuBookmarkList( const QPoint & )
{
	QAction * chosen = 0;
	QMenu *m;
	DCMenuHandler mhandler;
	DCEditServer * des;
	QList<QTreeWidgetItem*> selitems = TreeWidget_BOOKMARKS->selectedItems();
	QTreeWidgetItem * curitem;
	DCConfigHubProfile pConfigHubProfile;
	DCConfigHubItem ConfigHubItem;

	CString profilename;

	m = new QMenu(this);

	QAction * connect = mhandler.addAction( m, emiCONNECT, (selitems.count() > 0) );
	mhandler.addAction( m, emiSEPARATOR );
	QAction * add = mhandler.addAction( m, emiADD );
	QAction * edit = mhandler.addAction( m, emiEDIT, (selitems.count() == 1) );
	QAction * remove = mhandler.addAction( m, emiREMOVE, (selitems.count() > 0) );
	mhandler.addAction( m, emiSEPARATOR );
	QAction * updserver = mhandler.addAction( m, emiUPDATE_SERVER, (selitems.count() > 0) );
	QAction * updall = mhandler.addAction( m, emiUPDATE_ALL_SERVER );
	mhandler.addAction( m, emiSEPARATOR );
	QAction * profiles = mhandler.addAction( m, emiHUB_PROFILE_EDITOR );

	chosen = m->exec(QCursor::pos());

	delete m;

	if ( chosen == 0 )
	{
		return;
	}

	if ( chosen == add )
	{
		des = new DCEditServer();
		des->setCaption(tr("Add Bookmark"));

		//reset values
		des->Reset();
		
		while ( des->exec() == QDialog::Accepted )
		{
			// first we check some settings
			if ( des->LineEdit_NAME->text() == "" )
			{
				QMessageBox::critical( this, tr("Error"), tr("Please enter a hubname.") );

				continue;
			}

			if ( des->LineEdit_HOST->text() == "" )
			{
				QMessageBox::critical( this, tr("Error"), tr("Please enter a hubhost.") );

				continue;
			}

			// add bookmark to the list
			AddBookmark( des->LineEdit_NAME->text(), des->LineEdit_HOST->text(), des->LineEdit_DESCRIPTION->text() );

			// check if profiling possible
			if ( des->CheckBox_PROFILE->isChecked() == TRUE )
			{
				// get profile from dialog
				des->GetProfile(&pConfigHubProfile);
				
				// add new profile
				g_pConfig->AddHubProfile( &pConfigHubProfile );

				// save profile
				g_pConfig->SaveHubProfile();

				// set bookmark for that hub
				g_pConfig->SetBookmarkHubProfile(des->LineEdit_NAME->text().toAscii().data(),des->LineEdit_NAME->text().toAscii().data());
			}
			else
			{
				// clear bookmark from that hub
				g_pConfig->SetBookmarkHubProfile(des->LineEdit_NAME->text().toAscii().data(),"");
			}
			
			// update myinfo
			g_pConnectionManager->SendMyInfoToConnectedServers();
			
			break;
		}

		delete des;
	}
	else if ( chosen == edit )
	{
		bool prof = FALSE;

		// edit only for one selected item
		curitem = selitems.first();

		des = new DCEditServer();
		des->setCaption(tr("Edit Bookmark"));

		des->LineEdit_NAME->setText(curitem->text(0));
		des->LineEdit_HOST->setText(curitem->text(1));
		des->LineEdit_DESCRIPTION->setText(curitem->text(2));

		// hubitem
		if ( g_pConfig->GetBookmarkHub( curitem->text(0).toAscii().data(), &ConfigHubItem ) == TRUE )
		{
			if ( ConfigHubItem.m_sProfile != "" )
			{
				// get profile
				if ( g_pConfig->GetHubProfile( ConfigHubItem.m_sProfile, &pConfigHubProfile ) == TRUE )
				{
					des->SetProfile(&pConfigHubProfile);

					prof = TRUE;
				}
			}
		}

		while ( des->exec() == QDialog::Accepted  )
		{
			// first we check some settings
			if ( des->LineEdit_NAME->text() == "" )
			{
				QMessageBox::critical( this, tr("Error"), tr("Please enter a hubname.") );

				continue;
			}

			if ( des->LineEdit_HOST->text() == "" )
			{
				QMessageBox::critical( this, tr("Error"), tr("Please enter a hubhost.") );

				continue;
			}

			RemoveBookmark( curitem );

			if ( prof == TRUE )
			{
				// remove the profile
				g_pConfig->DelHubProfile( pConfigHubProfile.m_sName );
                	}

			// add as new bookmark
			AddBookmark( des->LineEdit_NAME->text(), des->LineEdit_HOST->text(), des->LineEdit_DESCRIPTION->text() );

			// check if profiling possible
			if ( des->CheckBox_PROFILE->isChecked() == TRUE )
			{
				// get profile from dialog
				des->GetProfile(&pConfigHubProfile);

				// add new profile
				g_pConfig->AddHubProfile( &pConfigHubProfile );

				// save profile
				g_pConfig->SaveHubProfile();

				// set bookmark for that hub
				g_pConfig->SetBookmarkHubProfile(des->LineEdit_NAME->text().toAscii().data(),des->LineEdit_NAME->text().toAscii().data());
			}
			else
			{
				// remove bookmark from that hub
				g_pConfig->SetBookmarkHubProfile(des->LineEdit_NAME->text().toAscii().data(),"");
			}

			// update myinfo
			g_pConnectionManager->SendMyInfoToConnectedServers();

			break;
		}

		delete des;
	}
	else if ( chosen == remove )
	{
		int i;
		StringMap * map;

		if ( g_pConfig->GetMap("DIALOG_REMOVE_BOOKMARK",map) == FALSE )
		{
			(*map)["SHOW"]    = QString().setNum(1);
			(*map)["DEFAULT"] = QString().setNum(0);
		}

		if ( ((*map)["SHOW"].toInt() == 1) || ((*map)["DEFAULT"].toInt() == 1) )
		{
			CDialogMessage * dlg = new CDialogMessage( this,
				QMessageBox::Warning,
				tr("Remove bookmarks"),
        			tr("You are sure ?"),
				tr("Remove"),
				tr("Cancel") );

			i = dlg->exec();

			(*map)["SHOW"]    = QString().setNum(!dlg->GetCheckBoxStatus());
			(*map)["DEFAULT"] = QString().setNum(i);

			delete dlg;


		}
		else
		{
			i = (*map)["DEFAULT"].toInt();
		}

		switch(i)
		{
	    		case 1: // The user clicked the cancel
        			return;
			default:
				break;
		}

	        for ( int i = 0; i < selitems.size(); i++ )
	        {
			curitem = selitems.at(i);
			
			// remove profile for that entry
			if ( g_pConfig->GetHubProfile( curitem->text(0).toAscii().data(), &pConfigHubProfile ) == TRUE )
			{
				g_pConfig->DelHubProfile( pConfigHubProfile.m_sName );
			}

			// remove bookmark
			RemoveBookmark(curitem);
		}
		
		// save changes to profile list, some may have been deleted
		g_pConfig->SaveHubProfile();
		
		// update myinfo
		g_pConnectionManager->SendMyInfoToConnectedServers();
	}
	else if ( chosen == connect )
	{
	        for ( int i = 0; i < selitems.size(); i++ )
	        {
			curitem = selitems.at(i);
			
			g_pConnectionManager->Connect( curitem->text(0).toAscii().data(), curitem->text(1).toAscii().data() );
		}
	}
	else if ( chosen == updserver )
	{
		DCConfigHubItem hubitem;

	        for ( int i = 0; i < selitems.size(); i++ )
	        {
			curitem = selitems.at(i);
			
			if ( g_pConfig->GetPublicHub( curitem->text(0).toAscii().data(), &hubitem ) == TRUE )
			{
				UpdateBookmark( hubitem.m_sName.Data(), hubitem.m_sHost.Data(), hubitem.m_sDescription.Data() );
				curitem->setText(1,hubitem.m_sHost.Data());
				curitem->setText(2,hubitem.m_sDescription.Data());
			}
		}
	}
	else if ( chosen == updall )
	{
		DCConfigHubItem * hubitem = 0;
		DCConfigHubItem hubitem1;
		CList<DCConfigHubItem> list;

		g_pConfig->GetBookmarkHubList(&list);

		while( (hubitem=list.Next(hubitem)) != 0 )
		{
			if ( g_pConfig->GetPublicHub( hubitem->m_sName, &hubitem1 ) == TRUE )
			{
				g_pConfig->UpdateBookmarkHub( hubitem1.m_sName, hubitem1.m_sHost, hubitem1.m_sDescription );
			}
		}

		g_pConfig->SaveDCBookHub();

		ShowBookmarkList();
	}
	else if ( chosen == profiles )
	{
		DCHubProfile * dlg = new DCHubProfile();

		dlg->exec();

		delete dlg;
		
		// update myinfo
		g_pConnectionManager->SendMyInfoToConnectedServers();
	}
}

/** */
void DCHubListManager::slotContextMenuPublicList( const QPoint & pos )
{
	QAction * chosen = 0;
	QMenu * m;
	DCMenuHandler mhandler;
	QList<PublicHubItem*> selitems;
	PublicHubItem * curitem;
	int numSelected;
	
	QModelIndexList indexlist = TreeView_PUBLIC->selectionModel()->selectedIndexes();
	
	for ( int i = 0; i < indexlist.size(); i++ )
	{
		QModelIndex index = indexlist.at(i);
		
		curitem = model->getItem( index.row() );
		
		if ( selitems.contains( curitem ) == FALSE )
		{
			selitems.append( curitem );
		}
	}
	
	numSelected = selitems.size();
	
	if ( numSelected == 0 )
	{
		return;
	}

	m = new QMenu(this);

	QAction * connect = mhandler.addAction( m, emiCONNECT );
	mhandler.addAction( m, emiSEPARATOR );
	
	QAction * remove = 0;
	if ( g_pConfig->GetRemovePublicHubEnabled() )
	{
		remove = mhandler.addAction( m, emiREMOVE );
		mhandler.addAction( m, emiSEPARATOR );
	}
	
	QAction * bookmark = mhandler.addAction( m, emiADD_BOOKMARK );
	mhandler.addAction( m, emiSEPARATOR );
	QAction * copycol = mhandler.addAction( m, emiCOPY_COLUMN_TO_CLIPBOARD, (numSelected == 1) );
	QAction * copyrow = mhandler.addAction( m, emiCOPY_ROW_TO_CLIPBOARD, (numSelected == 1) );

	chosen = m->exec(QCursor::pos());

	delete m;

	if ( chosen == 0 )
	{
		return;
	}

	if ( chosen == connect )
	{
	        for ( int i = 0; i < selitems.size(); i++ )
	        {
			curitem = selitems.at(i);
			g_pConnectionManager->Connect( curitem->name.toAscii().data(), curitem->server.toAscii().data() );
		}
	}
	else if ( chosen == remove )
	{
		for ( int i = 0; i < selitems.size(); i++ )
		{
			curitem = selitems.at(i);
			
			CString hubname = curitem->name.toAscii().data();
			CString hubhost = curitem->server.toAscii().data();
			CString desc = curitem->description.toAscii().data();
			
			if ( g_pConfig->RemovePublicHub(hubname,hubhost,desc) == TRUE )
			{
				model->deleteHub(curitem->name); // don't really need to check this return value too
			}
			else
			{
				QMessageBox::warning(this,tr("Remove public hub"),
				tr("Error removing hub \"") + QString::fromAscii(hubname.Data())
				+ QString("\" (") + QString::fromAscii(hubhost.Data()) + QString(")")
				);
			}
		}
	}
	else if ( chosen == bookmark )
	{
	        for ( int i = 0; i < selitems.size(); i++ )
	        {
			curitem = selitems.at(i);
			AddBookmark( curitem->name, curitem->server, curitem->description );
		}

		TabWidget_SERVERLIST->setTabLabel( TabWidget_SERVERLIST->page(1), tr("Bookmarks")+" ("+QString().setNum(TreeWidget_BOOKMARKS->model()->rowCount())+")" );
	}
	else if ( chosen == copycol )
	{
		int column = TreeView_PUBLIC->columnAt( pos.x() );
		
		curitem = selitems.first();
		
		QString s;
		
		switch ( column )
		{
			case 0:	s = curitem->name;
				break;
			case 1: s = curitem->server;
				break;
			case 2: s = curitem->description;
				break;
			case 3: s = QString().setNum(curitem->users);
				break;
			case 4: s = curitem->country;
				break;
			case 5: s = QString( CUtils::GetSizeString(curitem->shared,g_pConfig->GetUnit()).Data() );
				break;
			case 6: s = QString( CUtils::GetSizeString(curitem->minshare,g_pConfig->GetUnit()).Data() );
				break;
			case 7: s = curitem->extra;
				break;
			default: s = "";
				 break;
		}
		
		QApplication::clipboard()->setText( s );
	}
	else if ( chosen == copyrow )
	{
		QString s="";

		curitem = selitems.first();
		
		s = curitem->name + " " + curitem->server + " "
		  + curitem->description + " " + QString().setNum(curitem->users)
		  + " " + curitem->country + " " + QString( CUtils::GetSizeString(curitem->shared,g_pConfig->GetUnit()).Data() )
		  + " " + QString( CUtils::GetSizeString(curitem->minshare,g_pConfig->GetUnit()).Data() )
		  + " " + curitem->extra + "\n";

		QApplication::clipboard()->setText(s);
	}
}
