#ifndef _xbSTRING_
#define _xbSTRING_
/*<<<***************************************************************************
The MIT License (MIT)

Copyright(C) 2013 - 2015 Marc Mirti Mancinelli, Christophe Lardau and Philippe Pamart (xdcube.org)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
#Title: xbString
#Project: xdcBase
////////////////////////////////////////////////////////////////////////////////
#Author: Marc MIRTI MANCINELLI
#History:
<15/09/2013: creation.
12/02/2014: this notice inserted.
***************************************************************************>>>*/

#ifndef _xbENGINE_
#	include "xbEngine.h"
#endif

enum xbStringNumFmt
{
	xbStringNum_binary = 2,
	xbStringNum_base10 = 10,
	xbStringNum_hexa = 16
};

enum xbStringNumPrec
{
	xbStringNumPrec_full = -1,
	xbStringNumPrec_0 = 0,
	xbStringNumPrec_1 = 1,
	xbStringNumPrec_2 = 2,
	xbStringNumPrec_3 = 3,
	xbStringNumPrec_4 = 4,
	xbStringNumPrec_5 = 5
};

class xbBSTR;

#define xbSTRING_DEFW
#include "xbString.h.inl"
#undef xbSTRING_DEFW

#define xbSTRING_DEFA
#include "xbString.h.inl"
#undef xbSTRING_DEFA

#ifndef _xbSTRING_INTERNAL
#	ifdef _xbSTRING_UNICODE
#		define xbFormat		xbFormatW
#		define xbFormatV	xbFormatVW
#		define xbSortStringNC	xbSortStringNCW
#		define xbFindStringNC	xbFindStringNCW
#		define xbSortString		xbSortStringW
#		define xbFindString		xbFindStringW
#	else
#		define xbFormat		xbFormatA
#		define xbFormatV	xbFormatVA
#		define xbSortStringNC xbSortStringNCA
#		define xbFindStringNC	xbFindStringNCA
#		define xbSortString		xbSortStringA
#		define xbFindString		xbFindStringA
#	endif
#endif

void xbEXPORT xbRelOutput(const xbString &s,bool tofile = true);

xbEXPORT void xbCPconvert(ulong cpSrc,const xbStringA &src,ulong cpDst,xbStringA *pDst); //implemented in xbODregistry.cpp
xbEXPORT void xbCPconvert(ulong cpSrc,LPCSTR src,int lgsrc,ulong cpDst,xbStringA *pDst);
xbEXPORT void xbCPconvert(LPCWSTR src,int lgsrc,ulong cpDst,xbStringA *pDst);
class xbBSTR;
xbEXPORT void xbCPconvert(ulong cpSrc,const xbStringA &src,xbBSTR *pDst);
xbEXPORT void xbCPconvert(ulong cpSrc,LPCSTR src,int lgsrc,xbBSTR *pDst);
xbEXPORT void xbCPconvert(ulong cpSrc,const xbStringA &src,xbStringW *pDst);
xbEXPORT void xbCPconvert(ulong cpSrc,LPCSTR src,int lgsrc,xbStringW *pDst);

xbEXPORT bool xbCPconvertEx(LPCWSTR src,int lgsrc,ulong cpDst,xbStringA *pDst,bool bForce,xbOpMode opm,LPCSTR lpDefaultChar = NULL);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,const xbStringA &src,xbBSTR *pDst,bool bForce,xbOpMode opm);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,LPCSTR src,int lgsrc,xbBSTR *pDst,bool bForce,xbOpMode opm);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,const xbStringA &src,xbStringW *pDst,bool bForce,xbOpMode opm);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,LPCSTR src,int lgsrc,xbStringW *pDst,bool bForce,xbOpMode opm);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,const xbStringA &src,ulong cpDst,xbStringA *pDst,bool bForce,xbOpMode opm,LPCSTR lpDefaultChar = NULL);
xbEXPORT bool xbCPconvertEx(ulong cpSrc,LPCSTR src,int lgsrc,ulong cpDst,xbStringA *pDst,bool bForce,xbOpMode opm,LPCSTR lpDefaultChar = NULL);

