/***************************************************************************
                          dcconfig.cpp  -  description
                             -------------------
    begin                : Fri Mar 1 2002
    copyright            : (C) 2002 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 <qstringlist.h>
#include <qregexp.h>
#include <qprocess.h>
#include <qsound.h>
#include <qpixmap.h>
#include <qimage.h>

#include <dclib/core/cbytearray.h>
#include <dclib/core/cstring.h>
#include <dclib/core/cthread.h>
#include <dclib/dcobject.h>
#include <dclib/core/che3.h>
#include <dclib/core/cxml.h>
#include <dclib/core/csocket.h>
#include <dclib/core/cstringlist.h>

#include <dcuserslist.h>
#include <dciconloader.h>

#include "dcconfig.h"

#include <dclib/dcos.h>

// mac stuff
#if defined(Q_OS_MACX) 
#include <CoreFoundation/CoreFoundation.h> 
#endif 

// config files
#define DCGUI_CONFIG		"dcgui.cfg"
#define DCGUI_HUBFILTER		"dchubfilter.cfg"
#define DCGUI_FRIENDLIST	"dcfriendlist.cfg"

#define XML_DCGUI_CONFIG	"dcgui"
#define XML_DCGUI_HUBFILTER	"dchubfilter"
#define XML_DCGUI_FRIENDLIST	"dcfriendlist"

#define XML_GUI				"gui"
#define XML_OPENPRIVATECHATWIN		"openprivatechatwindow"
#define XML_UNIT			"unit"
#define XML_THEME			"theme"
#define XML_LANGUAGEFILE		"languagefile"
#define XML_APP_FONT			"appfont"
#define XML_APP_WIDTH			"appwidth"
#define XML_APP_HEIGHT			"appheight"
#define XML_TV_WIDTH			"tvwidth"
#define XML_TV_HEIGHT			"tvheight"
#define XML_TV_DOCKED			"tvdocked"
#define XML_TABBAR			"tabbar"
#define XML_TOOLBAR			"toolbar"
#define XML_STATUSBAR			"statusbar"
#define XML_EXTERNAL_SOUND_PLAYER	"externalsoundplayer"
#define XML_EXTERNAL_PLAYER		"externalplayer"
#define XML_SOUND_FILE_CONNECT		"soundfileconnect"
#define XML_SOUND_FILE_DISCONNECT	"soundfiledisconnect"
#define XML_SOUND_FILE_SEND		"soundfilesend"
#define XML_SOUND_FILE_RECEIVE		"soundfilereceive"
#define XML_SOUND_FILE_FIRSTRECEIVE	"soundfilefirstreceive"
#define XML_SOUND_FILE_NICK_MENTIONED	"soundnickmentioned"
#define XML_SOUND_ENABLED_CONNECT	"soundenabledconnect"
#define XML_SOUND_ENABLED_DISCONNECT	"soundenableddisconnect"
#define XML_SOUND_ENABLED_SEND		"soundenabledsend"
#define XML_SOUND_ENABLED_RECEIVE	"soundenabledreceive"
#define XML_SOUND_ENABLED_FIRSTRECEIVE	"soundenabledfirstreceive"
#define XML_SOUND_ENABLED_NICK_MENTIONED	"soundenablednickmentioned"
#define XML_SOUND_DISABLED		"sounddisabled"
#define XML_SOUND_DISABLED_AWAY		"sounddisabledaway"
#define XML_TIMESTAMP_PRIVATECHAT	"timestampprivatechat"
#define XML_TIMESTAMP_HUBCHAT		"timestamphubchat"
#define XML_SHOW_STATUS_MESSAGE		"showstatusmessage"
#define XML_SHOW_TRANSFER_WIN		"showtransferwin"
#define XML_SEND_HIDE_PRIVATE_CHAT_TO_PUBLIC_CHAT "sendhideprivatechattopublicchat"
#define XML_CHAT_MESSAGE_MAX_LINES	"chatmessagemaxlines"
#define XML_DEFAULTDOWNLOADMODE		"defaultdownloadmode"
#define XML_EMOTICONS			"emoticons"
#define XML_SENDCHAT			"sendchat"
#define XML_ENABLETRAY			"enabletray"
#define XML_QUERYONEXIT			"queryonexit"
#define XML_QUERYONFILEDELETE		"queryonfiledelete"
#define XML_SHOWCHATSENDBUTTON		"showchatsendbutton"
#define XML_CHATMAXPARAGRAPH		"chatmaxparagraph"
#define XML_DEFAULTFBREMOTEENCODING	"defaultfilelistremoteencoding"
#define XML_VALKNUT_DATA_PATH		"valknutdatapath"

#define XML_APP_ICON_THEME		"appicontheme"
#define XML_EMOTICON_THEME		"emoticontheme"
#define XML_USER_ICON_THEME		"userlisticontheme"

#define XML_TV_CHUNKPERCENT		"tvchunkpercent"
#define XML_TV_FILEPERCENT		"tvfilepercent"
#define XML_TV_CHUNKSIZE		"tvchunksize"
#define XML_TV_FILESIZE			"tvfilesize"
#define XML_TV_DOWNLOADRATESINGLE	"tvdownloadratesingle"
#define XML_TV_ELAPSEDTIMESINGLE	"tvelapsedtimesingle"
#define XML_TV_DOWNLOADRATEMULTI	"tvdownloadratemulti"
#define XML_TV_ELAPSEDTIMEMULTI		"tvelapsedtimemulti"

#define XML_NAME			"name"
#define XML_ENTRY			"entry"
#define XML_SECTION			"section"
#define XML_SIZE			"size"
#define XML_POS				"pos"

#define XML_FILTER			"filter"
#define XML_FILTERNAME			"filtername"
#define XML_CONTAINS			"contains"
#define XML_USER			"user"
#define XML_SERVER			"server"
#define XML_DESCRIPTION			"description"
#define XML_USERLISTRIGHTALIGNMENT	"userlistrightalignment"
#define XML_BACKGROUNDPIXMAP		"backgroundpixmap"
#define XML_BROWSER			"browser"
#define XML_SHOWCHATINTAB		"showchatintab"
#define XML_OPENCLIENTWINDOWSMINIMIZED	"openclientwindowsminimized"

#define XML_FLOODCOUNT			"floodcount"
#define XML_FLOODOPKICK			"floodopkick"
#define XML_FLOODKICKMESSAGE		"floodkickmessage"

#define XML_LCO_ENABLELOGGING			"LCO_ENABLELOGGING"
#define XML_LCO_APPENDDATE			"LCO_APPENDDATE"
#define XML_LCO_APPENDHUBNAME			"LCO_APPENDHUBNAME"
#define XML_LCO_APPENDHUBHOST			"LCO_APPENDHUBHOST"
#define XML_LCO_DISABLEPUBLICCHAT		"LCO_DISABLEPUBLICCHAT"
#define XML_LCO_ENABLENICKNAMEFILTER		"LCO_ENABLENICKNAMEFILTER"
#define XML_LCO_NICKNAMEFILTER_ENABLELOGGING	"LCO_NICKNAMEFILTER_ENABLELOGGING"

#define XML_CC_CHATTIMESTAMP			"CC_CHATTIMESTAMP"
#define XML_CC_CHATLOCALNICK			"CC_CHATLOCALNICK"
#define XML_CC_CHATLOCALTEXT			"CC_CHATLOCALTEXT"
#define XML_CC_CHATREMOTENICK			"CC_CHATREMOTENICK"
#define XML_CC_CHATREMOTETEXT			"CC_CHATREMOTETEXT"
#define XML_CC_CHATSTATUSNICK			"CC_CHATSTATUSNICK"
#define XML_CC_CHATSTATUSTEXT			"CC_CHATSTATUSTEXT"
#define XML_CC_PUBLICCHATTIMESTAMP		"CC_PUBLICCHATTIMESTAMP"
#define XML_CC_PUBLICCHATLOCALNICK		"CC_PUBLICCHATLOCALNICK"
#define XML_CC_PUBLICCHATLOCALTEXT		"CC_PUBLICCHATLOCALTEXT"
#define XML_CC_PUBLICCHATREMOTENICK		"CC_PUBLICCHATREMOTENICK"
#define XML_CC_PUBLICCHATREMOTETEXT		"CC_PUBLICCHATREMOTETEXT"
#define XML_CC_PUBLICCHATSTATUSNICK		"CC_PUBLICCHATSTATUSNICK"
#define XML_CC_PUBLICCHATSTATUSTEXT		"CC_PUBLICCHATSTATUSTEXT"
#define XML_CC_PUBLICPRIVATECHATNICK		"CC_PUBLICPRIVATECHATNICK"
#define XML_CC_PUBLICPRIVATECHATTEXT		"CC_PUBLICPRIVATECHATTEXT"
#define XML_CC_CHATSAY				"CC_CHATSAY"
#define XML_CC_PUBLICCHATMENICK			"CC_PUBLICCHATMENICK"
#define XML_CC_OPNICK				"CC_OPNICK"

#define XML_CLIENT_COLUMN_COMMENT		"clientcolumncomment"
#define XML_CLIENT_COLUMN_TAG			"clientcolumntag"
#define XML_CLIENT_COLUMN_SPEED			"clientcolumnspeed"
#define XML_CLIENT_COLUMN_EMAIL			"clientcolumnemail"
#define XML_CLIENT_COLUMN_SHARE			"clientcolumnshare"
#define XML_CLIENT_COLUMN_IP			"clientcolumnip"
#define XML_CLIENT_COLUMN_LOCKPK		"clientcolumnlockpk"
#define XML_CLIENT_COLUMN_SUPPORTS		"clientcolumnsupports"

#define XML_AUTO_AWAY_MODE		"autoawaymode"
#define XML_AUTO_AWAY_TIME		"autoawaytime"
#define XML_CHAT_SHOW_JOINS_AND_PARTS	"chatshowjoinsandparts"
#define XML_CHAT_SHOW_JOINS_AND_PARTS_ONLY_FAV	"chatshowjoinsandpartsonlyfav"
#define XML_CHAT_SUPPRESSED_NICKS	"suppressednicks"
#define XML_DOUBLE_CLICK_ACTION		"doubleclickaction"

#define XML_FRIEND			"friend"
#define XML_IMAGE			"image"
#define XML_SEND_IMAGE			"sendimage"
#define XML_AUTO_SEC			"autosec"
#define XML_USER_PHOTO			"userphoto"
#define XML_PERM_SLOT			"permslot"
#define XML_IGNORE			"ignore"

#define XML_USERCHATCOMMAND		"userchatcommand"
#define XML_USERCHATCOMMAND_NAME	"command_name"
#define XML_USERCHATCOMMAND_ACT		"command_action"

#define XML_UNIT_AUTO	"auto"
#define XML_UNIT_BYTE	"byte"
#define XML_UNIT_KBYTE	"kbyte"
#define XML_UNIT_MBYTE	"mbyte"
#define XML_UNIT_GBYTE	"gbyte"

#define XML_USERMENUCOMMAND		"usermenucommand"
#define XML_USERMENUCOMMAND_NAME	"command_name"
#define XML_USERMENUCOMMAND_ACT		"command_action"
#define XML_USERMENUCOMMAND_CONTEXT	"command_context"

#define XML_AUTORESPONSE_ENABLED	"autoresponse_enabled"
#define XML_AUTORESPONSE_ENABLED_PM	"autoresponse_enabled_pm"
#define XML_AUTORESPONSE		"autoresponse"
#define XML_AUTORESPONSE_TRIGGER	"trigger"
#define XML_AUTORESPONSE_RESPONSE	"response"
#define XML_AUTORESPONSE_CASE_SENS	"case_sensitive"
#define XML_AUTORESPONSE_DELAY		"autoresponse_delay"
#define XML_AUTORESPONSE_IGNORES	"autoresponse_ignores"

#define XML_FILELIST_NAMING_SCHEME	"filelist_naming_scheme"

#define XML_FOLDERS_RIGHT_PANE		"folders_in_right_pane"
#define XML_SIZES_IN_LEFT_PANE		"sizes_in_left_pane"
#define XML_FOLDERS_RIGHT_PANE_ON_TOP	"folders_in_right_pane_on_top"

DCConfig * g_pConfig = 0;

DCConfig::DCConfig( CString configpath ) : CConfig(configpath)
{
	// gui defaults
	bOpenPrivateChatWindow	= TRUE;
	m_eUnit			= euAUTO;
	sTheme			= "Default";
	sLanguageFile		= "";
	sAppFont		= DEFAULT_APP_FONT;
	iAppHeight		= 480;
	iAppWidth		= 640;
	iTransferViewHeight     = 100;
	iTransferViewWidth      = 640;
	bTransferViewDocked     = TRUE;
	bTabBar			= TRUE;
	bToolBar		= TRUE;
	bStatusBar		= TRUE;

	sSoundFileConnect	= "";
	sSoundFileDisconnect	= "";
	sSoundFileSend		= "";
	sSoundFileReceive	= "";
	sSoundFileFirstReceive	= "";
	sSoundFileNickMentioned = "";

	bSoundDisabled		= TRUE;
	bSoundDisabledAway	= TRUE;

	bSoundEnabledConnect	= TRUE;
	bSoundEnabledDisconnect	= TRUE;
	bSoundEnabledSend	= TRUE;
	bSoundEnabledReceive	= TRUE;
	bSoundEnabledFirstReceive = TRUE;
	bSoundEnabledNickMentioned = TRUE;

	bEnableEmoticons        = TRUE;
	bTimeStampPrivateChat	= TRUE;
	bTimeStampHubChat	= TRUE;
	bShowStatusMessage      = TRUE;
	bShowTransferWin        = FALSE;
	sSendChat		= "Enter";

	bExternalSoundPlayer	= FALSE;
	sExternalPlayer		= "";

	bTVChunkPercent         = FALSE;
	bTVFilePercent          = TRUE;
	bTVChunkSize            = FALSE;
	bTVFileSize             = TRUE;
	bTVDownloadRateSingle   = FALSE;
	bTVElapsedTimeSingle    = FALSE;
	bTVDownloadRateMulti    = TRUE;
	bTVElapsedTimeMulti     = TRUE;
	bThemeSupport           = TRUE;
	bUserListRightAlignment = TRUE;

	m_bClientColumnComment  = TRUE;
	m_bClientColumnTag      = TRUE;
	m_bClientColumnEMail    = TRUE;
	m_bClientColumnSpeed    = TRUE;
	m_bClientColumnShare    = TRUE;
	m_bClientColumnIP       = FALSE;
	m_bClientColumnLOCKPK   = FALSE;
	m_bClientColumnSUPPORTS = FALSE;

	iClientColumnNick     = 0;
	iClientColumnComment  = 0;
	iClientColumnTag      = 0;
	iClientColumnEMail    = 0;
	iClientColumnSpeed    = 0;
	iClientColumnShare    = 0;
	iClientColumnIP       = 0;
	iClientColumnLOCKPK   = 0;
	iClientColumnSUPPORTS = 0;

	m_bAutoAwayMode         = FALSE;
	m_nAutoAwayTime         = 300;

	m_bChatShowJoinsAndParts = FALSE;
	m_bChatShowJoinsAndPartsOnlyFav = FALSE;
	bSendHidePrivateChatToPublicChat = TRUE;

	m_UserIconCache = QPixmap("");
	m_nUICX = -2;
	m_nUICY = -2;

	iChatMessageMaxLines = 0;
	
	iFloodCount    = 3;
	m_bFloodOpKick = FALSE;
	
	m_pMimeSourceFactory = 0;

	pProcess = new QProcess ();

	iDefaultDownloadMode = 0;

	m_bEnableTray = TRUE;
	bQueryOnExit = FALSE;
	bQueryOnFileDelete = TRUE;
	bShowChatSendButton = TRUE;
	sBackgroundPixmap = "";
	sBrowser = "konqueror";
	bShowChatInTab = TRUE;
	m_nChatMaxParagraph = 0;
	bOpenClientWindowsMinimized = FALSE;
	m_EmoticonSettingList = 0;

	m_sDefaultFBRemoteEncoding = "DEFAULT";

	m_bLogChatOption_1 = FALSE;
	m_bLogChatOption_2 = FALSE;
	m_bLogChatOption_3 = FALSE;
	m_bLogChatOption_4 = FALSE;
	m_bLogChatOption_5 = FALSE;
	m_bLogChatOption_6 = FALSE;
	m_bLogChatOption_7 = FALSE;

	m_sChatColor_1  = "#000000";
	m_sChatColor_2  = "#005500";
	m_sChatColor_3  = "#000000";
	m_sChatColor_4  = "#ac0000";
	m_sChatColor_5  = "#000000";
	m_sChatColor_6  = "#ff0000";
	m_sChatColor_7  = "#000000";
	m_sChatColor_8  = "#000000";
	m_sChatColor_9  = "#005500";
	m_sChatColor_10 = "#000000";
	m_sChatColor_11 = "#ac0000";
	m_sChatColor_12 = "#000000";
	m_sChatColor_13 = "#ff0000";
	m_sChatColor_14 = "#000000";
	m_sChatColor_15 = "#ffff00";
	m_sChatColor_16 = "#000000";
	m_sChatColor_17 = "#0000ff";
	m_sChatColor_18 = "#ff0c52";
	m_sChatColor_19 = "#000000";

	m_sApplicationIconTheme = "default";
	m_sEmoticonTheme        = "default";
	m_sUserListIconTheme    = "default";
	
	m_sSuppressedNicks	= "Hub";
	
	// auto responder defaults to disabled
	m_bAutoResponderEnabled = FALSE;
	m_bAutoResponderEnabledForPM = FALSE;
	m_nAutoResponseDelay = 5;
	m_sAutoResponseIgnores = "";
	
	/* 0 = 0.3.8 integers
	 * 1 = 0.3.9 base64 encoded
	 * 2 = 0.3.10 human readable
	 */
	m_nFilelistNamingSchemeVersion = 0;
	
	m_bFoldersInRightPane = FALSE;
	m_bFolderSizesInLeftPane = TRUE;
	m_bFoldersInRightPaneOnTop = FALSE;

