#ifndef _KVI_TQSTRING_H_
#define _KVI_TQSTRING_H_

//=============================================================================
//
//   File : kvi_qstring.h
//   Creation date : Mon Aug 04 2003 13:36:33 CEST by Szymon Stefanek
//
//   This file is part of the KVirc irc client distribution
//   Copyright (C) 2003-2006 Szymon Stefanek (pragma at kvirc dot net)
//
//   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 opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================

//=============================================================================
//
// Helper functions for the TQString class
//
//=============================================================================

#include "kvi_settings.h"
#include "kvi_inttypes.h"
#include "kvi_stdarg.h"
#include "kvi_qcstring.h"

#include <tqstring.h>
#include <tqregexp.h>

///
/// \namespace KviTQString
///
/// \brief A namespace for TQString helper functions
///
/// This namespace contains several helper functions
/// that are used when dealing with TQString.
///
namespace KviTQString
{
	extern KVILIB_API TQString makeSizeReadable(size_t size);
	extern KVILIB_API bool equalCS(const TQString &sz1,const TQString &sz2);
	extern KVILIB_API bool equalCI(const TQString &sz1,const TQString &sz2);
	extern KVILIB_API bool equalCS(const TQString &sz1,const char * sz2);
	extern KVILIB_API bool equalCI(const TQString &sz1,const char * sz2);
	// sz2 is assumed to be null terminated here!
	extern KVILIB_API bool equalCI(const TQString &sz1,const TQChar * sz2);
	inline bool equalCS(const char * sz1,const TQString &sz2)
		{ return equalCS(sz2,sz1); };
	inline bool equalCI(const char * sz1,const TQString &sz2)
		{ return equalCI(sz2,sz1); };
	// sz1 is assumed to be null terminated here!
	inline bool equalCI(const TQChar * sz1,const TQString &sz2)
		{ return equalCI(sz2,sz1); };

	extern KVILIB_API bool equalCSN(const TQString &sz1,const TQString &sz2,unsigned int len);
	extern KVILIB_API bool equalCIN(const TQString &sz1,const TQString &sz2,unsigned int len);
	extern KVILIB_API bool equalCSN(const TQString &sz1,const char * sz2,unsigned int len);
	extern KVILIB_API bool equalCIN(const TQString &sz1,const char * sz2,unsigned int len);
	// sz2 is assumed to be null terminated here!
	extern KVILIB_API bool equalCIN(const TQString &sz1,const TQChar * sz2,unsigned int len);
	inline bool equalCSN(const char * sz1,const TQString &sz2,unsigned int len)
		{ return equalCSN(sz2,sz1,len); };
	inline bool equalCIN(const char * sz1,const TQString &sz2,unsigned int len)
		{ return equalCIN(sz2,sz1,len); };
	// sz1 is assumed to be null terminated here!
	inline bool equalCIN(const TQChar * sz1,const TQString &sz2,unsigned int len)
		{ return equalCIN(sz2,sz1,len); };

	//note that greater here means that come AFTER in the alphabetic order
	// return < 0 ---> str1 < str2
	// return = 0 ---> str1 = str2
	// return > 0 ---> str1 > str2
	extern KVILIB_API int cmpCI(const TQString &sz1,const TQString &sz2);
	extern KVILIB_API int cmpCIN(const TQString &sz1,const TQString &sz2,unsigned int len);
	extern KVILIB_API int cmpCS(const TQString &sz1,const TQString &sz2);

	extern KVILIB_API void detach(TQString &sz);

	// this makes the TQString sz appear as a null terminated array
	// it MAY RETURN 0 when the TQString is null!
	extern KVILIB_API const TQChar * nullTerminatedArray(const TQString &sz);

	inline bool lastCharIs(TQString &szString,const TQChar &c)
					{ return szString.endsWith(c); };

	extern KVILIB_API void ensureLastCharIs(TQString &szString,const TQChar &c);

	// wild expression matching
	extern KVILIB_API bool matchWildExpressionsCI(const TQString &szM1,const TQString &szM2);
	// wild or regexp matching
	extern KVILIB_API bool matchStringCI(const TQString &szExp,const TQString &szStr,bool bIsRegExp = false,bool bExact = false);
	extern KVILIB_API bool matchStringCS(const TQString &szExp,const TQString &szStr,bool bIsRegExp = false,bool bExact = false);

	extern KVILIB_API void vsprintf(TQString &s,const TQString &szFmt,kvi_va_list list);
	extern KVILIB_API TQString & sprintf(TQString &s,const TQString &szFmt,...);
	extern KVILIB_API void stripRightWhiteSpace(TQString &s);
	extern KVILIB_API void stripLeft(TQString &s,const TQChar &c);
	extern KVILIB_API void stripRight(TQString &s,const TQChar &c);
	extern KVILIB_API void appendFormatted(TQString &s,const TQString &szFmt,...);
	extern KVILIB_API void appendNumber(TQString &s,double dReal);
	extern KVILIB_API void appendNumber(TQString &s,kvi_i64_t iInteger);
	extern KVILIB_API void appendNumber(TQString &s,int iInteger);
	extern KVILIB_API void appendNumber(TQString &s,unsigned int uInteger);
	extern KVILIB_API void appendNumber(TQString &s,kvi_u64_t uInteger);
	
