/***************************************************************************
                          dcclient.cpp  -  description
                             -------------------
    begin                : Thu Oct 4 2001
    copyright            : (C) 2001-2005 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 <qpainter.h>
#include <qtextedit.h>
#include <qlineedit.h>
#include <qlistview.h>
#include <qlistbox.h>
#include <qcheckbox.h>
#include <qregexp.h>
#include <qspinbox.h>
#include <qcombobox.h>
#include <qpopupmenu.h>
#include <qcursor.h>
#include <qfile.h>
#include <qmessagebox.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlistbox.h>
#include <qtabwidget.h>
#include <qinputdialog.h>
#include <qfiledialog.h>
#include <qclipboard.h>
#include <qsound.h>
#include <qlayout.h>
#include <qsplitter.h>
#include <qtoolbutton.h>
#include <qtooltip.h>
#include <qstringlist.h>

#include <dcevent.h>
#include <dchubsearch.h>
#include <dcspy.h>
#include <dctransferview.h>
#include <dcconfig.h>
#include <dcfiletool.h>
#include <dcchat.h>
#include <dcmenuhandler.h>
#include <dcwidget.h>
#include <dcuserslist.h>
#include <dciconloader.h>

#include "dcconnectionmanager.h"
#include "dcclient.h"

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

/** */
DCClient::DCClient(QWidget* parent, const char *name, int wflags) : DCDialogClient(parent, name, wflags)
{
	int idx;

	m_pWorkspace = (QWorkspace*)parent;

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

	// set the ColumnWidthMode to manual, we will take care of this task
	for( idx = 0; idx < ListView_USERLIST->columns(); idx++ )
	{
		ListView_USERLIST->setColumnWidthMode( idx, QListView::Manual );
	}

	ListView_USERLIST->setColumnAlignment(5,Qt::AlignRight);

	m_pMessageList  = new CList<CObject>();
	m_pUserViewList = new CStringList();
	m_pChatList     = new CStringList();

	m_bUseTabWidget = g_pConfig->GetShowChatInTab();

	m_nChatFloodCounter = 0;

	InitDocument();
}

/** */
DCClient::~DCClient()
{
	CObject * Object;

	m_Timer.stop();

	m_pHubChat->removeEventFilter(this);
	delete m_pHubChat;

	if ( g_pUsersList )
	{
		// force recheck all friend state
		DCFriendObject m_pFriendObject;
		QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
	}

	Disconnect();

	m_Thread.Lock();

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

		delete m_pMessageList;
		m_pMessageList = 0;
	}

	m_Thread.UnLock();

	if ( m_pChatList )
	{
		CString s;
		DCChat * chat = 0;

		while( m_pChatList->Next( s, (CObject *&)chat ) )
		{
			m_pChatList->Remove(s);
			chat = 0;
		}

		delete m_pChatList;
		m_pChatList = 0;
	}

	delete m_pUserViewList;
	m_pUserViewList = 0;
}

/** */
void DCClient::InitDocument()
{
	StringMap * map;
	QValueList<int> frames;

	SetCrypt(FALSE);

	// restore settings
	if ( g_pConfig->GetMap("CLIENTVIEW",map) == TRUE )
	{
		if ( ((*map)["WIDTH"].toInt() > 0) && ((*map)["HEIGHT"].toInt() > 0) )
		{
			setGeometry( x(), y(), (*map)["WIDTH"].toInt(), (*map)["HEIGHT"].toInt() );
		}

		ListView_USERLIST->setSorting( (*map)["SORTCOLUMN"].toInt() );
	}

	// add hubchat widget
	m_pHubChat = new DCChat( TabWidget_CHAT, "HUB-Chat", WDestructiveClose, this, FALSE );
	m_pHubChat->installEventFilter(this);
	m_pHubChat->SetNick("",tr("Hub").ascii());

	TabWidget_CHAT->insertTab( m_pHubChat, tr("Hub") );

	// remove chat list tab
	if ( m_bUseTabWidget )
	{
		QWidget * page = TabWidget_CHAT->page(0);
		TabWidget_CHAT->removePage(page);
		delete page;

		TabWidget_CHAT->setCurrentPage(0);
		
		TabWidget_CHAT->setCornerWidget( new QPushButton( QIconSet( g_pIconLoader->GetPixmap(eiFILECLOSE) ), "", TabWidget_CHAT ) );
		QToolTip::add( TabWidget_CHAT->cornerWidget(), tr("Close chat tab") );
		TabWidget_CHAT->cornerWidget()->setEnabled(FALSE);
	}
	else
	{
		// set width mode
		ListView_CHATUSERLIST->setColumnWidthMode( 0, QListView::Maximum );
		// hide the column header
		ListView_CHATUSERLIST->header()->hide();

		connect( ListView_CHATUSERLIST,SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(slotDoubleClickedChatUserList(QListViewItem*)) );

		TabWidget_CHAT->setTabLabel( TabWidget_CHAT->page(0), tr("Chat List")+" ("+QString().setNum(ListView_CHATUSERLIST->childCount())+")" );

		TabWidget_CHAT->setCurrentPage(1);
	}

	if ( g_pConfig->GetUserListRightAlignment() == TRUE )
	{
		Splitter_CLIENT->moveToFirst(Frame_CHATLIST);

		Frame_CHATLIST->adjustSize();
		Frame_USERLIST->adjustSize();
	}

	if ( g_pConfig->GetMap("USERLISTVIEW",map) == TRUE )
	{
		if ( (*map)[QString().setNum(eclcNICK)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcNICK, (*map)[QString().setNum(eclcNICK)].toInt() );
		if ( (*map)[QString().setNum(eclcCOMMENT)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcCOMMENT, (*map)[QString().setNum(eclcCOMMENT)].toInt() );
		if ( (*map)[QString().setNum(eclcTAG)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcTAG, (*map)[QString().setNum(eclcTAG)].toInt() );
		if ( (*map)[QString().setNum(eclcEMAIL)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcEMAIL, (*map)[QString().setNum(eclcEMAIL)].toInt() );
		if ( (*map)[QString().setNum(eclcSPEED)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcSPEED, (*map)[QString().setNum(eclcSPEED)].toInt() );
		if ( (*map)[QString().setNum(eclcSHARE)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcSHARE, (*map)[QString().setNum(eclcSHARE)].toInt() );
		if ( (*map)[QString().setNum(eclcIP)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcIP, (*map)[QString().setNum(eclcIP)].toInt() );
		if ( (*map)[QString().setNum(eclcLOCKPK)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcLOCKPK, (*map)[QString().setNum(eclcLOCKPK)].toInt() );
		if ( (*map)[QString().setNum(eclcSUPPORTS)].toInt() > 0 )
			g_pConfig->SetClientColumnWidth( eclcSUPPORTS, (*map)[QString().setNum(eclcSUPPORTS)].toInt() );
		if ( (*map)["WIDTH"].toInt() > 0 )
		{
			frames = Splitter_CLIENT->sizes();
			if (frames.size() == 2)
			{
				if ( g_pConfig->GetUserListRightAlignment() == TRUE )
				{
					frames[0] = (width() - Splitter_CLIENT->handleWidth() - 1) - (*map)["WIDTH"].toInt();
					frames[1] = (*map)["WIDTH"].toInt() + 1;
				} else {
					frames[0] = (*map)["WIDTH"].toInt() + 1;
					frames[1] = (width() - Splitter_CLIENT->handleWidth() - 1) - (*map)["WIDTH"].toInt();
				}
				Splitter_CLIENT->setSizes(frames);
			}
		}
	}

	// set viewable columns
	ResizeListViewColumn();

	// load column order from config
	if ( g_pConfig->GetMap("USERLISTCOLUMNORDER",map) == TRUE)
	{
		if ( (*map)[QString().setNum(eclcNICK)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcNICK, (*map)[QString().setNum(eclcNICK)].toInt());
		if ( (*map)[QString().setNum(eclcCOMMENT)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcCOMMENT, (*map)[QString().setNum(eclcCOMMENT)].toInt());
		if ( (*map)[QString().setNum(eclcTAG)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcTAG, (*map)[QString().setNum(eclcTAG)].toInt());
		if ( (*map)[QString().setNum(eclcEMAIL)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcEMAIL, (*map)[QString().setNum(eclcEMAIL)].toInt());
		if ( (*map)[QString().setNum(eclcSPEED)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcSPEED, (*map)[QString().setNum(eclcSPEED)].toInt());
		if ( (*map)[QString().setNum(eclcSHARE)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcSHARE, (*map)[QString().setNum(eclcSHARE)].toInt());
		if ( (*map)[QString().setNum(eclcIP)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcIP, (*map)[QString().setNum(eclcIP)].toInt());
		if ( (*map)[QString().setNum(eclcLOCKPK)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcLOCKPK, (*map)[QString().setNum(eclcLOCKPK)].toInt());
		if ( (*map)[QString().setNum(eclcSUPPORTS)].toInt() >= 0 )
			ListView_USERLIST->header()->moveSection(eclcSUPPORTS, (*map)[QString().setNum(eclcSUPPORTS)].toInt());
	}
	
	connect( ListView_USERLIST,SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(slotDoubleClickedUserList(QListViewItem*)) );
	connect( ListView_USERLIST,SIGNAL(contextMenuRequested( QListViewItem *, const QPoint &, int )), this, SLOT(slotRightButtonClickedUserList(QListViewItem*, const QPoint &, int )) );
	connect( ListView_USERLIST->header(),SIGNAL(sizeChange(int, int, int)), this, SLOT(slotSaveColumnWidth(int, int, int)) );
	connect( TabWidget_CHAT,SIGNAL(currentChanged(QWidget*)), this, SLOT(slotTabWidgetChatCurrentChange(QWidget*)) );
	connect( ToolButton_CONNECT,SIGNAL(clicked()), this, SLOT(slotHubConnect()) );
	connect( ToolButton_SSL,SIGNAL(clicked()), this, SLOT(slotSSLInfo()) );
	
	if (m_bUseTabWidget)
	{
		connect( TabWidget_CHAT->cornerWidget(), SIGNAL(clicked()), this, SLOT(slotTabCornerCloseWidgetClicked()) );
	}

	// set connect disconnect button pixmap
	SetConnection(FALSE);

	TabWidget_CHAT->installEventFilter(this);
	ListView_USERLIST->installEventFilter(this);
	
	connect( &m_Timer, SIGNAL(timeout()), this, SLOT(timerDone()) );
	
	m_Timer.start( 500, TRUE );
}

/** */
void DCClient::DeInitDocument()
{
	DCChat * chat = 0;
	StringMap * map;

	// save client view settings
	g_pConfig->GetMap("CLIENTVIEW",map);

	(*map)["WIDTH"]      = QString().setNum(width());
	(*map)["HEIGHT"]     = QString().setNum(height());
	
#if QT_VERSION >= 0x030100
	(*map)["SORTCOLUMN"] = QString().setNum(ListView_USERLIST->sortColumn());
#endif

	SaveClientColumn();

	// save column order to config
	/* for (int i = 0; i < ListView_USERLIST->columns(); i ++)
	 *{
	 *	printf("Column %d is at position %d\n", i, ListView_USERLIST->header()->mapToIndex(i) );
	 *}
	 */
	 g_pConfig->GetMap("USERLISTCOLUMNORDER",map);
	 (*map)[QString().setNum(eclcNICK)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcNICK));
	 (*map)[QString().setNum(eclcCOMMENT)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcCOMMENT));
	 (*map)[QString().setNum(eclcTAG)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcTAG));
	 (*map)[QString().setNum(eclcEMAIL)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcEMAIL));
	 (*map)[QString().setNum(eclcSPEED)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcSPEED));
	 (*map)[QString().setNum(eclcSHARE)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcSHARE));
	 (*map)[QString().setNum(eclcIP)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcIP));
	 (*map)[QString().setNum(eclcLOCKPK)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcLOCKPK));
 	 (*map)[QString().setNum(eclcSUPPORTS)] = QString().setNum(ListView_USERLIST->header()->mapToIndex(eclcSUPPORTS));
	
	if ( m_pChatList )
	{
		while( m_pChatList->Next( (CObject *&)chat ) )
		{
			chat->removeEventFilter(this);
			chat->close();
		}
	}
}

/** */
void DCClient::SaveClientColumn()
{
	StringMap * map;

	g_pConfig->GetMap("USERLISTVIEW",map);
	(*map)[QString().setNum(eclcNICK)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcNICK ));
	(*map)[QString().setNum(eclcCOMMENT)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcCOMMENT ));
	(*map)[QString().setNum(eclcTAG)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcTAG ));
	(*map)[QString().setNum(eclcEMAIL)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcEMAIL ));
	(*map)[QString().setNum(eclcSPEED)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcSPEED ));
	(*map)[QString().setNum(eclcSHARE)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcSHARE ));
	(*map)[QString().setNum(eclcIP)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcIP ));
	(*map)[QString().setNum(eclcLOCKPK)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcLOCKPK ));
	(*map)[QString().setNum(eclcSUPPORTS)] = QString().setNum(g_pConfig->GetClientColumnWidth( eclcSUPPORTS ));
	(*map)["WIDTH"] = QString().setNum(Frame_USERLIST->width());
}