#if defined(Q_OS_MACX) 
	CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); 
	CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, kCFURLPOSIXPathStyle); 
	const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()); 

	SetValknutDataPath(pathPtr); 
#endif 

	if ( m_sValknutDataPath == "" )
#ifdef WIN32
		m_sValknutDataPath = GetDCLibDataPath().Data();
#else
		m_sValknutDataPath = VALKNUT_DATAPATH;
#endif
	g_pConfig = this;
}

DCConfig::~DCConfig()
{
	g_pConfig = NULL;
	
	delete pProcess;

	if ( m_pMimeSourceFactory )
	{
		QMimeSourceFactory::removeFactory(m_pMimeSourceFactory);
		delete m_pMimeSourceFactory;
	}

	if ( m_EmoticonSettingList )
	{
		delete m_EmoticonSettingList;
	}

	m_guiSettingMap.clear();

	m_EmoticonImage.reset();
}

/** */
void DCConfig::ParseDCGuiConfig( xmlNodePtr node )
{
	xmlNodePtr n1,n2,n3,n4;
	CXml xml;
	CString xml_name, xml_tmp;

	for(n1=node;n1!=0;n1=n1->next)
	{
		/* gui entrys */
		if ( xml.name(n1) == XML_GUI )
		{
			for(n2=n1->xmlChildrenNode;n2!=0;n2=n2->next)
			{
				xml_name = xml.name(n2);
				if ( xml_name == XML_OPENCLIENTWINDOWSMINIMIZED )
					bOpenClientWindowsMinimized = xml.getBoolChild(n2);
				else if ( xml_name == XML_OPENPRIVATECHATWIN )
					bOpenPrivateChatWindow = xml.getBoolChild(n2);
				else if ( xml_name == XML_CHATMAXPARAGRAPH )
					m_nChatMaxParagraph = xml.content(n2).asLONG();
				else if ( xml_name == XML_EMOTICONS )
				        bEnableEmoticons = xml.getBoolChild(n2);
				else if ( xml_name == XML_USER_PHOTO )
				        m_sUserPhotoFileName = xml.content(n2);
				else if ( xml_name == XML_TABBAR )
				        bTabBar = xml.getBoolChild(n2);
				else if ( xml_name == XML_TOOLBAR )
				        bToolBar = xml.getBoolChild(n2);
				else if ( xml_name == XML_STATUSBAR )
					bStatusBar = xml.getBoolChild(n2);
				else if ( xml_name == XML_USERLISTRIGHTALIGNMENT )
					bUserListRightAlignment = xml.getBoolChild(n2);
				else if ( xml_name == XML_SHOWCHATSENDBUTTON )
					bShowChatSendButton = xml.getBoolChild(n2);
				else if ( xml_name == XML_UNIT )
				{
					xml_tmp = xml.content(n2);
					if ( xml_tmp == XML_UNIT_AUTO )
						m_eUnit = euAUTO;
					else if ( xml_tmp == XML_UNIT_BYTE )
						m_eUnit = euBYTE;
					else if ( xml_tmp == XML_UNIT_KBYTE )
						m_eUnit = euKBYTE;
					else if ( xml_tmp == XML_UNIT_MBYTE )
						m_eUnit = euMBYTE;
					else if ( xml_tmp == XML_UNIT_GBYTE )
						m_eUnit = euGBYTE;
				}
				else if ( xml_name == XML_THEME )
					sTheme = xml.content(n2);
				else if ( xml_name == XML_BACKGROUNDPIXMAP )
					sBackgroundPixmap = xml.content(n2);
				else if ( xml_name == XML_BROWSER )
					sBrowser = xml.content(n2);
				else if ( xml_name == XML_LANGUAGEFILE )
					sLanguageFile = xml.content(n2);
				else if ( xml_name == XML_APP_FONT )
					sAppFont = xml.content(n2);
				else if ( xml_name == XML_APP_WIDTH )
					iAppWidth = xml.content(n2).asINT();
				else if ( xml_name == XML_APP_HEIGHT )
					iAppHeight = xml.content(n2).asINT();
				else if ( xml_name == XML_TV_WIDTH )
					iTransferViewWidth = xml.content(n2).asINT();
				else if ( xml_name == XML_TV_HEIGHT )
					iTransferViewHeight = xml.content(n2).asINT();
				else if ( xml_name == XML_TV_DOCKED )
					bTransferViewDocked = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_FILE_CONNECT )
					sSoundFileConnect = xml.content(n2);
				else if ( xml_name == XML_SOUND_FILE_DISCONNECT )
					sSoundFileDisconnect = xml.content(n2);
				else if ( xml_name == XML_SOUND_FILE_SEND )
					sSoundFileSend = xml.content(n2);
				else if ( xml_name == XML_SOUND_FILE_RECEIVE )
					sSoundFileReceive = xml.content(n2);
				else if ( xml_name == XML_SOUND_FILE_FIRSTRECEIVE )
					sSoundFileFirstReceive = xml.content(n2);
				else if ( xml_name == XML_SOUND_FILE_NICK_MENTIONED )
					sSoundFileNickMentioned = xml.content(n2);
				else if ( xml_name == XML_EXTERNAL_SOUND_PLAYER )
					bExternalSoundPlayer = xml.getBoolChild(n2);
				else if ( xml_name == XML_EXTERNAL_PLAYER )
					sExternalPlayer = xml.content(n2);
				else if ( xml_name == XML_SOUND_DISABLED )
					bSoundDisabled = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_DISABLED_AWAY )
					bSoundDisabledAway = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_CONNECT )
					bSoundEnabledConnect = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_DISCONNECT )
					bSoundEnabledDisconnect = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_SEND )
					bSoundEnabledSend = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_RECEIVE )
					bSoundEnabledReceive = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_FIRSTRECEIVE )
					bSoundEnabledFirstReceive = xml.getBoolChild(n2);
				else if ( xml_name == XML_SOUND_ENABLED_NICK_MENTIONED )
					bSoundEnabledNickMentioned = xml.getBoolChild(n2);
				else if ( xml_name == XML_TIMESTAMP_PRIVATECHAT )
					bTimeStampPrivateChat = xml.getBoolChild(n2);
				else if ( xml_name == XML_TIMESTAMP_HUBCHAT )
					bTimeStampHubChat = xml.getBoolChild(n2);
				else if ( xml_name == XML_SHOW_STATUS_MESSAGE )
					bShowStatusMessage = xml.getBoolChild(n2);
				else if ( xml_name == XML_SENDCHAT )
					sSendChat = xml.content(n2);
				else if ( xml_name == XML_SHOW_TRANSFER_WIN )
					bShowTransferWin = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_CHUNKPERCENT )
					bTVChunkPercent = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_FILEPERCENT )
					bTVFilePercent = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_CHUNKSIZE )
					bTVChunkSize = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_FILESIZE )
					bTVFileSize = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_DOWNLOADRATESINGLE )
					bTVDownloadRateSingle = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_ELAPSEDTIMESINGLE )
					bTVElapsedTimeSingle = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_DOWNLOADRATEMULTI )
					bTVDownloadRateMulti = xml.getBoolChild(n2);
				else if ( xml_name == XML_TV_ELAPSEDTIMEMULTI )
					bTVElapsedTimeMulti = xml.getBoolChild(n2);
				else if ( xml_name == XML_SEND_HIDE_PRIVATE_CHAT_TO_PUBLIC_CHAT )
					bSendHidePrivateChatToPublicChat = xml.getBoolChild(n2);
				else if ( xml_name == XML_CHAT_MESSAGE_MAX_LINES )
					iChatMessageMaxLines = xml.content(n2).asINT();
				else if ( xml_name == XML_FLOODCOUNT )
					iFloodCount = xml.content(n2).asINT();
				else if ( xml_name == XML_FLOODOPKICK )
					m_bFloodOpKick = xml.getBoolChild(n2);
				else if ( xml_name == XML_DEFAULTDOWNLOADMODE )
					iDefaultDownloadMode = xml.content(n2).asINT();
				else if ( xml_name == XML_QUERYONEXIT )
					bQueryOnExit = xml.getBoolChild(n2);
				else if ( xml_name == XML_ENABLETRAY )
					m_bEnableTray = xml.getBoolChild(n2);
				else if ( xml_name == XML_QUERYONFILEDELETE )
					bQueryOnFileDelete = xml.getBoolChild(n2);
				else if ( xml_name == XML_SHOWCHATINTAB )
					bShowChatInTab = xml.getBoolChild(n2);
				else if ( xml_name == XML_AUTO_AWAY_MODE )
					m_bAutoAwayMode = xml.getBoolChild(n2);
				else if ( xml_name == XML_AUTO_AWAY_TIME )
					m_nAutoAwayTime = xml.content(n2).asINT();
				else if ( xml_name == XML_CHAT_SHOW_JOINS_AND_PARTS )
					m_bChatShowJoinsAndParts = xml.getBoolChild(n2);
				else if ( xml_name == XML_CHAT_SHOW_JOINS_AND_PARTS_ONLY_FAV )
					m_bChatShowJoinsAndPartsOnlyFav = xml.getBoolChild(n2);
				else if ( xml_name == XML_CHAT_SUPPRESSED_NICKS )
					m_sSuppressedNicks = xml.content(n2).Data();
				else if ( xml_name == XML_DOUBLE_CLICK_ACTION )
					m_sDoubleClickAction = xml.content(n2).Data();
				else if ( xml_name == XML_DEFAULTFBREMOTEENCODING )
					m_sDefaultFBRemoteEncoding = xml.content(n2).Data();
				else if ( xml_name == XML_VALKNUT_DATA_PATH )
					m_sValknutDataPath = xml.content(n2).Data();
				else if ( xml_name == "MAP" )
				{
					StringMap * map = new StringMap();

					for(n3=n2->xmlChildrenNode;n3!=0;n3=n3->next)
					{
						xml_tmp = xml.name(n3);
						if ( xml_tmp == "KEY" )
							m_guiSettingMap[xml.content(n3).Data()] = map;
						else if ( xml_tmp == XML_ENTRY )
						{
							CString key="",name="";
							for(n4=n3->xmlChildrenNode;n4!=0;n4=n4->next)
							{
								xml_tmp = xml.name(n4);
								if ( xml_tmp == "KEY" )
									key = xml.content(n4);
								else if ( xml_tmp == "NAME" )
									name = xml.content(n4);
							}
							(*map)[key.Data()]=name.Data();
						}
					}
				}
				else if ( xml_name == XML_LCO_ENABLELOGGING )
					SetLogChatOption( elcoENABLELOGGING, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_APPENDDATE )
					SetLogChatOption( elcoAPPENDDATE, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_APPENDHUBNAME )
					SetLogChatOption( elcoAPPENDHUBNAME, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_APPENDHUBHOST )
					SetLogChatOption( elcoAPPENDHUBHOST, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_DISABLEPUBLICCHAT )
					SetLogChatOption( elcoDISABLEPUBLICCHAT, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_ENABLENICKNAMEFILTER )
					SetLogChatOption( elcoENABLENICKNAMEFILTER, xml.getBoolChild(n2) );
				else if ( xml_name == XML_LCO_NICKNAMEFILTER_ENABLELOGGING )
					SetLogChatOption( elcoNICKNAMEFILTER_ENABLELOGGING, xml.getBoolChild(n2) );
				else if ( xml_name == "NICKNAMEFILTER" )
				{
					if ( xml.content(n2) != "" )
						m_pLogChatNickNameFilter.Add( new CString(xml.content(n2)) );
				}
				else if ( xml_name == XML_CC_CHATTIMESTAMP )
					SetChatColor( eccCHATTIMESTAMP, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATLOCALNICK )
					SetChatColor( eccCHATLOCALNICK, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATLOCALTEXT )
					SetChatColor( eccCHATLOCALTEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATREMOTENICK )
					SetChatColor( eccCHATREMOTENICK, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATREMOTETEXT )
					SetChatColor( eccCHATREMOTETEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATSTATUSNICK )
					SetChatColor( eccCHATSTATUSNICK, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATSTATUSTEXT )
					SetChatColor( eccCHATSTATUSTEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATTIMESTAMP )
					SetChatColor( eccPUBLICCHATTIMESTAMP, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATLOCALNICK )
					SetChatColor( eccPUBLICCHATLOCALNICK, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATLOCALTEXT )
					SetChatColor( eccPUBLICCHATLOCALTEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATREMOTENICK )
					SetChatColor( eccPUBLICCHATREMOTENICK, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATREMOTETEXT )
					SetChatColor( eccPUBLICCHATREMOTETEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATSTATUSNICK )
					SetChatColor( eccPUBLICCHATSTATUSNICK, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATSTATUSTEXT )
					SetChatColor( eccPUBLICCHATSTATUSTEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICPRIVATECHATNICK )
					SetChatColor( eccPUBLICPRIVATECHATNICK, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICPRIVATECHATTEXT )
					SetChatColor( eccPUBLICPRIVATECHATTEXT, xml.content(n2) );
				else if ( xml_name == XML_CC_CHATSAY )
					SetChatColor( eccCHATSAY, xml.content(n2) );
				else if ( xml_name == XML_CC_PUBLICCHATMENICK )
					SetChatColor( eccPUBLICCHATMENICK, xml.content(n2) );
				else if ( xml_name == XML_CC_OPNICK )
					SetChatColor( eccOPNICK, xml.content(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_COMMENT )
					SetClientColumn( eclcCOMMENT, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_TAG )
					SetClientColumn( eclcTAG, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_SPEED )
					SetClientColumn( eclcSPEED, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_EMAIL )
					SetClientColumn( eclcEMAIL, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_SHARE )
					SetClientColumn( eclcSHARE, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_IP )
					SetClientColumn( eclcIP, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_LOCKPK )
					SetClientColumn( eclcLOCKPK, xml.getBoolChild(n2) );
				else if ( xml_name == XML_CLIENT_COLUMN_SUPPORTS )
					SetClientColumn( eclcSUPPORTS, xml.getBoolChild(n2) );
				else if ( xml_name == XML_USERMENUCOMMAND )
				{
					DC_UserMenuCommand * umc = new DC_UserMenuCommand();
					
					for( n3 = n2->xmlChildrenNode; n3 != 0; n3 = n3->next )
					{
						if ( xml.name(n3) == XML_USERMENUCOMMAND_NAME )
							umc->m_sName = xml.content(n3);
						else if ( xml.name(n3) == XML_USERMENUCOMMAND_ACT )
							umc->m_sCommand = xml.content(n3);
						else if ( xml.name(n3) == XML_USERMENUCOMMAND_CONTEXT )
							umc->m_nContext = xml.content(n3).asINT();
					}
					
					if ( umc->m_sName.IsEmpty() || umc->m_sCommand.IsEmpty() )
						delete umc;
					else
						m_lUserMenuCommands.Add( umc );
				}
				else if ( xml_name == XML_USERCHATCOMMAND )
				{
					DC_UserChatCommand * ucc = new DC_UserChatCommand();
					
					for ( n3 = n2->xmlChildrenNode; n3 != 0; n3 = n3->next )
					{
						if ( xml.name(n3) == XML_USERCHATCOMMAND_NAME )
							ucc->m_sName = xml.content(n3);
						else if ( xml.name(n3) == XML_USERCHATCOMMAND_ACT )
							ucc->m_sCommand = xml.content(n3);
					}
					
					if ( ucc->m_sName.IsEmpty() || ucc->m_sCommand.IsEmpty() )
						delete ucc;
					else
						m_lUserChatCommands.Add( ucc );
				}
				else if ( xml_name == XML_AUTORESPONSE_ENABLED )
					SetAutoResponderEnabled( xml.getBoolChild(n2) );
				else if ( xml_name == XML_AUTORESPONSE_ENABLED_PM )
					SetAutoResponderEnabledForPM( xml.getBoolChild(n2) );
				else if ( xml_name == XML_AUTORESPONSE )
				{
					DC_AutoResponseObject * aro = new DC_AutoResponseObject();
					
					for ( n3 = n2->xmlChildrenNode; n3 != 0; n3 = n3->next )
					{
						if ( xml.name(n3) == XML_AUTORESPONSE_TRIGGER )
							aro->m_sTrigger = xml.content(n3);
						else if ( xml.name(n3) == XML_AUTORESPONSE_RESPONSE )
							aro->m_sResponse = xml.content(n3);
						else if ( xml.name(n3) == XML_AUTORESPONSE_CASE_SENS )
							aro->m_bCaseSensitive = xml.getBoolChild(n3);
					}
					
					if ( aro->m_sTrigger.IsEmpty() || aro->m_sResponse.IsEmpty() )
					{
						delete aro;
					}
					else
					{
						m_lAutoResponses.Add( aro );
					}
				}
				else if ( xml_name == XML_AUTORESPONSE_DELAY )
					SetAutoResponseDelay( xml.content(n2).asLONG() );
				else if ( xml_name == XML_AUTORESPONSE_IGNORES )
					m_sAutoResponseIgnores = xml.content(n2);
				else if ( xml_name == XML_APP_ICON_THEME )
					m_sApplicationIconTheme = xml.content(n2).Data();
				else if ( xml_name == XML_EMOTICON_THEME )
					m_sEmoticonTheme = xml.content(n2).Data();
				else if ( xml_name == XML_USER_ICON_THEME )
					m_sUserListIconTheme = xml.content(n2).Data();
				else if ( xml_name == XML_FILELIST_NAMING_SCHEME )
					m_nFilelistNamingSchemeVersion = xml.content(n2).asINT();
				else if ( xml_name == XML_FOLDERS_RIGHT_PANE )
					SetFoldersInRightPane( xml.getBoolChild(n2) );
				else if ( xml_name == XML_SIZES_IN_LEFT_PANE )
					SetFolderSizesInLeftPane( xml.getBoolChild(n2) );
				else if ( xml_name == XML_FOLDERS_RIGHT_PANE_ON_TOP )
					SetFoldersInRightPaneOnTop( xml.getBoolChild(n2) );
			}
		}
	}
}

