///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains all string-related code.
 *	\file		IceString.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICESTRING_H__
#define __ICESTRING_H__

	#define STRING_STATS

	#define ASCII_TAB		0x09
	#define ASCII_SPACE		0x20

	class ICECORE_API String
	{
		public:
		// Constructors/Destructor
		/*explicit*/				String();
		/*explicit*/				String(const char* string);
		/*explicit*/				String(const String& str);
									~String();

						bool		Set(const char* string);					// Assign a string
						bool		Set(const String& string);					// Assign a string
		__forceinline	char*		Get()								const	{ return mText;							}
		__forceinline	char*		GetBuffer()							const	{ return mText;							}

						void		Reset();

						udword		Length()							const;		// Get the string's length
		__forceinline	udword		GetLength()							const	{ return Length();						}

						udword		Compare(const String& str2)			const;	// Compare the String with another one
						udword		Compare(const char* str2)			const;	// Compare the String with another one
						udword		FuzzyCompare(const String& str2)	const;	// Fuzzy comparisons between strings

						String&		ToUpper();									// Transform into uppercase
						String&		ToLower();									// Transform into lowercase
		// Eval
						bool		IsDecimal(sdword* value=null)		const;
						bool		IsFloat(float* value=null)			const;
						bool		IsFile()							const;
						bool		IsBool()							const;
						sdword		ToDecimal()							const;
						float		ToFloat()							const;

						udword		Replace(char oldchar, char newchar);		// Replace all 'oldchar' characters with 'newchar' ones
		// Parameters
						bool		GetParameter(String& param, char*& curpar)	const;	// Parameters parsing
						udword		NbParams()	const;

						String&		SetAt(ubyte cara, udword pos);
						ubyte		GetAt(udword pos);

		// String extraction methods
						String		Mid(udword first, udword count = -1);
						String		Left(udword count);
						String		Right(udword count);

		// Searching methods (to search a specific character or a sub-String)
						sdword		Find(ubyte character, udword from = 0, sdword to = -1);
						sdword		Find(const String& stringtofind, udword from = 0, sdword to = -1);
						sdword		ReverseFind(ubyte character);

		// Numerical operand extraction methods
						bool		Extract(float& f, udword from);
						bool		Extract(udword& i, udword from);
						bool		Extract(sdword& i, udword from);

		// Plain-text methods (where starts the next line? where is the end of the current line? etc...)
						sdword		NextLine(sdword from);
						sdword		GetEndOfLine(sdword from);

		__forceinline	bool		IsValid()							const	{ return mText!=0;		}
		__forceinline	bool		IsEmpty()							const	{ return Length()==0;	}
		// Cast operators
		//! Cast operator for const char* = String
		__forceinline	operator const char*()							const	{ return (const char*)(mText);								}
		//! Cast operator for char* = String
		__forceinline	operator char*()								const	{ return (char*)(mText);									}
		//! Cast operator for float = String
		__forceinline	operator float()								const	{ float tmp = MAX_FLOAT; IsFloat(&tmp);	return tmp;			}
		//! Cast operator for sdword = String
		__forceinline	operator sdword()								const	{ sdword tmp = INVALID_NUMBER; IsDecimal(&tmp); return tmp;	}

		// Access operators
						const char	operator[](udword i)				const	{ return mText ? mText[i] : 0;								}

		// Assignment operators
		//! Operator for String = const char*
		__forceinline	String&		operator=(const char* string)				{ Set(string);				return *this; }
		//! Operator for String = char*
		__forceinline	String&		operator=(char* string)						{ Set((const char*)string);	return *this; }
		//! Operator for String = String
		__forceinline	String&		operator=(const String& string)				{ Set(string);				return *this; }

		//! Concatenation operator for String += String
						String&		operator+=(const String& string);
		// Stats
#ifdef STRING_STATS
		__forceinline	udword		GetNbStrings()						const	{ return mNbStrings;	}
		__forceinline	udword		GetTotalBytes()						const	{ return mUsedRam;		}
		private:

		static			udword		mNbStrings;		//!< Number of strings around
		static			udword		mUsedRam;		//!< Amount of bytes used by strings in the system
#endif
						char*		mText;			//!< The character string held in the class
	};

	ICECORE_API	inline bool operator==(const String& s1, const char* s2)	{ return s1.Compare(s2) == 0; }	//!< Operator for String == char*
	ICECORE_API	inline bool operator!=(const String& s1, const char* s2)	{ return s1.Compare(s2) != 0; }	//!< Operator for String != char*

	ICECORE_API	inline bool operator==(const String& s1, const String& s2)	{ return s1.Compare(s2) == 0; }	//!< Operator for String == String
	ICECORE_API	inline bool operator!=(const String& s1, const String& s2)	{ return s1.Compare(s2) != 0; }	//!< Operator for String != String
	ICECORE_API	inline bool operator< (const String& s1, const String& s2)	{ return s1.Compare(s2) <  0; }	//!< Operator for String < String
	ICECORE_API	inline bool operator> (const String& s1, const String& s2)	{ return s1.Compare(s2) >  0; }	//!< Operator for String > String
	ICECORE_API	inline bool operator<=(const String& s1, const String& s2)	{ return s1.Compare(s2) <= 0; }	//!< Operator for String <= String
	ICECORE_API	inline bool operator>=(const String& s1, const String& s2)	{ return s1.Compare(s2) >= 0; }	//!< Operator for String >= String

#endif // __ICESTRING_H__



#ifdef TOFIX

class	FROOTS_API		String
{
	//String "arithmetic" operators
					String					operator+(String& str);
					String					operator+(char* car);
					String					operator+(char car);
					String&					operator+=(String& str);
					String&					operator+=(char* str);
					String&					operator+=(char car);
					String&					operator=(String& str);
					String&					operator=(char* str);

	//String boolean operators
					bool					operator==(String& str);
					bool					operator==(char* str);
					bool					operator!=(String& str);
					bool					operator!=(char* str);

	protected:
					udword					SetLength(udword count, bool KeepOldContent = true);	//This method is protected because it transforms the String object in a temporary "non-valid" String!

					ubyte*					mCharBuf;									//The actual buffer of character the String represents
					sdword					mLength;									//Cache of the String's length
};

#endif