/** */
void DCClient::SetCrypt( bool b )
{
	QToolTip::remove(ToolButton_SSL);
	ToolButton_SSL->setEnabled(b);

	if ( b )
	{
		QToolTip::add(ToolButton_SSL, tr("Line is encrypted."));
		ToolButton_SSL->setPixmap( g_pIconLoader->GetPixmap(eiSSL_YES));
	}
	else
	{
		QToolTip::add(ToolButton_SSL, tr("Line is not encrypted."));
		ToolButton_SSL->setPixmap( g_pIconLoader->GetPixmap(eiSSL_NO));
	}
}

/** */
void DCClient::SetConnection( bool b )
{
	QToolTip::remove(ToolButton_CONNECT);

	if ( b )
	{
		QToolTip::add(ToolButton_CONNECT, tr("Disconnect."));
		ToolButton_CONNECT->setPixmap( g_pIconLoader->GetPixmap(eiCONNECT_NO));
	}
	else
	{
		QToolTip::add(ToolButton_CONNECT, tr("Connect."));
		ToolButton_CONNECT->setPixmap( g_pIconLoader->GetPixmap(eiCONNECT_CREATING));
	}
}

/** */
void DCClient::slotSSLInfo()
{
}

/** event filter */
bool DCClient::eventFilter(QObject* object, QEvent* event)
{
	if((event->type() == QEvent::Close)&&((DCClient*)object!=this))
	{
		QCloseEvent* e=(QCloseEvent*)event;

		if ( m_pHubChat == object )
		{
			e->ignore();
			return TRUE;
		}

		DCChat* pView=(DCChat*)object;

		CloseChat(pView);
	}
	else if ( event->type() == QEvent::KeyPress )
	{
		QKeyEvent * e = (QKeyEvent*)event;

		// reconnect
		if ( (e->state() == AltButton) && (e->key() == Key_R) )
		{
			slotHubConnect();
		}
		
		if ( ListView_USERLIST->hasFocus() )
		{
			// TODO: add userlist shortcuts
		}
	}
	else if ( (event->type() == QEvent::MouseButtonPress) && (object == TabWidget_CHAT) )
	{
		QMouseEvent * e = (QMouseEvent*)event;

		if ( e->button() == QMouseEvent::RightButton )
		{
			if ( (TabWidget_CHAT->currentPage() != 0) &&
			     (TabWidget_CHAT->currentPage() != ListView_CHATUSERLIST) )
			{
                                 ((DCChat*)TabWidget_CHAT->currentPage())->slotRightButtonClickedChatOutput(QPoint());
			}
		}
	}

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

/** current tab widget change slot */
void DCClient::slotTabWidgetChatCurrentChange( QWidget * w )
{
	DCChat * chat = (DCChat*)w;
	
	if ( ! TabWidget_CHAT->tabIconSet(w).isNull() )
	{
		TabWidget_CHAT->setTabIconSet( w, QIconSet() );
		
		// reset nick color
		SetNickColor( QString::fromUtf8(chat->GetNick().Data()), ListView_USERLIST->colorGroup().text() );
	}
	
	if (m_bUseTabWidget)
	{
		if (TabWidget_CHAT->currentPage() == m_pHubChat)
		{
			TabWidget_CHAT->cornerWidget()->setEnabled(FALSE);
		}
		else
		{
			TabWidget_CHAT->cornerWidget()->setEnabled(TRUE);
		}
	}
}

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

	ResizeListViewColumn();
	
	m_pHubChat->InitView();
}

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

/** */
void DCClient::UpdateClientColumn( bool enabled, int index, int width )
{
	if ( enabled == FALSE )
	{
		ListView_USERLIST->setColumnWidth( index, 0 );
		ListView_USERLIST->header()->setResizeEnabled(FALSE, index);
	}
	else
	{
		if ( width < 10 ) { width = 10; } // otherwise newly-enabled columns remain hidden
		ListView_USERLIST->header()->setResizeEnabled(TRUE, index);
		ListView_USERLIST->setColumnWidth( index, width );
	}
}