/** */
int DCConfig::Load()
{
	LoadHubProfile();
	LoadDCLib();
	return LoadDCGui();
}

/** */
int DCConfig::Save()
{
	SaveDCLib();
	return SaveDCGui();
}

/** */
int DCConfig::LoadDCGui()
{
	int err = 0;
	CString s;
	xmlNodePtr node;
	CXml xml;

	s = sConfigPath + DCGUI_CONFIG;

	if ( xml.ParseFile(s) == TRUE )
	{
		for(node=xml.doc()->children;node!=0;node=node->next)
		{
			if ( xml.name(node) == XML_DCGUI_CONFIG )
			{
				ParseDCGuiConfig(node->xmlChildrenNode);
			}
		}
	}
	else
	{
		err = -1;
	}

	// get usericons - cannot be done here since icons not loaded yet
	m_UserIcons = g_pIconLoader->GetPixmap(eiUSERICONS);

	InitMimeSourceFactory();

	// check datapath exists
	QDir dir( GetValknutDataPath() );
	if ( !dir.exists() )
	{
		printf("Data path specified does not exist, resetting.\n");
		SetValknutDataPath(VALKNUT_DATAPATH);
	}

	return err;
}

/** */
int DCConfig::SaveDCGui()
{
	int err=0;
	CString s;
	xmlDocPtr doc;
	xmlNodePtr node,node1,node2;
	CXml xml;

	doc = xmlNewDoc((const xmlChar*)"1.0");

	doc->children = xmlNewDocNode(doc,0,(const xmlChar*)XML_DCGUI_CONFIG,0);

	// gui
	node = xmlNewChild( doc->children, 0, (const xmlChar*)XML_GUI, 0 );

	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_OPENCLIENTWINDOWSMINIMIZED, bOpenClientWindowsMinimized );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_OPENPRIVATECHATWIN, bOpenPrivateChatWindow );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_EMOTICONS, bEnableEmoticons );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TABBAR, bTabBar );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TOOLBAR, bToolBar );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_STATUSBAR, bStatusBar );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_USERLISTRIGHTALIGNMENT, bUserListRightAlignment );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SHOWCHATSENDBUTTON, bShowChatSendButton );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SHOWCHATINTAB, bShowChatInTab );
	xmlNewChild( node, 0, (const xmlChar*)XML_CHATMAXPARAGRAPH, (const xmlChar*) CString().setNum(m_nChatMaxParagraph).Data() );

	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_USER_PHOTO, m_sUserPhotoFileName );

	switch(m_eUnit)
	{
		case euBYTE:
			s = XML_UNIT_BYTE;
			break;
		case euKBYTE:
			s = XML_UNIT_KBYTE;
			break;
		case euMBYTE:
			s = XML_UNIT_MBYTE;
			break;
		case euGBYTE:
			s = XML_UNIT_GBYTE;
			break;
		default:
			s = XML_UNIT_AUTO;
			break;
	}

	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_UNIT, s );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_THEME, sTheme );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_BACKGROUNDPIXMAP, sBackgroundPixmap );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_BROWSER, sBrowser );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SENDCHAT, sSendChat );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_LANGUAGEFILE, sLanguageFile );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_APP_FONT, sAppFont );
	xmlNewChild( node, 0, (const xmlChar*)XML_APP_WIDTH, (const xmlChar*) CString().setNum(iAppWidth).Data() );
	xmlNewChild( node, 0, (const xmlChar*)XML_APP_HEIGHT, (const xmlChar*) CString().setNum(iAppHeight).Data() );
	xmlNewChild( node, 0, (const xmlChar*)XML_TV_WIDTH, (const xmlChar*) CString().setNum(iTransferViewWidth).Data() );
	xmlNewChild( node, 0, (const xmlChar*)XML_TV_HEIGHT, (const xmlChar*) CString().setNum(iTransferViewHeight).Data() );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_DOCKED, bTransferViewDocked );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_ENABLETRAY, m_bEnableTray );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_QUERYONEXIT, bQueryOnExit );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_QUERYONFILEDELETE, bQueryOnFileDelete );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_FOLDERS_RIGHT_PANE, m_bFoldersInRightPane );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SIZES_IN_LEFT_PANE, m_bFolderSizesInLeftPane );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_FOLDERS_RIGHT_PANE_ON_TOP, m_bFoldersInRightPaneOnTop );

	// sound settings
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_CONNECT, sSoundFileConnect );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_DISCONNECT, sSoundFileDisconnect );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_SEND, sSoundFileSend );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_RECEIVE, sSoundFileReceive );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_FIRSTRECEIVE, sSoundFileFirstReceive );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_SOUND_FILE_NICK_MENTIONED, sSoundFileNickMentioned );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_EXTERNAL_PLAYER, sExternalPlayer );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_CONNECT, bSoundEnabledConnect );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_DISCONNECT, bSoundEnabledDisconnect );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_SEND, bSoundEnabledSend );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_RECEIVE, bSoundEnabledReceive );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_FIRSTRECEIVE, bSoundEnabledFirstReceive );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_ENABLED_NICK_MENTIONED, bSoundEnabledNickMentioned );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_EXTERNAL_SOUND_PLAYER, bExternalSoundPlayer );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_DISABLED, bSoundDisabled );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SOUND_DISABLED_AWAY, bSoundDisabledAway );

	// log settings
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TIMESTAMP_PRIVATECHAT, bTimeStampPrivateChat );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TIMESTAMP_HUBCHAT, bTimeStampHubChat );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SHOW_STATUS_MESSAGE, bShowStatusMessage );

	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_ENABLELOGGING, GetLogChatOption( elcoENABLELOGGING ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_APPENDDATE, GetLogChatOption( elcoAPPENDDATE ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_APPENDHUBNAME, GetLogChatOption( elcoAPPENDHUBNAME ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_APPENDHUBHOST, GetLogChatOption( elcoAPPENDHUBHOST ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_DISABLEPUBLICCHAT, GetLogChatOption( elcoDISABLEPUBLICCHAT ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_ENABLENICKNAMEFILTER, GetLogChatOption( elcoENABLENICKNAMEFILTER ) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_LCO_NICKNAMEFILTER_ENABLELOGGING, GetLogChatOption( elcoNICKNAMEFILTER_ENABLELOGGING ) );

	CString *ps = 0;

	while ( (ps=m_pLogChatNickNameFilter.Next(ps)) != 0 )
	{
		xmlNewChild( node, 0, (const xmlChar*)"NICKNAMEFILTER", (const xmlChar*) xml.ToUTF8(*ps).Data() );
	}

	// default filebrowser remote encoding
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_DEFAULTFBREMOTEENCODING, m_sDefaultFBRemoteEncoding.ascii() );
	
	// valknut data path
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_VALKNUT_DATA_PATH, m_sValknutDataPath.ascii() );

	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATTIMESTAMP, GetChatColor(eccCHATTIMESTAMP) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATLOCALNICK, GetChatColor(eccCHATLOCALNICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATLOCALTEXT, GetChatColor(eccCHATLOCALTEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATREMOTENICK, GetChatColor(eccCHATREMOTENICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATREMOTETEXT, GetChatColor(eccCHATREMOTETEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATSTATUSNICK, GetChatColor(eccCHATSTATUSNICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATSTATUSTEXT, GetChatColor(eccCHATSTATUSTEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATTIMESTAMP, GetChatColor(eccPUBLICCHATTIMESTAMP) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATLOCALNICK, GetChatColor(eccPUBLICCHATLOCALNICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATLOCALTEXT, GetChatColor(eccPUBLICCHATLOCALTEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATREMOTENICK, GetChatColor(eccPUBLICCHATREMOTENICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATREMOTETEXT, GetChatColor(eccPUBLICCHATREMOTETEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATSTATUSNICK, GetChatColor(eccPUBLICCHATSTATUSNICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATSTATUSTEXT, GetChatColor(eccPUBLICCHATSTATUSTEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICPRIVATECHATNICK, GetChatColor(eccPUBLICPRIVATECHATNICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICPRIVATECHATTEXT, GetChatColor(eccPUBLICPRIVATECHATTEXT) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_CHATSAY, GetChatColor(eccCHATSAY) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_PUBLICCHATMENICK, GetChatColor(eccPUBLICCHATMENICK) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CC_OPNICK, GetChatColor(eccOPNICK) );

	// transfer view settings
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_CHUNKPERCENT, bTVChunkPercent );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_FILEPERCENT, bTVFilePercent );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_CHUNKSIZE, bTVChunkSize );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_FILESIZE, bTVFileSize );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_DOWNLOADRATESINGLE, bTVDownloadRateSingle );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_ELAPSEDTIMESINGLE, bTVElapsedTimeSingle );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_DOWNLOADRATEMULTI, bTVDownloadRateMulti );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_TV_ELAPSEDTIMEMULTI, bTVElapsedTimeMulti );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SHOW_TRANSFER_WIN, bShowTransferWin );
	
	xmlNewChild( node, 0, (const xmlChar*)XML_FLOODCOUNT, (const xmlChar*) CString().setNum(iFloodCount).Data() );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_FLOODOPKICK, m_bFloodOpKick );

	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SEND_HIDE_PRIVATE_CHAT_TO_PUBLIC_CHAT, bSendHidePrivateChatToPublicChat );
	xmlNewChild( node, 0, (const xmlChar*)XML_CHAT_MESSAGE_MAX_LINES, (const xmlChar*) CString().setNum(iChatMessageMaxLines).Data() );
	xmlNewChild( node, 0, (const xmlChar*)XML_DEFAULTDOWNLOADMODE, (const xmlChar*) CString().setNum(iDefaultDownloadMode).Data() );

	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_AUTO_AWAY_MODE, m_bAutoAwayMode );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_AUTO_AWAY_TIME, CString().setNum(m_nAutoAwayTime) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CHAT_SHOW_JOINS_AND_PARTS, m_bChatShowJoinsAndParts );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CHAT_SHOW_JOINS_AND_PARTS_ONLY_FAV, m_bChatShowJoinsAndPartsOnlyFav );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CHAT_SUPPRESSED_NICKS, m_sSuppressedNicks.ascii() );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_DOUBLE_CLICK_ACTION, m_sDoubleClickAction.ascii() );

	// save client column settings
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_COMMENT, GetClientColumn(eclcCOMMENT) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_TAG, GetClientColumn(eclcTAG) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_EMAIL, GetClientColumn(eclcEMAIL) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_SPEED, GetClientColumn(eclcSPEED) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_SHARE, GetClientColumn(eclcSHARE) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_IP, GetClientColumn(eclcIP) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_LOCKPK, GetClientColumn(eclcLOCKPK) );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_CLIENT_COLUMN_SUPPORTS, GetClientColumn(eclcSUPPORTS) );
	
	// user menu commands
	DC_UserMenuCommand * umc = 0;
	while( (umc=m_lUserMenuCommands.Next(umc)) != 0 )
	{
		node1 = xmlNewChild( node, 0, (const xmlChar*)XML_USERMENUCOMMAND, 0);
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_USERMENUCOMMAND_NAME, umc->m_sName );
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_USERMENUCOMMAND_ACT, umc->m_sCommand );
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_USERMENUCOMMAND_CONTEXT, CString().setNum(umc->m_nContext) );
	}
	
	// user chat commands
	DC_UserChatCommand * ucc = 0;
	while ( (ucc=m_lUserChatCommands.Next(ucc)) != 0 )
	{
		node1 = xmlNewChild( node, 0, (const xmlChar*)XML_USERCHATCOMMAND, 0);
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_USERCHATCOMMAND_NAME, ucc->m_sName );
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_USERCHATCOMMAND_ACT, ucc->m_sCommand );
	}
	
	// icon themes
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_APP_ICON_THEME, GetApplicationIconTheme().ascii() );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_EMOTICON_THEME, GetEmoticonTheme().ascii() );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_USER_ICON_THEME, GetUserListIconTheme().ascii() );
	
	// filelist naming scheme version
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_FILELIST_NAMING_SCHEME, CString().setNum(GetFilelistNamingSchemeVersion()) );
	
	// auto responses
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_AUTORESPONSE_ENABLED, GetAutoResponderEnabled() );
	xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_AUTORESPONSE_ENABLED_PM, GetAutoResponderEnabledForPM() );
	DC_AutoResponseObject * aro = 0;
	while ( (aro=m_lAutoResponses.Next(aro)) != 0 )
	{
		node1 = xmlNewChild( node, 0, (const xmlChar*)XML_AUTORESPONSE, 0);
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_AUTORESPONSE_TRIGGER, aro->m_sTrigger );
		xml.xmlNewStringChild( node1, 0, (const xmlChar*)XML_AUTORESPONSE_RESPONSE, aro->m_sResponse );
		xml.xmlNewBoolChild( node1, 0, (const xmlChar*)XML_AUTORESPONSE_CASE_SENS, aro->m_bCaseSensitive );
	}
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_AUTORESPONSE_DELAY, CString().setNum(GetAutoResponseDelay()) );
	xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_AUTORESPONSE_IGNORES, GetAutoResponseIgnores() );
	
	// save map settings
	SettingMap::Iterator it;
	StringMap::Iterator it1;

	for(it=m_guiSettingMap.begin();it!=m_guiSettingMap.end();++it)
	{
		node1 = xmlNewChild( node, 0, (const xmlChar*)"MAP", 0 );
		xmlNewChild( node1, 0, (const xmlChar*)"KEY", (const xmlChar*) xml.ToUTF8(it.key().ascii()).Data() );
		for(it1=it.data()->begin();it1!=it.data()->end();++it1)
		{
			node2 = xmlNewChild( node1, 0, (const xmlChar*)XML_ENTRY, 0 );
			xmlNewChild( node2, 0, (const xmlChar*)"KEY", (const xmlChar*) xml.ToUTF8(it1.key().ascii()).Data() );
			xmlNewChild( node2, 0, (const xmlChar*)"NAME", (const xmlChar*) xml.ToUTF8(it1.data().ascii()).Data() );
		}
	}

	// save file
	s = sConfigPath + DCGUI_CONFIG;

	if ( SaveConfigXmlViaTemp(s,doc) == -1 )
	{
		err = -1;
	}

	xmlFreeDoc(doc);

	return err;
}