enum xbCPtransformMode
{
xbCPtransform_byteRev = LCMAP_BYTEREV, // Windows NT/2000/XP: Use byte reversal. For example, if you pass in 0x3450 0x4822 the result is 0x5034 0x2248.  
xbCPtransform_fullWidth = LCMAP_FULLWIDTH, // Uses wide characters (where applicable). 
xbCPtransform_halfWidth = LCMAP_HALFWIDTH, // Uses narrow characters (where applicable). 
xbCPtransform_hiragana = LCMAP_HIRAGANA, // Hiragana. 
xbCPtransform_katakana = LCMAP_KATAKANA, // Katakana. 
xbCPtransform_linguisticCasing = LCMAP_LINGUISTIC_CASING, // Uses linguistic rules for casing, rather than file system rules (the default). Valid with LCMAP_LOWERCASE or LCMAP_UPPERCASE only. 
xbCPtransform_lower = LCMAP_LOWERCASE, // Uses lowercase. 
xbCPtransform_simplifiedChinese = LCMAP_SIMPLIFIED_CHINESE, // Windows NT 4.0 and later: Maps traditional Chinese characters to simplified Chinese characters. 
xbCPtransform_sortKey = LCMAP_SORTKEY, // Produces a normalized wide charactersort key. For more information, see lpDestStr and Remarks. 
xbCPtransform_traditionalChinese = LCMAP_TRADITIONAL_CHINESE, //Windows NT 4.0 and later: Maps simplified Chinese characters to traditional Chinese characters. 
xbCPtransform_upper = LCMAP_UPPERCASE, // Uses uppercase. 

xbCPtransform_unaccent = NORM_IGNORENONSPACE,

//The following flags are used only with the LCMAP_SORTKEY flag. Flag Meaning 
xbCPtransform_ignoreCase = NORM_IGNORECASE, // Ignores case.  
xbCPtransform_ignoreKanatype = NORM_IGNOREKANATYPE, // Does not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal. 
xbCPtransform_ignoreNonSpace = NORM_IGNORENONSPACE, // Ignores nonspacing. This flag also removes Japanese accent characters. 
xbCPtransform_ignoreSymbols = NORM_IGNORESYMBOLS, // Ignores symbols.  
xbCPtransform_ignoreWidth = NORM_IGNOREWIDTH, // Does not differentiate between a single-byte character and the same character as a double-byte character. 
xbCPtransform_stringSort = SORT_STRINGSORT, // Treats punctuation the same as symbols. 

/*
If the LCMAP_SORTKEY flag is not specified, the LCMapString function performs string mapping. In this case the following restrictions apply: 

LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive. 
LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive. 
LCMAP_HALFWIDTH and LCMAP_FULLWIDTH are mutually exclusive. 
LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive. 
LCMAP_LOWERCASE and LCMAP_UPPERCASE are not valid in combination with any of these flags: LCMAP_HIRAGANA, LCMAP_KATAKANA, LCMAP_HALFWIDTH, LCMAP_FULLWIDTH. 
When the LCMAP_SORTKEY flag is specified, the LCMapString function generates a sort key. In this case the following restriction applies: 

LCMAP_SORTKEY is mutually exclusive with all other LCMAP_* flags, with the sole exception of LCMAP_BYTEREV. 
*/
};
xbEXPORT bool xbCPtransform(LCID lcid,LPCWSTR src,int lgsrc,xbCPtransformMode mask,xbBSTR *pDst,xbOpMode opm =xbOp_Required);
xbEXPORT bool xbCPtransform(LCID lcid,LPCWSTR src,int lgsrc,xbCPtransformMode mask,xbStringW *pDst,xbOpMode opm =xbOp_Required);
xbEXPORT bool xbCPtransform(LCID lcid,LPCSTR src,int lgsrc,xbCPtransformMode mask,xbStringA *pDst,xbOpMode opm =xbOp_Required);

/*
#ifdef _xbSTRING_UNICODE
xbStringW  xbEXPORT operator+(const xbStringA &str1, const xbStringW &str2);
xbStringW  xbEXPORT operator+(const xbStringW &str1, const xbStringA &str2);
#else
xbStringA  xbEXPORT operator+(const xbStringA &str1, const xbStringW &str2);
xbStringA  xbEXPORT operator+(const xbStringW &str1, const xbStringA &str2);
#endif
*/
xbEXPORT xbString xbStrFromHR(xbHR hr);

enum xbTokenError
{
	xbTokenError_End = -1,
	xbTokenError_StringNotTerminated = -2,
	xbTokenError_BlockNotTerminated = -3
};
#endif