/** resize the ListView columns */
void DCClient::ResizeListViewColumn()
{
	int width,i;

//	printf("%d\n",g_pConfig->GetClientColumnWidth( eclcNICK ));
	if ( g_pConfig->GetClientColumnWidth( eclcNICK ) < 30 )
	{
		i     = 36;
		width = ListView_USERLIST->width();

		if ( ListView_USERLIST->verticalScrollBar()->isVisible() )
			width -= (ListView_USERLIST->verticalScrollBar()->size().width()+4);

		if ( width > 0 )
		{
			if ( g_pConfig->GetClientColumn( eclcCOMMENT ) == FALSE )
				i -= 5;
			if ( g_pConfig->GetClientColumn( eclcTAG ) == FALSE )
				i -= 4;
			if ( g_pConfig->GetClientColumn( eclcSPEED ) == FALSE )
				i -= 2;
			if ( g_pConfig->GetClientColumn( eclcEMAIL ) == FALSE )
				i -= 3;
			if ( g_pConfig->GetClientColumn( eclcSHARE ) == FALSE )
				i -= 4;
			if ( g_pConfig->GetClientColumn( eclcIP ) == FALSE )
				i -= 4;
			if ( g_pConfig->GetClientColumn( eclcLOCKPK ) == FALSE )
				i -= 4;
			if ( g_pConfig->GetClientColumn( eclcSUPPORTS ) == FALSE )
				i -= 4;

			g_pConfig->SetClientColumnWidth( eclcCOMMENT,  (width*5)/i );
			g_pConfig->SetClientColumnWidth( eclcTAG,      (width*4)/i );
			g_pConfig->SetClientColumnWidth( eclcSPEED,    (width*2)/i );
			g_pConfig->SetClientColumnWidth( eclcEMAIL,    (width*3)/i );
			g_pConfig->SetClientColumnWidth( eclcSHARE,    (width*4)/i );
			g_pConfig->SetClientColumnWidth( eclcIP,       (width*4)/i );
			g_pConfig->SetClientColumnWidth( eclcLOCKPK,   (width*4)/i );
			g_pConfig->SetClientColumnWidth( eclcSUPPORTS, (width*4)/i );
			g_pConfig->SetClientColumnWidth( eclcNICK,     (width*6)/i );
		}
	}

	if ( g_pConfig->GetClientColumnWidth( eclcNICK ) > 0 )
	{
		UpdateClientColumn( TRUE,                                       0, g_pConfig->GetClientColumnWidth( eclcNICK ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcCOMMENT ),  1, g_pConfig->GetClientColumnWidth( eclcCOMMENT ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcTAG ),      2, g_pConfig->GetClientColumnWidth( eclcTAG ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcSPEED ),    3, g_pConfig->GetClientColumnWidth( eclcSPEED ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcEMAIL ),    4, g_pConfig->GetClientColumnWidth( eclcEMAIL ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcSHARE ),    5, g_pConfig->GetClientColumnWidth( eclcSHARE ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcIP ),       6, g_pConfig->GetClientColumnWidth( eclcIP ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcLOCKPK ),   7, g_pConfig->GetClientColumnWidth( eclcLOCKPK ) );
		UpdateClientColumn( g_pConfig->GetClientColumn( eclcSUPPORTS ), 8, g_pConfig->GetClientColumnWidth( eclcSUPPORTS ) );
	}
}

/** */
void DCClient::UpdateCaption()
{
	QString s;

	switch(GetConnectionState())
	{
		case estCONNECTED:
				s = "[+]";
				break;
		default:
				s = "[-]";
				break;
	}

	s += " ";
	s += QString::fromUtf8(GetHubName().Data());

	if ( GetHubTopic() != "" )
	{
		s += " (";
		s += QString::fromUtf8(GetHubTopic().Data());
		s += ")";
	}
	
	if (s.length() > 50)
	{
		s = s.left(50) + "...";
	}

	setCaption(s);
}

/** */
void DCClient::UpdateStatusBar()
{
	TextLabel_USERCOUNT->setText( QString().setNum(ListView_USERLIST->childCount()) );
	TextLabel_SHARESIZE->setText( CUtils::GetSizeString(UserList()->ShareSize(),g_pConfig->GetUnit()).Data() );
}

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

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

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

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

		m_Thread.UnLock();

		if ( Object == 0 )
		{
			break;
		}

		DCMsg = (CDCMessage*) Object;

		switch ( DCMsg->m_eType )
		{
			case DC_MESSAGE_CONNECTION_STATE:
			{
				CMessageConnectionState *msg = (CMessageConnectionState*) Object;

				if ( msg->m_eState == estCONNECTED )
				{
					m_nChatFloodCounter = 0;
					m_bUserPassword     = FALSE;

					UpdateCaption();
					setIcon( g_pIconLoader->GetPixmap(eiCONNECTED) );
					// repaint new icon in minimized mode
					if ( isMinimized() )
						showMinimized();

					m_pHubChat->AddStatus(tr("Connected").ascii());

					// init userlist
					DC_NickList(0);

					g_pConfig->PlaySound(eusCONNECT);

					SetConnection(TRUE);

					SetCrypt(FALSE);
				}
				if ( msg->m_eState == estSSLCONNECTED )
				{
					SetCrypt(TRUE);
				}
				else if ( msg->m_eState == estCONNECTIONTIMEOUT )
				{
					m_pHubChat->AddStatus(tr("Connection timeout").ascii());

					SetConnection(FALSE);

					SetCrypt(FALSE);
				}
				else if ( msg->m_eState == estSOCKETERROR )
				{
					QString s;
					s = tr("Error: '") + msg->m_sMessage.Data() + "'";
					m_pHubChat->AddStatus(s.ascii());

					SetConnection(FALSE);

					SetCrypt(FALSE);
				}
				else if ( msg->m_eState == estDISCONNECTED )
				{
					m_nChatFloodCounter = 0;

					UpdateCaption();
					setIcon( g_pIconLoader->GetPixmap(eiNOTCONNECTED) );
					// repaint new icon in minimized mode
					if ( isMinimized() )
						showMinimized();

					m_pHubChat->AddStatus(tr("Disconnected").ascii());
					g_pConfig->PlaySound(eusDISCONNECT);

					if ( g_pUsersList )
					{
						// force recheck all friend state
						DCFriendObject m_pFriendObject;
						QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
					}

					// reset all chats
					DCChat * chat = 0;
					while ( m_pChatList->Next( (CObject*&)chat ) == 1 )
					{
						chat->SetCrypt(esecsNONE);
						chat->AddStatus(tr("We left the hub.").ascii());
        				}

					SetConnection(FALSE);

					SetCrypt(FALSE);
				}

				break;
			}

			case DC_MESSAGE_VALIDATEDENIDE:
			{
				m_pHubChat->AddStatus(tr("Your Nick is already in use.").ascii());
				Disconnect();
				break;
			}

			case DC_MESSAGE_NICKLIST:
			{
				DC_NickList( (CMessageNickList *) Object );
				break;
			}

			case DC_MESSAGE_OPLIST:
			{
				DC_OpList( (CMessageNickList *) Object );
				break;
			}

			case DC_MESSAGE_REVCONNECTTOME:
			{
				CMessageRevConnectToMe * msg = (CMessageRevConnectToMe*) Object;

				if ( GetMode() == ecmPASSIVE )
				{
					if ( g_pConfig->GetSendMessageOnActiveModeRequest() == TRUE )
					{
						SendPrivateMessage( GetNick(), msg->m_sDstNick, tr("Sorry, you will not be able to download from me, because we are both in passive mode. (automated message)").ascii() );
					}
				}

				break;
			}

			case DC_MESSAGE_CHAT:
			{
				CMessageChat * msg = (CMessageChat *) Object;
				
				if ( m_ChatFloodMessage.m_sMessage == msg->m_sMessage && m_ChatFloodMessage.m_sNick == msg->m_sNick )
				{
					// increment flood counter
					m_nChatFloodCounter++;
				}
				else
				{
					// update message and reset counter
					m_ChatFloodMessage.m_sMessage = msg->m_sMessage;
					m_ChatFloodMessage.m_sNick    = msg->m_sNick;
					m_nChatFloodCounter = 0;
				}

				// if flood detect enabled ?
				if ( g_pConfig->GetFloodCount() > 0 )
				{
					if ( m_nChatFloodCounter >= g_pConfig->GetFloodCount() )
					{
						// only one flood message
						if ( m_nChatFloodCounter == g_pConfig->GetFloodCount() )
						{
							m_pHubChat->AddStatus(tr("Flood Detected ("+QString().setNum(m_nChatFloodCounter)+")").ascii());

							// now the admin kick the user if enabled
							if ( (g_pConfig->GetFloodOpKick() == TRUE) && (!UserList()->IsAdmin(msg->m_sNick)) && (UserList()->IsAdmin(GetNick())) )
							{
								//if OP kick the user for Flooding
								CString kickmessage=g_pConfig->GetFloodOpKickMessage();
								SendPrivateMessage( GetNick(), msg->m_sNick.Data(), ("You are being kicked because: " + kickmessage));
								SendChat( GetNick(), GetNick() + " is kicking " + msg->m_sNick.Data() + " because: " + kickmessage );
								SendKick(msg->m_sNick.Data());
							}
						}

						// don't show the flood messages
						msg = 0;
					}
				}

				if ( msg )
				{
					DC_Chat( msg );
				}

				break;
			}

			case DC_MESSAGE_MYINFO:
			{
				DC_MyInfo( (CMessageMyInfo *) Object );
				break;
			}

			case DC_MESSAGE_QUIT:
			{
				DC_Quit( (CMessageQuit *) Object );
				break;
			}

			case DC_MESSAGE_SEARCH:
			{
				if ( g_pSpy )
					g_pSpy->DC_Search( (CMessageSearch *) Object );
				break;
			}

			case DC_MESSAGE_HELLO:
			{
				CMessageHello * msg = (CMessageHello *) Object;

				DC_Hello(msg);

				break;
			}

			case DC_MESSAGE_FORCEMOVE:
			{
				CMessageForceMove * msg = (CMessageForceMove*) Object;

				if ( g_pConfig->GetForceMoveEnabled() == TRUE )
				{
					UpdateCaption();

					m_pHubChat->AddStatus( (tr("Redirect to ")+ msg->m_sHost.Data() + ":" + QString().setNum(msg->m_nPort)).ascii() );
				}
				else
				{
					m_pHubChat->AddStatus( (tr("Redirect disabled ")+ msg->m_sHost.Data() + ":" + QString().setNum(msg->m_nPort)).ascii() );
				}

				break;
			}

			case DC_MESSAGE_HUBNAME:
			{
				CMessageHubName * msg = (CMessageHubName*) Object;

				if ( (msg->m_sOldHubName != "") && (msg->m_sOldHubName != msg->m_sHubName) )
				{
					m_pHubChat->AddStatus( (tr("Hubname change:")+(" '"+msg->m_sOldHubName+"' -> '"+msg->m_sHubName+"'").Data()).ascii() );
				}

				UpdateCaption();

				// update caption from the main chat
				m_pHubChat->SetNick("",msg->m_sHubName.Data());

				// update caption from all private chats
				if ( m_pChatList )
				{
					DCChat * chat = 0;

					while( m_pChatList->Next( (CObject *&)chat ) )
					{
						chat->SetNick( chat->GetNick(), msg->m_sHubName.Data() );
					}
				}

				break;
			}

			case DC_MESSAGE_HUB_TOPIC:
			{
				UpdateCaption();
				break;
			}

			case DC_MESSAGE_PRIVATECHAT:
			{
				CMessagePrivateChat * msg = (CMessagePrivateChat*) Object;

				DC_PrivateChat( msg );

				break;
			}

			case DC_MESSAGE_GETPASS:
			{
				bool ok = FALSE;
				DCConfigHubProfile pConfigHubProfile;

				if ( m_bUserPassword == FALSE )
				{
					// get password from profile
					if ( g_pConfig->GetBookmarkHubProfile( GetHubName(), GetHost(), &pConfigHubProfile ) == TRUE )
					{
						if ( pConfigHubProfile.m_sPassword != "" )
						{
							m_pHubChat->AddStatus(tr("Use password from profile").ascii());
							SendPass(pConfigHubProfile.m_sPassword);
							SetUsedPassword(TRUE);
							m_bUserPassword = TRUE;
							break;
						}
						else
						{
							m_pHubChat->AddStatus(tr("Password from profile is empty").ascii());
						}
					}
					else
					{
						m_pHubChat->AddStatus(tr("No profile found for this hub").ascii());
					}
				}

				QString text = QInputDialog::getText(
					tr( "Password - ")+GetHubName().Data(),
					tr( "Please enter your password" ),
					QLineEdit::Password, QString::null, &ok, this );

				if ( ok && !text.isEmpty() )
				{
					SendPass(text.ascii());
					SetUsedPassword(TRUE);
				}
				else
				{
					Disconnect();
				}

				break;
			}

			case DC_MESSAGE_BADPASS:
			{
				m_pHubChat->AddStatus(tr("Wrong password").ascii());
				SetUsedPassword(FALSE);
				break;
			}

			case DC_MESSAGE_USERIP:
			{
				CMessageUserIP * msg = (CMessageUserIP*) Object;
				
				// fill in the IP address column for the given nick
				QListViewItem * item = ListView_USERLIST->findItem( msg->m_sNick.Data(), 0 );
				
				if ( item != 0 )
				{
					item->setText( 6, msg->m_sIP.Data() );
				}
				
				break;
			}

			default:
			{
				break;
			}
		}

		if ( Object )
			delete Object;
	}

	m_Timer.start( 500, TRUE );
}