/** */
int DCConfig::LoadDCHubFilter( CStringList * list )
{
	CString s, xml_name;
	xmlNodePtr node,n1,n2;
	CXml xml;
	DC_HubFilterObject * HubFilterObject;

	s = sConfigPath + DCGUI_HUBFILTER;

	if ( xml.ParseFile(s) == TRUE )
	{
		for(node=xml.doc()->children;node!=0;node=node->next)
		{
			if ( xml.name(node) == XML_DCGUI_HUBFILTER )
			{
				for(n1=node->xmlChildrenNode;n1!=0;n1=n1->next)
				{
					if ( xml.name(n1) == XML_FILTER )
					{
						HubFilterObject = new DC_HubFilterObject();

						for(n2=n1->xmlChildrenNode;n2!=0;n2=n2->next)
						{
							xml_name = xml.name(n2);
							if ( xml_name == XML_FILTERNAME )
								HubFilterObject->m_sFilterName = xml.content(n2);
							else if ( xml_name == XML_CONTAINS )
								HubFilterObject->m_sContains = xml.content(n2);
							else if ( xml_name == XML_USER )
								HubFilterObject->m_nUser = xml.content(n2).asINT();
							else if ( xml_name == XML_NAME )
								HubFilterObject->m_bName = xml.getBoolChild(n2);
							else if ( xml_name == XML_SERVER )
								HubFilterObject->m_bServer = xml.getBoolChild(n2);
							else if ( xml_name == XML_DESCRIPTION )
								HubFilterObject->m_bDescription = xml.getBoolChild(n2);
						}

						if ( HubFilterObject->m_sFilterName != "" )
							list->Add( HubFilterObject->m_sFilterName, HubFilterObject );
						else
							delete HubFilterObject;
					}
				}
			}
		}
	}

	return 0;
}

