// GTextUtils.h
//
// Common text/string-related utilities, including
// text-format data importing facilities and types.
// NOTE CHANGE IN-PROGRESS: Many text-related methods
// currently in GUtils.h will be moved here in the near
// future.

#ifndef _GTEXTUTILS_H_
#define _GTEXTUTILS_H_

#include "GTypes.h"  // for cppsstream

#ifndef USE_WIDE_CHARS
	typedef  int gint;
#else
	typedef  wint_t gint;
#endif

class GTextUtils  
{
public:
	static void						OSInitResourceStrings(void);
	static bool						ReadStringsFromFile(cppstring sPath);
	static void						FreeResourceStrings(void);
	
	static int						GetStringIndexByKey(const char * sKey);
	static cppstring				GetStringByKey(const char * sKey);
	static std::string				GetNarrowStringByKey(const char * sKey);
	static bool						OSGetOSStringByKey(const char * sKey, OSStringPtr pOSString);
	
	static cppstring				GetStringByIndex(int nIndex);
	static std::string				GetNarrowStringByIndex(int nIndex);
	static bool						OSGetOSStringByIndex(int nIndex, OSStringPtr pOSString);

	static StringVector				GetRangeOfStrings(int nStartIndex, int nEndIndex);

	static bool						OSTextDataToClipboard(const cppstring & sText, bool bClearClipboard=true);
	static bool						OSIsTextClipDataAvailable(long * pOutLength = NULL);
	static bool						OSGetTextClipData(cppstring * pOutString);
//	static GDeviceRect				GetBestRectForText(cppstring sText, const GDeviceRect &maxRect, int kFontHeight, int nMinWidth = 450);
	
	static bool						OSPrintPlainText(const cppstring & sText, bool bShowJobDialog=false);

	static cppstring				RealToCPPString(real rNum, int nPrecision = 3, EFloatStyle eFloatStyle = kFloatStyle_default);
	static cppstring				RealToCPPString(real rNum, int nPrecision, bool bPrecisionDecimal);
	static cppstring				RealToDisplayCPPString(real rNum, int nDigits);
	static cppstring				RealToCPPStringRoundedToSigDigits(real rNum, int nSigDigits);

	static cppstring				LongToCPPString(long nNum);
	static std::string				LongToString(long nNum);

	static real						CPPStringToReal(const cppstring &sNumber);
	static real						StringToReal(const narrowstring &sNumber);
	static long						CPPStringToLong(const cppstring &sInteger);
	static long						StringToLong(const narrowstring &sInteger);

	static bool						IsStringRealNumber(cppstring sNumber, real *pfValue = NULL); // RETURN true if number is a real
	static bool						IsStringLong(const cppstring & sNumber, long *pnValue = NULL); // RETURN true if number is a long
	static bool						IsNarrowStringLong(const narrowstring & sNumber, long *pnValue = NULL); // RETURN true if number is a long
	static cppstring				StringReplace(cppstring sBase, const cppstring &sSearchFor, const cppstring &sReplaceWith); 
	static std::string				AsciiStringReplace(std::string sBase, const std::string &sSearchFor, const std::string &sReplaceWith); 

	static bool						StringIsAllDigits(const cppstring & sNumber);
	static cppstring				ExtractBaseName(const cppstring & sFullName, int * p_nOutNumberSuffix);
									// For a name like "Run 3", ExtractBaseName will return "Run' and p_nOutNumberSuffix will be set to "3"
	static real						GetVersionFromBaseName(cppstring sFilename, cppstring sBaseName);
	
	static cppstring				MatchSubString(const cppstring & sFullName, const cppstring & sMatchName, const cppstring & sSubName);
	
	static cppstring				ParenthesizeString(const cppstring &sInString);
	static narrowstring				ParenthesizeNarrowString(const narrowstring &sInString);

	static cppstring				FilterOutChars(const cppstring &sInString, const cppstring &sFilterChars);
	static cppstring				ConvertToUppercase(const cppstring &sInString);
	static bool						StringsEqualIgnoringCase(const cppstring &s1, const cppstring &s2);
	
	static EImportTextFormat		ParseImportFormat(std::ifstream * pInStream);
	static int						GetWordsPerLine(std::stringstream * pInStream);
	static cppstring				StripPathAndExtension(const cppstring &sFileAndPath);
	static cppstring				StripPath(const cppstring &sFileAndPath);
	static cppstring				GetExtension(const cppstring &sFileName);
	static cppstring				GetPath(const cppstring &sFileName);
	static cppstring				OSGetPathSeparator(void);
	static bool						InvalidDataWorldName(const cppstring &sName);
	// standard c string library functions with wide versions
	static gchar *					Gstrcpy(gchar *strDestination,const gchar * strSource );
	static gchar *					Gstrncpy(gchar *strDestination,const gchar * strSource, size_t nCount);
	static int						Gstrcmp(const gchar *str1,const gchar *str2);
	static int						Gstrncmp(const gchar *str1,const gchar *str2, size_t nCount);
	static long						Gstrtol(const gchar *nptr, gchar **endptr, int base);
	static double					Gstrtod(const gchar *nptr, gchar **endptr);
	static size_t					Gstrlen(const gchar * str );
	static int						Gisspace(const gint c);
	static int						Gisalpha (const gint c);
	static int						Gisprint(const gint c);
	static gint						GEOF();
	static	bool					IsEOF(int i);