/** */
int DCClient::DC_CallBack( CObject * Object )
{
	int err;

	m_Thread.Lock();

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

	m_Thread.UnLock();

	return err;
}

/** chat */
void DCClient::DC_Chat( CMessageChat * MessageChat )
{
	// check for ignored nick
	if ( g_pUsersList->ignoreNick( MessageChat->m_sNick ) == TRUE )
	{
		//printf("Ignoring \"%s\" from \"%s\"\n", MessageChat->m_sMessage.Data(), MessageChat->m_sNick.Data());
		return;
	}
	
	m_pHubChat->AddMessage(MessageChat->m_sNick.Data(),MessageChat->m_sMessage.Data(),TRUE);

	if ( !m_pHubChat->isVisible() )
	{
		TabWidget_CHAT->setTabIconSet( m_pHubChat, QIconSet( g_pIconLoader->GetPixmap(eiMESSAGE) ) );
	}
	
	// send chat event
	g_pConnectionManager->HubEvent(this);
	
	// check for auto responses
	if (g_pConfig->GetAutoResponderEnabled() == TRUE)
	{
		this->doAutoResponse( MessageChat->m_sNick.Data(), MessageChat->m_sMessage.Data(), m_pHubChat );
	}
}

/** myinfo */
void DCClient::DC_MyInfo( CMessageMyInfo * MessageMyInfo )
{
	CString s;
	DCFileTool FileTool;
	QPixmap pm;

	DCUserItem * pui=0;

	if ( m_pUserViewList->Get( MessageMyInfo->m_sNick, (CObject*&)pui ) == -1 )
	{
		pui = new DCUserItem();
		m_pUserViewList->Add(MessageMyInfo->m_sNick,pui);

#ifndef WIN32
		pm = *g_pConfig->GetUserIcon(MessageMyInfo->m_bOperator,MessageMyInfo->m_eClientMode,MessageMyInfo->m_eAwayMode,MessageMyInfo->m_eUserSpeed,MessageMyInfo->m_eClientVersion);
		pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8(MessageMyInfo->m_sNick.Data()), pm );
#else
		pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8(MessageMyInfo->m_sNick.Data()) );
#endif
		// user not in the list, add it
		addUser( MessageMyInfo->m_sNick.Data() );
	}
	else
	{
		if ( (pui->MyInfo.m_eAwayMode != MessageMyInfo->m_eAwayMode) ||
		     (pui->MyInfo.m_eUserSpeed != MessageMyInfo->m_eUserSpeed) ||
		     (pui->MyInfo.m_bOperator != MessageMyInfo->m_bOperator) ||
		     (pui->MyInfo.m_eClientMode != MessageMyInfo->m_eClientMode) ||
		     (pui->MyInfo.m_eClientVersion != MessageMyInfo->m_eClientVersion) )
		{
#ifndef WIN32
			pm = *g_pConfig->GetUserIcon(MessageMyInfo->m_bOperator,MessageMyInfo->m_eClientMode,MessageMyInfo->m_eAwayMode,MessageMyInfo->m_eUserSpeed,MessageMyInfo->m_eClientVersion);
			pui->pItem->setPixmap(0,pm);
#endif
		}
	}

	pui->MyInfo = *MessageMyInfo;

	pui->pItem->setText(1,QString::fromUtf8(MessageMyInfo->m_sComment.Data()));
	pui->pItem->setText(2,MessageMyInfo->m_sVerComment.Data());
	pui->pItem->setText(3,MessageMyInfo->m_sUserSpeed.Data());
	pui->pItem->setText(4,QString::fromUtf8(MessageMyInfo->m_sEMail.Data()));

	pui->pItem->myvalue = MessageMyInfo->m_nShared;
	pui->pItem->mycol   = 5;

	s = CUtils::GetSizeString(MessageMyInfo->m_nShared,g_pConfig->GetUnit());
	pui->pItem->setText(5,s.Data());

	pui->pItem->setText(6,MessageMyInfo->m_sTransferHost.Data());
	pui->pItem->setText(7,MessageMyInfo->m_MessageLock.m_sData.Data());
	pui->pItem->setText(8,MessageMyInfo->m_MessageSupports.m_sContent.Data());
	
	// send friend event
	if ( g_pUsersList )
	{
		DCFriendObject m_pFriendObject;

		m_pFriendObject.m_sName        = MessageMyInfo->m_sNick;
		m_pFriendObject.m_sDescription = MessageMyInfo->m_sComment;
		m_pFriendObject.m_eAwayMode    = MessageMyInfo->m_eAwayMode;
		m_pFriendObject.m_sHubName     = GetHubName();
		m_pFriendObject.m_sHubHost     = GetIP();
		QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
	}
	
	UpdateStatusBar();
}