/** */
int DCConfig::SaveDCHubFilter( CStringList * list )
{
	int err=0;
	CString s;
	xmlDocPtr doc;
	DC_HubFilterObject * HubFilterObject;
	xmlNodePtr node;
	CXml xml;

	doc = xmlNewDoc((const xmlChar*)"1.0");

	doc->children = xmlNewDocNode(doc,0,(const xmlChar*)XML_DCGUI_HUBFILTER,0);

	HubFilterObject = 0;

	while( list->Next((CObject *&)HubFilterObject) == 1 )
	{
		node = xmlNewChild( doc->children, 0, (const xmlChar*)XML_FILTER, 0 );

		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_FILTERNAME, HubFilterObject->m_sFilterName );
		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_CONTAINS, HubFilterObject->m_sContains );
		xmlNewChild( node, 0, (const xmlChar*)XML_USER, (const xmlChar*) CString().setNum(HubFilterObject->m_nUser).Data() );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_NAME, HubFilterObject->m_bName );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SERVER, HubFilterObject->m_bServer );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_DESCRIPTION, HubFilterObject->m_bDescription );
	}

	// save file
	s = sConfigPath + DCGUI_HUBFILTER;

	if ( SaveConfigXmlViaTemp(s,doc) == -1 )
	{
		err = -1;
	}

	xmlFreeDoc(doc);

	return err;
}