	extern KVILIB_API void cutFromFirst(TQString &s,const TQChar &c,bool bIncluded = true);
	extern KVILIB_API void cutFromLast(TQString &s,const TQChar &c,bool bIncluded = true);
	extern KVILIB_API void cutToFirst(TQString &s,const TQChar &c,bool bIncluded = true,bool bClearIfNotFound = false);
	extern KVILIB_API void cutToLast(TQString &s,const TQChar &c,bool bIncluded = true,bool bClearIfNotFound = false);
	extern KVILIB_API void cutFromFirst(TQString &s,const TQString &c,bool bIncluded = true);
	extern KVILIB_API void cutFromLast(TQString &s,const TQString &c,bool bIncluded = true);
	extern KVILIB_API void cutToFirst(TQString &s,const TQString &c,bool bIncluded = true,bool bClearIfNotFound = false);
	extern KVILIB_API void cutToLast(TQString &s,const TQString &c,bool bIncluded = true,bool bClearIfNotFound = false);
	
	extern KVILIB_API TQString upperISO88591(const TQString &szSrc);
	extern KVILIB_API TQString lowerISO88591(const TQString &szSrc);
	extern KVILIB_API TQString getToken(TQString &szString,const TQChar &sep);
	
	extern KVILIB_API void transliterate(TQString &s,const TQString &szToFind,const TQString &szReplacement);

	extern KVILIB_API void bufferToHex(TQString &szRetBuffer,const unsigned char * buffer,unsigned int len);

	// a global empty string (note that this is ALSO NULL under TQt 3.x)
	extern KVILIB_API const TQString empty;

	///
	/// A portability wrapper which with TQt3 and TQt4.
	/// Returns a lowcase version of the parameter string.
	///
	inline TQString toLower(const TQString &s)
	{
#ifdef COMPILE_USE_QT4
		return s.toLower();
#else
		return s.lower();
#endif
	}
	
	inline int find(const TQString &s,TQChar c,int index = 0,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.indexOf(c,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.find(c,index,cs);
#endif
	}

	inline int find(const TQString &s,char c,int index = 0,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.indexOf(c,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.find(c,index,cs);
#endif
	}

	inline int find(const TQString &s,const TQString & str,int index = 0,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.indexOf(str,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.find(str,index,cs);
#endif
	}

	inline int find(const TQString &s,const TQRegExp & rx,int index = 0)
	{
#ifdef COMPILE_USE_QT4
		return s.indexOf(rx,index);
#else
		return s.find(rx,index);
#endif
	}

	inline int find(const TQString &s,const char * str,int index = 0)
	{
#ifdef COMPILE_USE_QT4
		return s.indexOf(TQString(str),index);
#else
		return s.find(str,index);
#endif
	}

	inline int findRev(const TQString &s,TQChar c,int index = -1,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.lastIndexOf(c,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.findRev(c,index,cs);
#endif
	}

	inline int findRev(const TQString &s,char c,int index = -1,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.lastIndexOf(c,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.findRev(c,index,cs);
#endif
	}

	inline int findRev(const TQString &s,const TQString & str,int index = -1,bool cs = true)
	{
#ifdef COMPILE_USE_QT4
		return s.lastIndexOf(str,index,cs ? TQt::CaseSensitive : TQt::CaseInsensitive);
#else
		return s.findRev(str,index,cs);
#endif
	}

	inline int findRev(const TQString &s,const TQRegExp & rx,int index = -1)
	{
#ifdef COMPILE_USE_QT4
		return s.lastIndexOf(rx,index);
#else
		return s.findRev(rx,index);
#endif
	}

	inline int findRev(const TQString &s,const char * str,int index = -1)
	{
#ifdef COMPILE_USE_QT4
		return s.lastIndexOf(TQString(str),index);
#else
		return s.findRev(str,index);
#endif
	}

	inline TQString trimmed(const TQString &s)
	{
#ifdef COMPILE_USE_QT4
		return s.trimmed();
#else
		return s.stripWhiteSpace();
#endif
	}

	// WARNING: DO NOT USE CONSTRUCTS LIKE char * c = KviTQString::toUtf8(something).data();
	//          They are dangerous since with many compilers the returned string gets destroyed
	//          at the end of the instruction and the c pointer gets thus invalidated.
	//          Use
	//           KviTQCString tmp = KviTQString::toUtf8(something);
	//           char * c = tmp.data(); 
	//          instead.
	//          Yes, I know that it sucks, but it's the only way to
	//          transit to qt 4.x more or less cleanly...
	inline KviTQCString toUtf8(const TQString &s)
	{
#ifdef COMPILE_USE_QT4
		return s.toUtf8();
#else
		return s.utf8();
#endif
	}

	inline KviTQCString toLocal8Bit(const TQString &s)
	{
		return s.local8Bit();
	}
	
	inline kvi_i64_t toI64(TQString &szNumber,bool * bOk)
	{
#if SIZEOF_LONG_INT == 8
		return szNumber.toLong(bOk);
#else
		return szNumber.toLongLong(bOk);
#endif
	}
	
	inline kvi_u64_t toU64(TQString &szNumber,bool * bOk)
	{
#if SIZEOF_LONG_INT == 8
		return szNumber.toULong(bOk);
#else
		return szNumber.toULongLong(bOk);
#endif
	}
};

// QT4SUX: Because TQString() is gone. TQString() is SLOWER than TQString() since it invokes a constructor and destructor.

#endif //!_KVI_TQSTRING_H_