/** hello */
void DCClient::DC_Hello( CMessageHello * MessageHello )
{
	DCUserItem * pui=0;
	QPixmap pm;

	if ( m_pUserViewList->Get( MessageHello->m_sNick, (CObject*&)pui ) == -1 )
	{
		pui = new DCUserItem();
		m_pUserViewList->Add(MessageHello->m_sNick,pui);

#ifndef WIN32
		pm = *g_pConfig->GetUserIcon(FALSE,ecmNONE,euamNONE,eusUNKNOWN,eucvNONE);
		pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8(MessageHello->m_sNick.Data()), pm );
#else
		pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8(MessageHello->m_sNick.Data()) );
#endif
		pui->MyInfo.m_sNick = MessageHello->m_sNick;
		pui->MyInfo.m_bOperator = FALSE;
		pui->MyInfo.m_eAwayMode = euamNORMAL;
		
		addUser( MessageHello->m_sNick.Data() );
	}

	pui->pItem->mycol = 5;

	UpdateStatusBar();
}

/** quit */
void DCClient::DC_Quit( CMessageQuit * MessageQuit )
{
	DCChat * chat;
	DCUserItem * pui=0;

	if ( m_pUserViewList->Get( MessageQuit->m_sNick, (CObject*&)pui ) == 0 )
	{
		ListView_USERLIST->takeItem(pui->pItem);
		delete pui->pItem;
		m_pUserViewList->Del(MessageQuit->m_sNick);
	}

	if ( m_pChatList->Get( MessageQuit->m_sNick, (CObject*&)chat ) == 0 )
	{
		chat->SetCrypt(esecsNONE);
		chat->AddStatus(tr("User left the hub.").ascii());
        }

	// send friend event
	if ( g_pUsersList )
	{
		DCFriendObject m_pFriendObject;

		m_pFriendObject.m_sName     = MessageQuit->m_sNick;
		m_pFriendObject.m_eAwayMode = euamOFFLINE;
		m_pFriendObject.m_sHubName  = GetHubName();
		m_pFriendObject.m_sHubHost  = GetIP();
		QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
	}

	if ( g_pConfig->GetChatShowJoinsAndParts() == TRUE )
	{
		if ( g_pConfig->GetChatShowJoinsAndPartsOnlyFav() == TRUE )
		{
			if ( g_pUsersList->isNickInList( MessageQuit->m_sNick ) )
			{
				m_pHubChat->AddStatus(tr("Parts: ") + MessageQuit->m_sNick);
			}
		}
		else
		{
			m_pHubChat->AddStatus(tr("Parts: ") + MessageQuit->m_sNick);
		}
	}

	UpdateStatusBar();

	// remove nick from nicklist
	removeCompleteNick(MessageQuit->m_sNick.Data());
}

/** nicklist */
void DCClient::DC_NickList( CMessageNickList * MessageNickList )
{
	QString s = "";
	CString * Nick = 0;
	QPixmap pm;
	DCUserItem * pui;

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

	m_pUserViewList->Clear();

	if ( MessageNickList )
	{
		while ( (Nick=MessageNickList->m_NickList.Next(Nick)) != 0 )
		{
			if ( m_pUserViewList->Get( *Nick, (CObject*&)pui ) == -1 )
			{
				pui = new DCUserItem();
				m_pUserViewList->Add(*Nick,pui);
	
#ifndef WIN32
				pm = *g_pConfig->GetUserIcon(FALSE,ecmNONE,euamNONE,eusUNKNOWN,eucvNONE);
				pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8((*Nick).Data()), pm );
#else
				pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8((*Nick).Data()) );
#endif
				pui->pItem->mycol = 5;
				pui->MyInfo.m_sNick = (*Nick);
				pui->MyInfo.m_bOperator = FALSE;
				pui->MyInfo.m_eAwayMode = euamNORMAL;
			}

			// send friend event
			if ( g_pUsersList )
			{
				DCFriendObject m_pFriendObject;

				m_pFriendObject.m_sName     = *Nick;
				m_pFriendObject.m_eAwayMode = euamONLINE;
				m_pFriendObject.m_sHubName  = GetHubName();
				m_pFriendObject.m_sHubHost  = GetIP();
				QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
			}

			// add nick to nicklist
			addCompleteNick(Nick->Data());
		}
	}

	ListView_USERLIST->setUpdatesEnabled(TRUE);
	ListView_USERLIST->triggerUpdate();

	UpdateStatusBar();
}

/** oplist */
void DCClient::DC_OpList( CMessageNickList * MessageOpList )
{
	CString * Nick = 0;
	QPixmap pm;
	DCUserItem * pui;

	ListView_USERLIST->setUpdatesEnabled(FALSE);

	while ( (Nick=MessageOpList->m_NickList.Next(Nick)) != 0 )
	{
		pui = 0;
		if ( m_pUserViewList->Get( *Nick, (CObject*&)pui ) == -1 )
		{
			pui = new DCUserItem();
			m_pUserViewList->Add(*Nick,pui);

			// user not in the list, add it
			addUser( Nick->Data() );

#ifndef WIN32
			pm = *g_pConfig->GetUserIcon(TRUE,ecmNONE,euamNONE,eusUNKNOWN,eucvNONE);
			pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8((*Nick).Data()), pm );
#else
			pui->pItem = new DC_UserListItem( ListView_USERLIST, QString::fromUtf8((*Nick).Data()) );
#endif
			pui->pItem->mycol = 5;
			pui->MyInfo.m_sNick = (*Nick);
		}
		else
		{
			if ( pui->MyInfo.m_bOperator == FALSE )
			{
#ifndef WIN32
				pm = *g_pConfig->GetUserIcon(TRUE,pui->MyInfo.m_eClientMode,pui->MyInfo.m_eAwayMode,pui->MyInfo.m_eUserSpeed,pui->MyInfo.m_eClientVersion);
				pui->pItem->setPixmap( 0, pm );
#endif
			}
		}

		pui->MyInfo.m_bOperator  = TRUE;
		pui->MyInfo.m_eAwayMode  = euamNORMAL;
		pui->pItem->m_bSortTop = TRUE;

		// add nick to nicklist
		addCompleteNick(Nick->Data());
	}

	ListView_USERLIST->setUpdatesEnabled(TRUE);
	ListView_USERLIST->triggerUpdate();

	UpdateStatusBar();
}

void DCClient::DC_PrivateChat( QString nick, QString fromnick, QString message, bool bLocal )
{
	CMessagePrivateChat msg;

	msg.m_sSrcNick      = nick.ascii();
	msg.m_sMultiSrcNick = fromnick.ascii();
	msg.m_sMessage      = message.ascii();

	DC_PrivateChat( &msg, bLocal );
}