/** */
int DCConfig::LoadDCFriendList( CStringList * list )
{
	CString s, xml_name;
	xmlNodePtr node,n1,n2;
	CXml xml;
	DCFriendObject * FriendObject;

	s = sConfigPath + DCGUI_FRIENDLIST;

	if ( xml.ParseFile(s) == TRUE )
	{
		for(node=xml.doc()->children;node!=0;node=node->next)
		{
			if ( xml.name(node) == XML_DCGUI_FRIENDLIST )
			{
				for(n1=node->xmlChildrenNode;n1!=0;n1=n1->next)
				{
					if ( xml.name(n1) == XML_FRIEND )
					{
						FriendObject = new DCFriendObject();

						for(n2=n1->xmlChildrenNode;n2!=0;n2=n2->next)
						{
							xml_name = xml.name(n2);
							if ( xml_name == XML_NAME )
								FriendObject->m_sName = xml.content(n2);
							else if ( xml_name == XML_DESCRIPTION )
								FriendObject->m_sDescription = xml.content(n2);
							else if ( xml_name == XML_HUBNAME )
								FriendObject->m_sHubName = xml.content(n2);
							else if ( xml_name == XML_HUBHOST )
								FriendObject->m_sHubHost = xml.content(n2);
							else if ( xml_name == XML_IMAGE )
								FriendObject->m_sImageFileName = xml.content(n2);
							else if ( xml_name == XML_SEND_IMAGE )
								FriendObject->m_bSendImage = xml.getBoolChild(n2);
							else if ( xml_name == XML_AUTO_SEC )
								FriendObject->m_bAutoSec = xml.getBoolChild(n2);
							else if ( xml_name == XML_PERM_SLOT )
								FriendObject->m_bPermSlot = xml.getBoolChild(n2);
							else if ( xml_name == XML_IGNORE )
								FriendObject->m_bIgnore = xml.getBoolChild(n2);
						}

						if ( FriendObject->m_sName != "" )
							list->Add( FriendObject->m_sName, FriendObject );
						else
							delete FriendObject;
					}
				}
			}
		}
	}

	return 0;
}

/** */
int DCConfig::SaveDCFriendList( CStringList * list )
{
	int err=0;
	CString s;
	xmlDocPtr doc;
	DCFriendObject * FriendObject;
	xmlNodePtr node;
	CXml xml;

	doc = xmlNewDoc((const xmlChar*)"1.0");

	doc->children = xmlNewDocNode(doc,0,(const xmlChar*)XML_DCGUI_FRIENDLIST,0);

	FriendObject = 0;

	while( list->Next((CObject *&)FriendObject) == 1 )
	{
		node = xmlNewChild( doc->children, 0, (const xmlChar*)XML_FRIEND, 0 );

		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_NAME, FriendObject->m_sName );
		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_DESCRIPTION, FriendObject->m_sDescription );
		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_HUBNAME, FriendObject->m_sHubName );
		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_HUBHOST, FriendObject->m_sHubHost );
		xml.xmlNewStringChild( node, 0, (const xmlChar*)XML_IMAGE, FriendObject->m_sImageFileName );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_SEND_IMAGE, FriendObject->m_bSendImage );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_AUTO_SEC, FriendObject->m_bAutoSec );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_PERM_SLOT, FriendObject->m_bPermSlot );
		xml.xmlNewBoolChild( node, 0, (const xmlChar*)XML_IGNORE, FriendObject->m_bIgnore );
	}

	// save file
	s = sConfigPath + DCGUI_FRIENDLIST;

	if ( SaveConfigXmlViaTemp(s,doc) == -1 )
	{
		err = -1;
	}

	xmlFreeDoc(doc);

	return err;
}

/** */
QPixmap * DCConfig::GetUserIcon( bool op, eClientMode clientmode, eUserAwayMode awaymode, eUserSpeed speed, eUserClientVersion version )
{
	int x,y;

	y = 0;

	switch(speed)
	{
		case eusMODEM:
		case eus288KBPS:
		case eus336KBPS:
		case eus56KBPS:
		case eus0005:
		case eus001:
		case eus002:
		case eus005:
			x = 0;
			break;
		case eusISDN:
		case eus01:
			x = 16;
			break;
		case eusSATELLITE:
			x = 32;
			break;
		case eusCABLE:
		case eus02:
			x = 64;
			break;
		case eusDSL:
		case eus05:
		case eus1:
			x = 80;
			break;
		case eusLANT1:
		case eusLANT3:
		case eus2:
		case eus5:
		case eus10:
		case eus20:
		case eus50:
		case eus100:
			x = 96;
			break;
		default:
			x = 128;
			break;
	}

	if ( (x != -1) && (y != -1) )
	{
		if ( op )
		{
			y += 16*6;
		}

		if ( awaymode == euamAWAY )
		{
			y += 16;
		}

		if ( version == eucvDCGUI )
		{
			y += 16*4;
		}

		if ( clientmode == ecmPASSIVE )
		{
			y += 16*12;
		}
	}

	if ( (x == m_nUICX) &&
	     (y == m_nUICY) )
	{
		return &m_UserIconCache;
	}

	m_nUICX = x;
	m_nUICY = y;

	if ( (x == -1) && (y == -1) )
	{
		m_UserIconCache = g_pIconLoader->GetPixmap(eiGV);
	}
	else
	{
		m_UserIconCache = m_UserIcons.copy(x,y,16,16);
        }

	return &m_UserIconCache;
}

/** */
CString DCConfig::GetSoundFile( eUserSound usersound )
{
	CString s;

	switch (usersound)
	{
		case eusCONNECT:
			s = sSoundFileConnect;
			break;
		case eusDISCONNECT:
			s = sSoundFileDisconnect;
			break;
		case eusSEND:
			s = sSoundFileSend;
			break;
		case eusRECEIVE:
			s = sSoundFileReceive;
			break;
		case eusFIRSTRECEIVE:
			s = sSoundFileFirstReceive;
			break;
		case eusNICKMENTIONED:
			s = sSoundFileNickMentioned;
			break;
		default:
			s = "";
			break;
	}

	return s;
}

/** */
void DCConfig::SetSoundFile( eUserSound usersound, CString soundfile )
{
	switch (usersound)
	{
		case eusCONNECT:
			sSoundFileConnect = soundfile;
			break;
		case eusDISCONNECT:
			sSoundFileDisconnect = soundfile;
			break;
		case eusSEND:
			sSoundFileSend = soundfile;
			break;
		case eusRECEIVE:
			sSoundFileReceive = soundfile;
			break;
		case eusFIRSTRECEIVE:
			sSoundFileFirstReceive = soundfile;
			break;
		case eusNICKMENTIONED:
			sSoundFileNickMentioned = soundfile;
			break;
		default:
			break;
	}
}

/** */
bool DCConfig::GetSoundEnabled( eUserSound usersound )
{
	bool b;

	switch (usersound)
	{
		case eusCONNECT:
			b = bSoundEnabledConnect;
			break;
		case eusDISCONNECT:
			b = bSoundEnabledDisconnect;
			break;
		case eusSEND:
			b = bSoundEnabledSend;
			break;
		case eusRECEIVE:
			b = bSoundEnabledReceive;
			break;
		case eusFIRSTRECEIVE:
			b = bSoundEnabledFirstReceive;
			break;
		case eusNICKMENTIONED:
			b = bSoundEnabledNickMentioned;
			break;
		default:
			b = FALSE;
			break;
	}

	return b;
}

/** */
void DCConfig::SetSoundEnabled( eUserSound usersound, bool enabled )
{
	switch (usersound)
	{
		case eusCONNECT:
			bSoundEnabledConnect = enabled;
			break;
		case eusDISCONNECT:
			bSoundEnabledDisconnect = enabled;
			break;
		case eusSEND:
			bSoundEnabledSend = enabled;
			break;
		case eusRECEIVE:
			bSoundEnabledReceive = enabled;
			break;
		case eusFIRSTRECEIVE:
			bSoundEnabledFirstReceive = enabled;
			break;
		case eusNICKMENTIONED:
			bSoundEnabledNickMentioned = enabled;
			break;
		default:
			break;
	}
}

/** */
void DCConfig::PlaySound( eUserSound usersound )
{
	CString s = "";

	if ( bSoundDisabled == TRUE )
	{
		return;
	}

	if ( (GetAwayMode() == euamAWAY) && (bSoundDisabledAway == TRUE) )
	{
		return;
	}

	switch(usersound)
	{
		case eusCONNECT:
			if ( bSoundEnabledConnect )
				s = sSoundFileConnect;
			break;
		case eusDISCONNECT:
			if ( bSoundEnabledDisconnect )
				s = sSoundFileDisconnect;
			break;
		case eusSEND:
			if ( bSoundEnabledSend )
				s = sSoundFileSend;
			break;
		case eusRECEIVE:
			if ( bSoundEnabledReceive )
				s = sSoundFileReceive;
			break;
		case eusFIRSTRECEIVE:
			if ( bSoundEnabledFirstReceive )
				s = sSoundFileFirstReceive;
			break;
		case eusNICKMENTIONED:
			if ( bSoundEnabledNickMentioned )
				s = sSoundFileNickMentioned;
			break;
		default:
			break;
	}

	PlaySound(s);
}

/** */
void DCConfig::PlaySound( CString file )
{
	if ( file == "" )
	{
		return;
	}

	if ( bExternalSoundPlayer == FALSE )
	{
		QSound::play(file.Data());
	}
	else
	{
		if ( pProcess->isRunning() == TRUE )
		{
			pProcess->kill();
		}

		pProcess->clearArguments();

		pProcess->addArgument(sExternalPlayer.Data());
		pProcess->addArgument(file.Data());

		if ( !pProcess->start() )
		{
			printf("error start play process\n");
		}
	}
}

/** */
void DCConfig::SetTimeStamp( eTimeStamp timestamp, bool enabled )
{
	switch(timestamp)
	{
		case etsPRIVATECHAT:
			bTimeStampPrivateChat = enabled;
			break;
		case etsHUBCHAT:
			bTimeStampHubChat = enabled;
			break;
		default:
			break;
	}
}

/** */
bool DCConfig::GetTimeStamp( eTimeStamp timestamp )
{
	bool res;

	switch(timestamp)
	{
		case etsPRIVATECHAT :
			res = bTimeStampPrivateChat;
			break;
		case etsHUBCHAT:
			res = bTimeStampHubChat;
			break;
		default:
			res = FALSE;
			break;
	}

	return res;
}

