#ifndef __STRING_H__
#define __STRING_H__

#include "Common.h"
#include "Signal.h"

namespace AScript {

//-----------------------------------------------------------------------------
// String operations
//-----------------------------------------------------------------------------
int GetEscaped(int ch);
const TCHAR *FindString(const TCHAR *str, const TCHAR *sub, bool ignoreCaseFlag);

String EscapeString(const TCHAR *str);
String Capitalize(const TCHAR *str);
String Lower(const TCHAR *str);
String Upper(const TCHAR *str);
String Strip(const TCHAR *str, const SymbolSet &attrs);
String Left(const TCHAR *str, size_t len);
String Right(const TCHAR *str, size_t len);
String Middle(const TCHAR *str, int start, int len);
String Join(const ValueList &valList, const TCHAR *str);
String Replace(const TCHAR *str, const TCHAR *sub, const TCHAR *replace,
									int nMaxReplace, const SymbolSet &attrs);
void SplitPathList(Environment &env, const TCHAR *str, ValueList &valList);
Value FindString(Environment &env, Signal sig,
		const TCHAR *str, const TCHAR *sub, int start, const SymbolSet &attrs);

inline bool IsSJISFirst(int ch) {
	return 0x81 <= ch && ch <= 0x9f || 0xe0 <= ch && ch <= 0xef;
}

inline bool IsSJISSecond(int ch) {
	return 0x40 <= ch && ch <= 0x7e || 0x80 <= ch && ch <= 0xfc;
}

inline bool IsDigit(int ch) {
	return _T('0') <= ch && ch <= _T('9');
}

inline bool IsHexDigit(int ch) {
	return
		_T('0') <= ch && ch <= _T('9') ||
		_T('A') <= ch && ch <= _T('F') ||
		_T('a') <= ch && ch <= _T('f');
}

inline int ConvHexDigit(int ch) {
	return
		(_T('0') <= ch && ch <= _T('9'))? ch - _T('0') :
		(_T('A') <= ch && ch <= _T('F'))? ch - _T('A') + 10 :
		(_T('a') <= ch && ch <= _T('f'))? ch - _T('a') + 10 : 0;
}

inline bool IsOctDigit(int ch) {
	return _T('0') <= ch && ch <= _T('7');
}

inline int ConvOctDigit(int ch) {
	return (_T('0') <= ch && ch <= _T('7'))? ch - _T('0') : 0;
}

inline bool IsWhite(int ch) {
	return ch == _T(' ') || ch == _T('\t');
}

inline bool IsSpace(int ch) {
	return ch == _T(' ') || ch == _T('\t') || ch == _T('\r') || ch == _T('\n');
}

inline bool IsSymbolFirstChar(int ch) {
	return
		(_T('a') <= ch && ch <= _T('z')) ||
		(_T('A') <= ch && ch <= _T('Z')) ||
		ch == _T('_') || ch == _T('$') || ch == _T('@') || IsSJISFirst(ch);
}

inline bool IsSymbolChar(int ch) {
	return
		(_T('a') <= ch && ch <= _T('z')) ||
		(_T('A') <= ch && ch <= _T('Z')) ||
		ch == _T('_') || ch == _T('$') || (_T('0') <= ch && ch <= _T('9'));
}

inline TCHAR ToUpper(TCHAR ch) {
	return (_T('a') <= ch && ch <= _T('z'))? ch - _T('a') + _T('A') : ch;
}

inline TCHAR ToLower(TCHAR ch) {
	return (_T('A') <= ch && ch <= _T('Z'))? ch - _T('A') + _T('a') : ch;
}

inline int CompareChar(TCHAR ch1, TCHAR ch2, bool ignoreCaseFlag) {
	return ignoreCaseFlag?
		static_cast<int>(ToUpper(ch1)) - static_cast<int>(ToUpper(ch2)) :
		static_cast<int>(ch1) - static_cast<int>(ch2);
}

#if defined(WINVER)
inline bool IsPathSeparator(TCHAR ch) { return ch == _T(';'); }
#else
inline bool IsPathSeparator(TCHAR ch) { return ch == _T(';') || ch == _T(':'); }
#endif

//-----------------------------------------------------------------------------
// StringList
//-----------------------------------------------------------------------------
class StringList : public std::vector<String> {
public:
	static const StringList Null;
	inline StringList() {}
private:
	inline StringList(const StringList &stringList) {}
	inline void operator=(const StringList &stringList) {}
};

}

#endif