/** */
void DCClient::DC_PrivateChat( CMessagePrivateChat * msg, bool bLocal )
{
	QWidget * focuswidget = 0;
	bool bShowChat = TRUE;

	DCChat * chat;

	if ( msg->m_sSrcNick == "" )
	{
		return;
	}
	
	// also check for ignored nick for PMs
	if ( g_pUsersList->ignoreNick( msg->m_sSrcNick ) == TRUE )
	{
		printf("Ignoring PM \"%s\" from \"%s\"\n", msg->m_sMessage.Data(), msg->m_sSrcNick.Data() );
		return;
	}

	// create a new chat window
	if( m_pChatList->Get( msg->m_sSrcNick, (CObject*&)chat ) != 0 )
	{
		focuswidget = qApp->focusWidget();

		if ( m_bUseTabWidget )
		{
			chat = new DCChat( TabWidget_CHAT, "chat", WDestructiveClose, this );
		}
		else
		{
			chat = new DCChat( m_pWorkspace, "chat", WDestructiveClose, this );
			new QListViewItem(ListView_CHATUSERLIST,QString::fromUtf8(msg->m_sSrcNick.Data()));
			TabWidget_CHAT->setTabLabel( TabWidget_CHAT->page(0), tr("Chat List")+" ("+QString().setNum(ListView_CHATUSERLIST->childCount())+")" );
		}

		// fix hide if chat maximized
		chat->show();
		chat->hide();

		chat->installEventFilter(this);
		chat->SetNick(msg->m_sSrcNick.Data(),GetHubName().Data());

		m_pChatList->Add( msg->m_sSrcNick, (CObject*)chat );

		if ( (g_pConfig->GetOpenPrivateChatWindow() == FALSE) && (bLocal == FALSE) )
		{
			bShowChat = FALSE;
		}
		// check for max lines and set chat invisible
		else if ( (g_pConfig->GetChatMessageMaxLines() > 0) &&
			  (QString(msg->m_sMessage.Data()).contains("\n") > g_pConfig->GetChatMessageMaxLines()) )
		{
			bShowChat = FALSE;
		}
		
		// check for nicks to not open chat windows
		DCConfigHubProfile pConfigHubProfile;
		QString nickregexp = "";
		
		if ( g_pConfig->GetBookmarkHubProfile( GetHubName(), GetHost(), &pConfigHubProfile ) == TRUE )
		{
			nickregexp = pConfigHubProfile.m_sSuppressedNicks.Data();
		}
		
		if (nickregexp == "")
		{
			nickregexp = g_pConfig->GetSuppressedNicks();
		}
		
		if (nickregexp != "")
		{
			QRegExp rx(nickregexp);
			rx.setCaseSensitive(FALSE);
			if (rx.search(msg->m_sSrcNick.Data()) != -1)
			{
				bShowChat = FALSE;
			}
		}
		
		if ( m_bUseTabWidget )
		{
			TabWidget_CHAT->insertTab( chat, msg->m_sSrcNick.Data() );
		}

		if ( bShowChat || bLocal )
		{
			if ( m_bUseTabWidget )
				TabWidget_CHAT->showPage(chat);
			else
				chat->setEnabled(TRUE);
			chat->show();
		}
		else
		{
			if ( !m_bUseTabWidget )
			{
				chat->setEnabled(FALSE);
				chat->hide();
			}

			// restore focus
			if ( focuswidget )
				focuswidget->setFocus();
		}

		g_pConfig->PlaySound(eusFIRSTRECEIVE);
	}
	// enable all local (user input)
	else if ( bLocal == TRUE )
	{
		if ( chat->isVisible() == FALSE )
		{
			if ( m_bUseTabWidget )
				TabWidget_CHAT->showPage(chat);
			else
				chat->setEnabled(TRUE);
			chat->show();
		}
		SetNickColor( msg->m_sSrcNick.Data(), ListView_USERLIST->colorGroup().text() );
	}

	if ( msg->m_sMessage != "" )
	{
		chat->AddMessage( msg );

		if ( chat->isVisible() == FALSE )
		{
			SetNickColor( msg->m_sSrcNick.Data(), Qt::red );

			if ( m_bUseTabWidget )
				TabWidget_CHAT->setTabIconSet( chat, QIconSet( g_pIconLoader->GetPixmap(eiMESSAGE) ) );
		}
		else
		{
			SetNickColor( msg->m_sSrcNick.Data(), ListView_USERLIST->colorGroup().text() );
		}
	}

	if ( (chat->isVisible() == FALSE) &&
	     (g_pConfig->GetSendHidePrivateChatToPublicChat() == TRUE) )
	{
		CString nick;

		// send private chat to public chat
		if ( (msg->m_sSrcNick != msg->m_sMultiSrcNick) && (msg->m_sMultiSrcNick != "") )
			nick = msg->m_sSrcNick + "::" + msg->m_sMultiSrcNick;
		else
			nick = msg->m_sSrcNick;
		m_pHubChat->AddMessage( nick.Data(), msg->m_sMessage.Data(), TRUE, TRUE );
	}
	
	// init chat view
	chat->InitView();
	
	// send chat event
	g_pConnectionManager->HubEvent(this);
	
	if (g_pConfig->GetAutoResponderEnabledForPM() == TRUE)
	{
		this->doAutoResponse( msg->m_sSrcNick.Data(), msg->m_sMessage.Data(), chat );
	}	
}

/** handling if user join the hub */
void DCClient::addUser( QString nick )
{
	DCChat * chat;

	// add nick to nicklist
	addCompleteNick(nick);

	// show joins
	if ( g_pConfig->GetChatShowJoinsAndParts() == TRUE )
	{
		if ( g_pConfig->GetChatShowJoinsAndPartsOnlyFav() == TRUE )
		{
			if ( g_pUsersList->isNickInList( nick.ascii() ) == TRUE )
			{
				m_pHubChat->AddStatus( tr("Joins: ") + CString(nick.ascii()) );
			}
		}
		else
		{
			m_pHubChat->AddStatus( tr("Joins: ") + CString(nick.ascii()) );
		}
	}

	// show rejoin on private chat
	if ( m_pChatList->Get( nick.ascii(), (CObject*&)chat ) == 0 )
	{
		chat->AddStatus(tr("User rejoin the hub.").ascii());
	}

	// send event to friendlist
	if ( g_pUsersList )
	{
		DCFriendObject m_pFriendObject;

		m_pFriendObject.m_sName     = nick.ascii();
		m_pFriendObject.m_eAwayMode = euamONLINE;
		m_pFriendObject.m_sHubName  = GetHubName();
		m_pFriendObject.m_sHubHost  = GetIP();
		QApplication::postEvent( g_pUsersList, new DC_FriendEvent( EVENT_UPDATE_FRIEND, &m_pFriendObject ) );
	}
}

/** */
void DCClient::SetNickColor( QString nick, QColor color )
{
	DC_UserListItem *item;

	if ( (item = (DC_UserListItem *)ListView_USERLIST->findItem( nick, 0 )) != 0 )
	{
		if ( item->colorText != color )
		{
			item->colorText = color;
			item->repaint();
		}
	}
}

/** */
void DCClient::CloseChat( DCChat * chat )
{
	chat->removeEventFilter(this);

	if ( m_pChatList != 0 )
	{
		m_pChatList->Remove(chat->GetNick());
	}

	if ( m_bUseTabWidget )
	{
		TabWidget_CHAT->removePage(chat);
	}
	else
	{
		QListViewItem* item;
		if ( (item = ListView_CHATUSERLIST->findItem(chat->GetNick().Data(),0)) != 0 )
		{
			ListView_CHATUSERLIST->takeItem(item);
			delete item;
			TabWidget_CHAT->setTabLabel( TabWidget_CHAT->page(0), tr("Chat List")+" ("+QString().setNum(ListView_CHATUSERLIST->childCount())+")" );
		}
	}

	chat->close();
}

/** */
void DCClient::CloseAllChats()
{
	DCChat * chat=0;

	while( m_pChatList->Next((CObject*&)chat) )
	{
		CloseChat(chat);
		chat = 0;
        }
}

/** */
void DCClient::slotDoubleClickedUserList( QListViewItem * item )
{
	if ( item == 0 )
	{
		return;
	}

	if ( g_pConfig->GetDoubleClickAction() == tr("Downloads filelist") )
	{
		g_pTransferView->DLM_QueueAdd(
			item->text(0).ascii(),
			GetHubName(),
			GetIP() + ":" + QString().setNum(GetPort()).ascii(),
			DC_USER_FILELIST_HE3,
			DC_USER_FILELIST_HE3,
			"",
			"",
			eltBUFFER,
			0,
			0,
			0,
			""
		);
	}
	else
	{
		DC_PrivateChat( item->text(0), "", "", TRUE );
	}
}

/** */
void DCClient::slotDoubleClickedChatUserList( QListViewItem * item )
{
	DCChat * chat = 0;
	QString nick;

	if ( item == 0 )
	{
		return;
	}

	nick = item->text(0);

	if ( nick == "" )
	{
		return;
	}

	if ( m_pChatList->Get( nick.ascii(), (CObject*&)chat ) == 0 )
	{
		if ( !m_bUseTabWidget )
			chat->setEnabled(TRUE);

		// take widget to top
		if ( chat->isMinimized() )
		{
			chat->showNormal();
		}
		else if ( chat->isVisible() )
		{
			// TODO: dont work fix it
			chat->show();
			chat->raise();
		}
		else
		{
			chat->show();
		}

		SetNickColor( nick, ListView_USERLIST->colorGroup().text() );
	}
}

/** */
int DCClient::selectedItems( QListView * list, CList<CString> * lst )
{
	QListViewItemIterator it( (QListView *)list );

	for ( ; it.current(); it++ )
	{
		if ( it.current()->isSelected() )
		{
			lst->Add(new CString( it.current()->text(0)) );
//			lst.append(it.current());
		}
	}

	return lst->Count();
}