/** */
bool DCConfig::GetTransferViewOptions( eTransferViewOptions e ) const
{
	switch(e)
	{
		case etvoCHUNKPERCENT:
			return bTVChunkPercent;
			break;
		case etvoFILEPERCENT:
			return bTVFilePercent;
			break;		
		case etvoCHUNKSIZE:
			return bTVChunkSize;
			break;		
		case etvoFILESIZE:
			return bTVFileSize;
			break;		
		case etvoDOWNLOADRATESINGLE:
			return bTVDownloadRateSingle;
			break;		
		case etvoELAPSEDTIMESINGLE:
			return bTVElapsedTimeSingle;
			break;		
		case etvoDOWNLOADRATEMULTI:
			return bTVDownloadRateMulti;
			break;		
		case etvoELAPSEDTIMEMULTI:
			return bTVElapsedTimeMulti;
			break;		
		default:
			return FALSE;
			break;
	}
}

/** */
void DCConfig::SetTransferViewOptions( eTransferViewOptions e, bool b )
{
  	switch(e)
	{
		case etvoCHUNKPERCENT:
			bTVChunkPercent = b;
			break;
		case etvoFILEPERCENT:
			bTVFilePercent = b;
			break;		
		case etvoCHUNKSIZE:
			bTVChunkSize = b;
			break;		
		case etvoFILESIZE:
			bTVFileSize = b;
			break;		
		case etvoDOWNLOADRATESINGLE:
			bTVDownloadRateSingle = b;
			break;		
		case etvoELAPSEDTIMESINGLE:
			bTVElapsedTimeSingle = b;
			break;		
		case etvoDOWNLOADRATEMULTI:
			bTVDownloadRateMulti = b;
			break;		
		case etvoELAPSEDTIMEMULTI:
			bTVElapsedTimeMulti = b;
			break;		
		default:
			break;
	}
}

/** */
bool DCConfig::InitMimeSourceFactory()
{
	DC_EmoticonObject * EmoticonObject;
	CString s,imagename;
	xmlNodePtr node,n1,n2;
	CXml xml;
	int id;
	bool res = FALSE;

	if ( m_pMimeSourceFactory )
	{
		QMimeSourceFactory::removeFactory(m_pMimeSourceFactory);
		delete m_pMimeSourceFactory;
		m_pMimeSourceFactory = 0;
	}

	m_EmoticonImage.reset();

	if ( m_EmoticonSettingList )
	{
		delete m_EmoticonSettingList;
	}

	m_EmoticonSettingList = new CList<DC_EmoticonObject>();

	// load emoticons
	
	// first we check if a local icon present
	s = GetConfigPath()+DIRSEPARATOR;
	
	if ( xml.ParseFile(s+"emoticons.xml") == FALSE )
	{
		// get global icons
		s = (GetValknutDataPath()+DIRSEPARATOR+"icons"+DIRSEPARATOR+"emot"+DIRSEPARATOR+GetEmoticonTheme()+DIRSEPARATOR).ascii();

		if ( xml.ParseFile(s+"emoticons.xml") == FALSE )
		{
			return res;
		}
	}

	id = 0;

	// parse the list
	for(node=xml.doc()->children;node!=0;node=node->next)
	{
		if ( xml.name(node) == "emoticons" )
		{
			for(n1=node->xmlChildrenNode;n1!=0;n1=n1->next)
			{
				if ( xml.name(n1) == "emoticon" )
				{
					EmoticonObject = new DC_EmoticonObject();

					EmoticonObject->m_Text = xml.prop(n1,"text").Data();

					for(n2=n1->xmlChildrenNode;n2!=0;n2=n2->next)
					{
						if ( xml.name(n2) == "source" )
						{
							EmoticonObject->left   = xml.prop(n2,"left").asINT();
							EmoticonObject->top    = xml.prop(n2,"top").asINT();
							EmoticonObject->right  = xml.prop(n2,"right").asINT();
							EmoticonObject->bottom = xml.prop(n2,"bottom").asINT();

							imagename = xml.prop(n2,"name") + ".xpm";
						}
					}

					if ( EmoticonObject->m_Text != "" )
					{
							EmoticonObject->m_nID = id;
							id++;
							m_EmoticonSettingList->Add(EmoticonObject);

//							printf("%s\n",EmoticonObject->m_Text.Data());
					}
				}
			}
		}
	}
	
	if ( m_EmoticonImage.load((s+imagename).Data()) == TRUE )
	{
		res = TRUE;
	}
	else
	{
		if ( m_EmoticonSettingList )
		{
			delete m_EmoticonSettingList;
			m_EmoticonSettingList = 0;
		}
	}

	if ( m_EmoticonSettingList )
	{
		if ( m_EmoticonSettingList->Count() > 0 )
		{
			m_pMimeSourceFactory = new QMimeSourceFactory();

			EmoticonObject = 0;

			while( (EmoticonObject=m_EmoticonSettingList->Next(EmoticonObject)) != 0 )
			{
				m_pMimeSourceFactory->setImage( ("emoticon" + CString().setNum(EmoticonObject->m_nID)).Data(), 
					m_EmoticonImage.copy(EmoticonObject->left,EmoticonObject->top,EmoticonObject->right-EmoticonObject->left,EmoticonObject->bottom-EmoticonObject->top) );
			}

			QMimeSourceFactory::addFactory(m_pMimeSourceFactory);

			res = TRUE;
		}
	}

	return res;
}

/** */
CList<DC_EmoticonObject> * DCConfig::EmoticonList()
{
	return m_EmoticonSettingList;
}

/** */
QImage & DCConfig::GetEmoticonImage()
{
	return m_EmoticonImage;
}

/** */
bool DCConfig::GetMap( CString name, StringMap *& map )
{
	bool res = TRUE;

	if ( m_guiSettingMap.find(name.Data()) == m_guiSettingMap.end() )
	{
		m_guiSettingMap[name.Data()] = new StringMap();
		res = FALSE;
	}

	map = m_guiSettingMap[name.Data()];

	return res;
}

/** */
CString DCConfig::GetChatColor( eChatColor type ) const
{
	switch (type)
	{
		case eccCHATTIMESTAMP:
			return m_sChatColor_1;
		case eccCHATLOCALNICK:
			return m_sChatColor_2;
		case eccCHATLOCALTEXT:
			return m_sChatColor_3;
		case eccCHATREMOTENICK:
			return m_sChatColor_4;
		case eccCHATREMOTETEXT:
			return m_sChatColor_5;
		case eccCHATSTATUSNICK:
			return m_sChatColor_6;
		case eccCHATSTATUSTEXT:
			return m_sChatColor_7;
		case eccPUBLICCHATTIMESTAMP:
			return m_sChatColor_8;
		case eccPUBLICCHATLOCALNICK:
			return m_sChatColor_9;
		case eccPUBLICCHATLOCALTEXT:
			return m_sChatColor_10;
		case eccPUBLICCHATREMOTENICK:
			return m_sChatColor_11;
		case eccPUBLICCHATREMOTETEXT:
			return m_sChatColor_12;
		case eccPUBLICCHATSTATUSNICK:
			return m_sChatColor_13;
		case eccPUBLICCHATSTATUSTEXT:
			return m_sChatColor_14;
		case eccPUBLICPRIVATECHATNICK:
			return m_sChatColor_15;
		case eccPUBLICPRIVATECHATTEXT:
			return m_sChatColor_16;
		case eccCHATSAY:
			return m_sChatColor_17;
		case eccPUBLICCHATMENICK:
			return m_sChatColor_18;
		case eccOPNICK:
			return m_sChatColor_19;
		default:
			break;
	}

	return "";
}

/** */
void DCConfig::SetChatColor( eChatColor type, CString s )
{
	switch (type)
	{
		case eccCHATTIMESTAMP:
			m_sChatColor_1 = s;
			break;
		case eccCHATLOCALNICK:
			m_sChatColor_2 = s;
			break;
		case eccCHATLOCALTEXT:
			m_sChatColor_3 = s;
			break;
		case eccCHATREMOTENICK:
			m_sChatColor_4 = s;
			break;
		case eccCHATREMOTETEXT:
			m_sChatColor_5 = s;
			break;
		case eccCHATSTATUSNICK:
			m_sChatColor_6 = s;
			break;
		case eccCHATSTATUSTEXT:
			m_sChatColor_7 = s;
			break;
		case eccPUBLICCHATTIMESTAMP:
			m_sChatColor_8 = s;
			break;
		case eccPUBLICCHATLOCALNICK:
			m_sChatColor_9 = s;
			break;
		case eccPUBLICCHATLOCALTEXT:
			m_sChatColor_10 = s;
			break;
		case eccPUBLICCHATREMOTENICK:
			m_sChatColor_11 = s;
			break;
		case eccPUBLICCHATREMOTETEXT:
			m_sChatColor_12 = s;
			break;
		case eccPUBLICCHATSTATUSNICK:
			m_sChatColor_13 = s;
			break;
		case eccPUBLICCHATSTATUSTEXT:
			m_sChatColor_14 = s;
			break;
		case eccPUBLICPRIVATECHATNICK:
			m_sChatColor_15 = s;
			break;
		case eccPUBLICPRIVATECHATTEXT:
			m_sChatColor_16 = s;
			break;
		case eccCHATSAY:
			m_sChatColor_17 = s;
			break;
		case eccPUBLICCHATMENICK:
			m_sChatColor_18 = s;
			break;
		case eccOPNICK:
			m_sChatColor_19 = s;
			break;
		default:
			break;
	}
}

/** */
void DCConfig::SetLogChatOption( eLogChatOptions elco, bool enabled )
{
	switch(elco)
	{
		case elcoENABLELOGGING:
			m_bLogChatOption_1 = enabled;
			break;
		case elcoAPPENDDATE:
			m_bLogChatOption_2 = enabled;
			break;
		case elcoAPPENDHUBNAME:
			m_bLogChatOption_3 = enabled;
			break;
		case elcoDISABLEPUBLICCHAT:
			m_bLogChatOption_4 = enabled;
			break;
		case elcoENABLENICKNAMEFILTER:
			m_bLogChatOption_5 = enabled;
			break;
		case elcoNICKNAMEFILTER_ENABLELOGGING:
			m_bLogChatOption_6 = enabled;
			break;
		case elcoAPPENDHUBHOST:
			m_bLogChatOption_7 = enabled;
			break;
		default:
			break;
	}
}