	static cppstring				ConvertNarrowStringToWide(const std::string  sNarrow);
	static std::string				ConvertWideStringToNarrow(const cppstring  sWide);

	static unsigned short			GetValueFromCharacterEscape(cppstring sCharEscape);
									// sCharEscape should be a standard XML/HTML escape sequence in one of two formats:
									//  &#N;  or  &#xN;
									// In the first case, nnn is a base-10 integer; in the second case, a hexadecimal integer.
									// The method simply converts the value to an integer correctly according to base (presence of the "x"
									// indicated hexadecimal).
	
	static cppstring				EncodeCharacterEscape(unsigned short nUTF8Char);
									
	static cppstring				OSGetNativeCharCodeForUTF8(unsigned short nUTF8Char);
									// Typically a Windows-charset or MacRoman character equivalent to a UTF-8 char code.
									// NOTE that if controls & text displays have UTF-8 support this OS method should
									// not do anything, assuming we're also using wide strings.
									
	static unsigned short			OSGetUTF8CharCodeForNative(unsigned short nNativeChar);								
									// REVISIT - the methods below use a narrow decimal-string-escape method of character conversion
									// which should be abandoned in favor of the methods above
									
	static cppstring				ConvertToOSSpecialChars(cppstring s); // go through s and convert "&SpecialCharxx" to the xx'th special OS character
	static cppstring				ConvertFromOSSpecialChars(cppstring s); // go through s and convert any OS special chars to "&SpecialCharxx"
	static StringVector	*			GetOSSpecialChars(void);   // list of all possible web entities (#&###;) to map from incoming text
	static StringVector	*			GetOSSpecialCharCodes(void);  // list of Local char map chars/strings to map web entities TO

	static StringVector *			GetOSOutgoingSpecialChars(void); // list of chars to map to web entities for outgoing text
	static StringVector *			GetOSOutgoingSpecialCharCodes(void); // list of web entities to map chars to

	static const cppstring			kSpecialCharFlag;

	static cppstring				OSConvertReturnLineFeed(cppstring sText);	// do OS-Specific new line conversion
	static bool						OSGetLine(cppsstream * pInStream, cppstring * pOutString);
	static int						OSGetTextLength(cppstring sText);
	static short					AdjustTextSizeByAppPref(short nOrigSize, bool bApplyNewSize=true, void * pOSData=NULL);
									// Routine to nudge text sizes up if user preferences
									// so dictate.  The return value is the new font pt. size.
									// If bApplyNewSize is true (default) this routine actually 
									// applies the larger text size for immediate drawing; pOSData 
									// can be used as needed for draw-releated data (e.g. a draw context).
									
	static short					OSApplyTextSize(short nNewSize, void * pOSData=NULL);
									// Apply new text size for text drawing.  pOSData can be
									// used for a draw context etc.


	static narrowstring				RemoveSameRoot(AsciiStringVector *pvStrings); // if all strings have the same root (i.e. text before the last '\') then remove it (and return it)

	static EFloatStyle				GetFloatStyle(bool bPrecisionDecimal); // return a float style based on bPrecisionDecimal

	static cppstring				TranslatePathToFile(cppstring sPath); // Convert all separator characters to the proper OS
	static cppstring				TranslatePathFromFile(cppstring sPath); // Convert all separator characters from the proper OS

	static int						kSmallestFontSize;	// used in font size controls
	static int						kLargestFontSize;

private:
	static StringVector				kvSpecialChar;	
	static StringVector				kvSpecialCharCode;	

	
	static StringVector				kvOutgoingSpecialChar;	
	static StringVector				kvOutgoingSpecialCharCode;	

	static std::map<narrowstring, int>	m_mStringIndices;
	static std::vector<cppstring>	m_vStringData;
};

#define GSTD_STRING(x) GTextUtils::GetStringByKey(#x)
#define GSTD_INDEX(x) GTextUtils::GetStringIndexByKey(#x)
#define GSTD_INDEXSTRING(x) GTextUtils::GetStringByIndex(x)
#define GSTD_OSSTRING(x, p) GTextUtils::OSGetOSStringByKey(#x, p)
#define GSTD_NARROWSTRING(x) GTextUtils::GetNarrowStringByKey(#x)

#endif // _GTEXTUTILS_H_