/** */
void DCClient::slotHubConnect()
{
	if ( GetConnectionState() == estNONE )
	{
		SetConnection(TRUE);
		Connect();
		UpdateReconnect( ersNONE, 0 );
	}
	else if ( GetConnectionState() == estCONNECTED )
	{
		SetConnection(FALSE);
		Disconnect();
	}
}

/** */
void DCClient::slotRightButtonClickedUserList( QListViewItem *, const QPoint &, int column )
{
	int id;
	QPopupMenu *m,*mslot;
	QString username;
	CList<CString> selitems;
	CList<DC_UserMenuCommand> usercommands;
	DC_UserMenuCommand * umc = 0; 
	QListViewItem * curitem;
	CString * ps;
	int numSelected;
	QString usercommand, origUserCommand;

	numSelected = selectedItems(ListView_USERLIST,&selitems);

	m = new QPopupMenu(this);

	if ( numSelected == 1 )
	{
		curitem = ListView_USERLIST->currentItem();
		username = curitem->text(0);
		DCMenuHandler::InsertMenu( m, emiUSER_CAPTION, FALSE, tr("User: ") + username );
	}
	else
	{
		QString numUsers;
		numUsers.setNum(numSelected);
		DCMenuHandler::InsertMenu( m, emiUSER_CAPTION, FALSE, numUsers + tr(" users") );
	}

	DCMenuHandler::InsertMenu( m, emiSEPARATOR );
	DCMenuHandler::InsertMenu( m, emiPRIVATE_CHAT, (numSelected > 0) );
	DCMenuHandler::InsertMenu( m, emiADD_FRIEND, (numSelected > 0) );
	DCMenuHandler::InsertMenu( m, emiBROWSE_USER_FILES, (numSelected > 0) );
	DCMenuHandler::InsertMenu( m, emiSEPARATOR );
	
	mslot = DCMenuHandler::InsertMenu( m, emiUPLOAD_SLOT, TRUE );
	DCMenuHandler::InsertMenu( mslot, emiADD, (numSelected > 0) );
	DCMenuHandler::InsertMenu( mslot, emiADD_PERMANENT, (numSelected > 0) );
	DCMenuHandler::InsertMenu( mslot, emiREMOVE, (numSelected > 0) );

	DCMenuHandler::InsertMenu( m, emiSEPARATOR );
	DCMenuHandler::InsertMenu( m, emiUPDATE_USER, (numSelected > 0) );
	DCMenuHandler::InsertMenu( m, emiRELOAD_USERLIST, (GetConnectionState() == estCONNECTED) );
	DCMenuHandler::InsertMenu( m, emiSEPARATOR );
	DCMenuHandler::InsertMenu( m, emiCOPY_COLUMN_TO_CLIPBOARD, (numSelected == 1) );
	DCMenuHandler::InsertMenu( m, emiCOPY_ROW_TO_CLIPBOARD, (numSelected == 1) );

	DCMenuHandler::InsertMenu( m, emiSEPARATOR );
	DCMenuHandler::InsertMenu( m, emiCHECK_CLIENT_VERSION, numSelected > 0 );

	if ( UserList()->IsAdmin(GetNick()) )
	{
		DCMenuHandler::InsertMenu( m, emiKICK, UserList()->IsAdmin(GetNick()) && (numSelected > 0) );
		DCMenuHandler::InsertMenu( m, emiFORCE_MOVE, UserList()->IsAdmin(GetNick()) && (numSelected > 0) );
		DCMenuHandler::InsertMenu( m, emiGET_USER_IP, UserList()->IsAdmin(GetNick()) && (numSelected > 0) && GetSupportsUserIP2() );
	}
	
	DCMenuHandler::InsertMenu( m, emiSEPARATOR );

	g_pConfig->GetUserMenuCommands(&usercommands);
	
	while( (umc=usercommands.Next(umc)) != 0 )
	{
		if ( (umc->m_nContext & 2) == 2 )
		{
			umc->m_nID = m->insertItem(umc->m_sName.Data(), -1);
			m->setItemEnabled( umc->m_nID, numSelected > 0 );
		}
	}
	
	id = m->exec(QCursor::pos());

	delete m;

	if ( id == emiPRIVATE_CHAT )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			DC_PrivateChat( QString::fromUtf8(ps->Data()), "", "", TRUE );
		}
	}
	else if ( id == emiADD_FRIEND )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			g_pUsersList->AddFriend( ps->Data(), GetHubName(), GetIP(), "" );
		}
	}
	else if ( id == emiBROWSE_USER_FILES )
	{
		if ( GetMode() == ecmNONE )
		{
			return;
		}

		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			/** add transfer to the waitlist */
			g_pTransferView->DLM_QueueAdd( ps->Data(), GetHubName(), GetIP()+":"+QString().setNum(GetPort()).ascii(),
						DC_USER_FILELIST_HE3, DC_USER_FILELIST_HE3, "", "", eltBUFFER,
						0, 0, 0, "" );
		}
	}
	else if ( id == emiCHECK_CLIENT_VERSION )
	{
		if ( GetMode() == ecmNONE )
		{
			return;
		}

		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			/** add transfer to the waitlist */
			g_pTransferView->DLM_QueueAdd( ps->Data(), GetHubName(), GetIP()+":"+QString().setNum(GetPort()).ascii(),
						"client check", "client check", "", "", eltCLIENTVERSION,
						0, 0, 0, "" );
		}
	}
	else if ( id == emiUPDATE_USER )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			SendGetInfo( *ps, GetNick() );
		}
	}
	else if ( id == emiCOPY_COLUMN_TO_CLIPBOARD )
	{
		QListViewItem *item1;
		QClipboard *cb = QApplication::clipboard();
		cb->setText("");

		if ( (item1=ListView_USERLIST->currentItem()) != 0 )
		{
			cb->setText( item1->text(column) );
		}
	}
	else if ( id == emiCOPY_ROW_TO_CLIPBOARD )
	{
		int idx;
		QString s="";
		QListViewItem *item1;
		QClipboard *cb = QApplication::clipboard();
		cb->setText("");

		if ( (item1=ListView_USERLIST->currentItem()) != 0 )
		{
			for( idx = 0; idx < ListView_USERLIST->columns(); idx++ )
			{
				s += item1->text(idx) + "\n";
			}
			cb->setText(s);
		}
	}
	else if ( id == emiADD )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			g_pTransferView->DLM_AddUserSlot(*ps, GetHubName(), 1);
		}
	}
	else if ( id == emiADD_PERMANENT )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			g_pTransferView->DLM_AddUserSlot(*ps, GetHubName(), 0);
			g_pTransferView->DLM_AddUserSlot(*ps, GetHubName(), 0, TRUE);
		}
	}
	else if ( id == emiREMOVE )
	{
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			g_pTransferView->DLM_AddUserSlot(*ps, GetHubName(), 0);
		}
	}
	else if ( id == emiKICK )
	{
		QString kickmessage;

		if ( !GetOPKickMessage(kickmessage) )
		{
			return;
		}
		
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			OPKick( ps->Data(), kickmessage );
		}
	}
	else if ( id == emiFORCE_MOVE )
	{
		QString host,message;

		if ( !GetOPForceMoveMessage(message,host) )
		{
			return;
		}
				
		for(ps=0;(ps=selitems.Next(ps)) != 0;)
		{
			OPForceMove( ps->Data(), message, host );
		}
	}
	else if ( id == emiGET_USER_IP )
	{
		for( ps=0; (ps=selitems.Next(ps)) != 0; )
		{
			SendString( CString("$UserIP ") + ps->Data() + CString("|") );
		}
	}
	else if ( id == emiRELOAD_USERLIST )
	{
		RequestNickList();
	}
	else
	{
		umc = 0;
		while( (umc=usercommands.Next(umc)) != 0 )
		{
			if ( id == umc->m_nID )
			{
				usercommand = umc->m_sCommand.Data();
				
				origUserCommand = usercommand;
				
				for(ps=0;(ps=selitems.Next(ps)) != 0;)
				{
					usercommand = replaceCommandTags( origUserCommand, ps->Data() );
					
					m_pHubChat->AddStatus(usercommand.ascii());
					SendString(usercommand.ascii());
				}
			}
		}
	}
}

void DCClient::slotSaveColumnWidth(int section, int oldSize, int newSize)
{
	eClientColumn mapped_section;

	if (section == 0)
		mapped_section = eclcNICK;
	else
		mapped_section = eClientColumn(section - 1);
	g_pConfig->SetClientColumnWidth( mapped_section, newSize );
}

/** */
bool DCClient::GetOPKickMessage( QString & message )
{
	bool ok = FALSE;

	message = QInputDialog::getText(
		tr("OP Kick"),
		tr("Please enter a reason"),
		QLineEdit::Normal, QString::null, &ok, 0 );

	return ok;
}