/** */
bool DCConfig::GetLogChatOption( eLogChatOptions elco )
{
	switch(elco)
	{
		case elcoENABLELOGGING:
			return m_bLogChatOption_1;
			break;
		case elcoAPPENDDATE:
			return m_bLogChatOption_2;
			break;
		case elcoAPPENDHUBNAME:
			return m_bLogChatOption_3;
			break;
		case elcoDISABLEPUBLICCHAT:
			return m_bLogChatOption_4;
			break;
		case elcoENABLENICKNAMEFILTER:
			return m_bLogChatOption_5;
			break;
		case elcoNICKNAMEFILTER_ENABLELOGGING:
			return m_bLogChatOption_6;
			break;
		case elcoAPPENDHUBHOST:
			return m_bLogChatOption_7;
			break;
		default:
			break;
	}

	return FALSE;
}

/** */
void DCConfig::SetLogChatNickNameFilter( CList<CString> * list )
{
	CString * ps = 0;

	if ( !list )
	{
		return;
	}

	m_pLogChatNickNameFilter.Clear();

	while( (ps = list->Next(ps)) != 0 )
	{
		m_pLogChatNickNameFilter.Add( new CString(*ps) );
	}
}

/** */
void DCConfig::GetLogChatNickNameFilter( CList<CString> * list )
{
	CString * ps = 0;

	if ( !list )
	{
		return;
	}

	list->Clear();

	while( (ps = m_pLogChatNickNameFilter.Next(ps)) != 0 )
	{
		list->Add( new CString(*ps) );
	}
}

/** */
bool DCConfig::CheckLogChatNickNameFilter( CString nick )
{
	CString * ps = 0;

	if ( GetLogChatOption(elcoENABLENICKNAMEFILTER) == FALSE )
	{
		return TRUE;
	}

	while( (ps = m_pLogChatNickNameFilter.Next(ps)) != 0 )
	{
		if ( *ps == nick )
		{
			if ( GetLogChatOption(elcoNICKNAMEFILTER_ENABLELOGGING) )
			{
				return TRUE;
			}
			else
			{
				return FALSE;
			}
		}
	
	}

	// nick not found
	if ( !GetLogChatOption(elcoNICKNAMEFILTER_ENABLELOGGING) )
		return TRUE;

	return FALSE;
}

/** */
bool DCConfig::GetClientColumn( eClientColumn e )
{
	switch(e)
	{
		case eclcCOMMENT:
			return m_bClientColumnComment;
			break;
		case eclcTAG:
			return m_bClientColumnTag;
			break;
		case eclcEMAIL:
			return m_bClientColumnEMail;
			break;
		case eclcSPEED:
			return m_bClientColumnSpeed;
			break;
		case eclcSHARE:
			return m_bClientColumnShare;
			break;
		case eclcIP:
			return m_bClientColumnIP;
			break;
		case eclcLOCKPK:
			return m_bClientColumnLOCKPK;
			break;
		case eclcSUPPORTS:
			return m_bClientColumnSUPPORTS;
			break;
		default:
			break;
	}

	return FALSE;
}

/** */
void DCConfig::SetClientColumn( eClientColumn e, bool b )
{
	switch(e)
	{
		case eclcCOMMENT:
			m_bClientColumnComment = b;
			break;
		case eclcTAG:
			m_bClientColumnTag = b;
			break;
		case eclcEMAIL:
			m_bClientColumnEMail = b;
			break;
		case eclcSPEED:
			m_bClientColumnSpeed = b;
			break;
		case eclcSHARE:
			m_bClientColumnShare = b;
			break;
		case eclcIP:
			m_bClientColumnIP = b;
			break;
		case eclcLOCKPK:
			m_bClientColumnLOCKPK = b;
			break;
		case eclcSUPPORTS:
			m_bClientColumnSUPPORTS = b;
			break;
		default:
			break;
	}
}

/** */
int DCConfig::GetClientColumnWidth( eClientColumn e )
{
	switch(e)
	{
		case eclcNICK:
			return iClientColumnNick;
			break;
		case eclcCOMMENT:
			return iClientColumnComment;
			break;
		case eclcTAG:
			return iClientColumnTag;
			break;
		case eclcEMAIL:
			return iClientColumnEMail;
			break;
		case eclcSPEED:
			return iClientColumnSpeed;
			break;
		case eclcSHARE:
			return iClientColumnShare;
			break;
		case eclcIP:
			return iClientColumnIP;
			break;
		case eclcLOCKPK:
			return iClientColumnLOCKPK;
			break;
		case eclcSUPPORTS:
			return iClientColumnSUPPORTS;
			break;
		default:
			break;
	}

	return 0;
}

/** */
void DCConfig::SetClientColumnWidth( eClientColumn e, int i )
{
	switch(e)
	{
		case eclcNICK:
			iClientColumnNick = i;
			break;
		case eclcCOMMENT:
			iClientColumnComment = i;
			break;
		case eclcTAG:
			iClientColumnTag = i;
			break;
		case eclcEMAIL:
			iClientColumnEMail = i;
			break;
		case eclcSPEED:
			iClientColumnSpeed = i;
			break;
		case eclcSHARE:
			iClientColumnShare = i;
			break;
		case eclcIP:
			iClientColumnIP = i;
			break;
		case eclcLOCKPK:
			iClientColumnLOCKPK = i;
			break;
		case eclcSUPPORTS:
			iClientColumnSUPPORTS = i;
			break;
		default:
			break;
	}
}

/** */
void DCConfig::SetUserMenuCommands( CList<DC_UserMenuCommand> * list )
{
	DC_UserMenuCommand * umc = 0, *umc1;
	
	if (!list)
	{
		return;
	}
	
	m_lUserMenuCommands.Clear();
	
	while( (umc=list->Next(umc)) != 0)
	{
		umc1 = new DC_UserMenuCommand();
		umc1->m_sName    = umc->m_sName;
		umc1->m_sCommand = umc->m_sCommand;
		umc1->m_nContext = umc->m_nContext;
		m_lUserMenuCommands.Add( umc1 );
	}
	
	return;
}

/** */
long DCConfig::GetUserMenuCommands( CList<DC_UserMenuCommand> * list)
{
	DC_UserMenuCommand * umc = 0, *umc1;
	
	if (!list)
	{
		return 0;
	}
	
	list->Clear();
	
	while( (umc=m_lUserMenuCommands.Next(umc)) != 0 )
	{
		umc1 = new DC_UserMenuCommand();
		umc1->m_sName    = umc->m_sName;
		umc1->m_sCommand = umc->m_sCommand;
		umc1->m_nContext = umc->m_nContext;
		
		list->Add( umc1 );
	}
	
	return list->Count();
}

/** */
void DCConfig::SetUserChatCommands( CList<DC_UserChatCommand> * list )
{
	DC_UserChatCommand * ucc = 0, *ucc1;
	
	if (!list)
	{
		return;
	}
	
	m_lUserChatCommands.Clear();
	
	while( (ucc=list->Next(ucc)) != 0 )
	{
		ucc1 = new DC_UserChatCommand();
		ucc1->m_sName    = ucc->m_sName;
		ucc1->m_sCommand = ucc->m_sCommand;
		m_lUserChatCommands.Add( ucc1 );
		
	}
	
	return;
}

/** */
long DCConfig::GetUserChatCommands( CList<DC_UserChatCommand> * list )
{
	DC_UserChatCommand * ucc = 0, *ucc1;
	
	if (!list)
	{
		return 0;
	}
	
	list->Clear();
	
	while( (ucc=m_lUserChatCommands.Next(ucc)) != 0 )
	{
		ucc1 = new DC_UserChatCommand();
		ucc1->m_sName    = ucc->m_sName;
		ucc1->m_sCommand = ucc->m_sCommand;
		
		list->Add( ucc1 );
	}
	
	return list->Count();
}

/** */
void DCConfig::SetAutoResponses( CList<DC_AutoResponseObject> * list )
{
	DC_AutoResponseObject * aro = 0, * aro1 = 0;
	
	if (!list)
	{
		return;
	}
	
	m_lAutoResponses.Clear();
	
	while( (aro=list->Next(aro)) != 0 )
	{
		aro1 = new DC_AutoResponseObject();
		aro1->m_sTrigger       = aro->m_sTrigger;
		aro1->m_bCaseSensitive = aro->m_bCaseSensitive;
		aro1->m_sResponse      = aro->m_sResponse;
		
		m_lAutoResponses.Add( aro1 );
	}
	
	return;
}

/** */
long DCConfig::GetAutoResponses( CList<DC_AutoResponseObject> * list )
{
	DC_AutoResponseObject * aro = 0, * aro1 = 0;
	
	if (!list)
	{
		return 0;
	}
	
	list->Clear();
	
	while( (aro=m_lAutoResponses.Next(aro)) != 0)
	{
		aro1 = new DC_AutoResponseObject();
		aro1->m_sTrigger       = aro->m_sTrigger;
		aro1->m_bCaseSensitive = aro->m_bCaseSensitive;
		aro1->m_sResponse      = aro->m_sResponse;
		
		list->Add( aro1 );
	}
	
	return list->Count();
}

void DCConfig::RenameStoredFilelists()
{
	QDir dir;
	QStringList listing;
	
	printf("Renaming stored filelists ...\n");
	
	dir.setPath( g_pConfig->GetFileListPath().Data() );
	
	listing = dir.entryList();
	
	for (QStringList::Iterator it = listing.begin(); it != listing.end(); ++it)
	{
		QString filename = *it;
		
		if ( (filename == ".") || (filename == "..") )
		{
			// skip
		}
		else
		{
			QFile file;
			file.setName( g_pConfig->GetFileListPath().Data() + filename );
			if (file.open( IO_ReadOnly ))
			{
				QString line, nick, hubhost;
				file.readLine( line, (Q_ULONG) 2048 );
				
				if (line == "---HEADER START---\n")
				{
					while (line != "---HEADER END---\n")
					{
						file.readLine( line, (Q_ULONG) 2048 );
						
						if (line.left(5) == "NICK=")
						{
							nick = line.mid(5);
							nick = nick.replace("\n", "");
						}
						else if (line.left(8) == "HUBHOST=")
						{
							hubhost = line.mid(8);
							hubhost = hubhost.replace("\n", "");
						}
					}
				}
				else
				{
					printf("%s is not a valknut filelist\n", filename.ascii());
					file.close();
					continue;
				}
				
				file.close();
				
				QString newname = nick + "-" + hubhost + ".filelist";
				newname = newname.replace('/', "_");
				newname = newname.replace('\\', "_");
				newname = newname.replace(':', "_");
				
				printf("Renaming %s to %s ...", filename.ascii(), newname.ascii());
				if (dir.rename(filename, newname) == TRUE)
				{
					printf(" OK\n");
				}
				else
				{
					printf(" renaming failed!\n");
				}
			}
			else
			{
				printf("Couldn't open %s!\n", filename.ascii());
			}
		}
	}
	
	// finished, set variable so renaming will not be done again
	this->SetFilelistNamingSchemeVersion(2);
}