/** */
bool DCClient::GetOPForceMoveMessage( QString & message, QString & host )
{
	bool ok = FALSE;

	host = QInputDialog::getText(
		tr("OP Force Move"),
		tr("Please enter host"),
		QLineEdit::Normal, QString::null, &ok, 0 );

	if ( !ok )
	{
		return ok;
	}

	ok = FALSE;

	message = QInputDialog::getText(
		tr("OP Force Move"),
		tr("Please enter a message"),
		QLineEdit::Normal, QString::null, &ok, 0 );

	return ok;
}

/** */
bool DCClient::OPKick( QString nick, QString message )
{
	bool res = FALSE;

	SendPrivateMessage( GetNick(), nick.ascii(), ("You are being kicked because: " + message).ascii());
	SendChat( GetNick(), GetNick() + " is kicking " + nick.ascii() + " because: " + message.ascii() );
	SendKick(nick.ascii());

	return res;
}

/** */
bool DCClient::OPForceMove( QString nick, QString message, QString host )
{
	bool res = FALSE;

	SendOpForceMove( nick.ascii(), host.ascii(), message.ascii() );

	return res;
}

/** */
void DCClient::slotDoubleClickedUserChat( QListBoxItem * item )
{
	DCChat * chat;
	QString nick;

	if ( item == 0 )
	{
		return;
	}

	nick = item->text();

	if ( nick == "" )
	{
		return;
	}

	if ( m_pChatList->Get( nick.ascii(), (CObject*&)chat ) == 0 )
	{
		if ( !m_bUseTabWidget )
			chat->setEnabled(TRUE);
		chat->show();
		SetNickColor( nick, ListView_USERLIST->colorGroup().text() );
        }
}

/** */
void DCClient::addCompleteNick( QString nick )
{
	QStringList::Iterator it = m_completeNicks.find(nick);

	if (it != m_completeNicks.end())
		m_completeNicks.remove(it);

	m_completeNicks.prepend(nick);
}

/** */
void DCClient::removeCompleteNick( QString nick )
{
	m_completeNicks.remove(nick);
}

/** */
QString DCClient::findNick( QString part, uint which )
{
	QStringList matches;
	QString lpart = part.lower();
	
	for (QStringList::ConstIterator it = m_completeNicks.begin(); it != m_completeNicks.end(); ++it)
	{
		if ( (*it).lower().find(lpart) != -1 )
			matches.append(*it);
	}
/*
	for(uint i=0; i < nicks->count(); i++)
	{
		if (matches.contains(nicks->text(i)))
			continue;
		if(qstrlen(nicks->text(i)) >= part.length())
		{
			if(qstrnicmp(part, nicks->text(i), part.length()) == 0)
			{
				QString qsNick = ksopts->nick;
				if(qstrcmp(nicks->text(i), qsNick) != 0)
				{ // Don't match your own nick
					matches.append(nicks->text(i));
				}
			}
		}
	}
*/
	if(matches.count() > 0)
	{
		if(which < matches.count())
			return *(matches.at(which));
		else
			return QString::null;
	}

	return part;
}

void DCClient::slotTabCornerCloseWidgetClicked()
{
	CloseChat( (DCChat*) TabWidget_CHAT->currentPage() );
}

/** Replaces the %[tag] s in the command with the proper values */
QString DCClient::replaceCommandTags(QString command, QString remotenick)
{
	QString usercommand = command;
	
	usercommand.replace( "%[mynick]", GetNick().Data() );
	usercommand.replace( "%[myNI]", GetNick().Data() );
	
	QString comtag = GetComment().Data();
	QString comment = comtag.mid(0, comtag.find('<'));
	QString tag = comtag.mid(comtag.find('<'));
	
	usercommand.replace( "%[mytag]", tag );
	usercommand.replace( "%[myTAG]", tag );
	
	usercommand.replace( "%[mydescription]", comment );
	usercommand.replace( "%[myDE]", comment );
	
	usercommand.replace( "%[myemail]", GetEMail().Data() );
	usercommand.replace( "%[myEM]", GetEMail().Data() );
	
	usercommand.replace( "%[myshare]", GetShareSize().Data() );
	usercommand.replace( "%[mySS]", GetShareSize().Data() );
	
	usercommand.replace( "%[myshareshort]", CUtils::GetSizeString(GetShareSize().asULL(), euAUTO).Data() );
	usercommand.replace( "%[mySSshort]", CUtils::GetSizeString(GetShareSize().asULL(), euAUTO).Data() );
	
	usercommand.replace( "%[myip]", g_pConfig->GetTCPHostString( FALSE ).Data() );
	usercommand.replace( "%[myI4]", g_pConfig->GetTCPHostString( FALSE ).Data() );
	
	usercommand.replace( "%[nick]", remotenick );
	usercommand.replace( "%[userNI]", remotenick );
	
	QListViewItem * item = ListView_USERLIST->findItem(remotenick ,0);
	
	if ( item == 0 )
	{
		//printf("Warning: nick \"%s\" not found in userlist.\n", remotenick.ascii());
	}
	else
	{
		usercommand.replace( "%[userTAG]", item->text(2) );
		usercommand.replace( "%[tag]", item->text(2) );
		
		usercommand.replace( "%[userDE]", item->text(1) );
		usercommand.replace( "%[description]", item->text(1) );
		
		usercommand.replace( "%[userSS]", QString().setNum(((DC_UserListItem*)item)->myvalue) );
		usercommand.replace( "%[share]", QString().setNum(((DC_UserListItem*)item)->myvalue) );
		
		usercommand.replace( "%[userSSshort]", item->text(5) );
		usercommand.replace( "%[shareshort]", item->text(5) );
		
		usercommand.replace( "%[userEM]", item->text(4) );
		usercommand.replace( "%[email]", item->text(4) );
		
		usercommand.replace( "%[userI4]", item->text(6) );
		usercommand.replace( "%[ip]", item->text(6) );
	}
	
	while ( usercommand.find("%[line:") != -1 )
	{
		bool ok;
		int loc = usercommand.find("%[line:");
		int end = usercommand.find("]", loc);
		
		// 7 is length of "%[line:"
		QString reason = usercommand.mid(loc + 7, end - (loc + 7));
		
		QString text = QInputDialog::getText(
		tr("User command for ") + remotenick,
		reason,
		QLineEdit::Normal,
		QString::null,
		&ok,
		this
		);
	
		//if ( ok && !text.isEmpty() )
		//{
			usercommand.replace( "%[line:" + reason + "]", text );
		//}
	}
					
	{
		struct tm * t;
		time_t ti;
		char timed[2048];
						
		ti = time(0);
		t  = localtime(&ti);
		strftime(timed, sizeof(timed), usercommand.ascii(), t);
		usercommand = timed;
	}
	
	return usercommand;
}

void DCClient::doAutoResponse( QString nick, QString message, DCChat * chatobject )
{
	long delay = g_pConfig->GetAutoResponseDelay();
	long now = QDateTime::currentDateTime().toTime_t();
	
	if ( (delay > 0) &&
	     (nick == lastAutoNick) &&
	     (now < delay + lastAutoResponseTime)
	   )
	{
		// avoid spamming
		//printf("Auto response spam protection!\n");
		return;
	}
	
	// null pointer check
	if (chatobject == 0)
	{
		printf("Error: DCClient::doAutoResponse called with NULL chatobject!\n");
		return;
	}
	
	// do not respond to ourself
	if (nick == this->GetNick())
	{
		//printf("Not auto-responding to ourself.\n");
		return;
	}
	
	// check for ignored nicks
	CString ignores = g_pConfig->GetAutoResponseIgnores();
	if (ignores != "")
	{
		QRegExp ignore_re;
		ignore_re.setPattern(ignores.Data());
		ignore_re.setCaseSensitive(FALSE);
		if (ignore_re.search(nick) != -1)
		{
			//printf("Not auto responding to %s\n", nick.ascii());
			return;
		}
	}
	
	CList<DC_AutoResponseObject> arlist;
	DC_AutoResponseObject * aro = 0;
	
	g_pConfig->GetAutoResponses(&arlist);
	
	QRegExp re;
	
	while ((aro=arlist.Next(aro)) != 0)
	{
		re.setPattern(aro->m_sTrigger.Data());
		re.setCaseSensitive(aro->m_bCaseSensitive);
		if (re.search(message) != -1) // pattern matches
		{
			QString chat = this->replaceCommandTags( aro->m_sResponse.Data(), nick );
			//this->SendChat( this->GetNick(), chat.ascii() );
			chatobject->TextEdit_CHATINPUT->setText(chat);
			chatobject->SendMessage( "" );
			
			// update last nick and time for anti-spam
			lastAutoNick = nick;
			lastAutoResponseTime = QDateTime::currentDateTime().toTime_t();
			
			// stop searching list of triggers
			break;
		}
	}
}
