#ifndef _STRING_CONVERT_H_
#define _STRING_CONVERT_H_

#include "GdCPP_Exports.h"
#include <string>

#ifndef STRINGIZE
	// 宏转字符串
	#define STRINGIZE_IMPL(x) #x
	#define STRINGIZE(x) STRINGIZE_IMPL(x)
#endif

/// 忽略大小写判断string是否相等
GDCPP_API bool cmpIngoreCase(const std::string& s1, const std::string& s2);
GDCPP_API bool cmpIngoreCase(const std::string& s1, const char* s2);

/// 忽略大小写判断wstring是否相等
GDCPP_API bool cmpIngoreCase(const std::wstring& s1, const std::wstring& s2);
GDCPP_API bool cmpIngoreCase(const std::string& s1, const wchar_t* s2);

/// @brief utf16 std::wstring转utf8 std::string
/// @param wstr utf16 std::wstring
/// @return utf8 std::string
GDCPP_API std::string utf16_8(const std::wstring& wstr);

GDCPP_API std::string utf16_8(const wchar_t* wstr);
GDCPP_API int         utf16_8(const wchar_t* wstr, char* dst, int dstsize);

/// @brief utf8 std::string转utf16 std::wstring
/// @param str utf8 std::string
/// @return utf16字符串
GDCPP_API std::wstring utf8_16(const std::string& str);
GDCPP_API std::wstring utf8_16(const char* str);

GDCPP_API std::string Utf16ToGBK(const wchar_t* wstr);
GDCPP_API int         Utf16ToGBK(const wchar_t* wstr, char* dst, int dstsize);

GDCPP_API std::string GbkToUtf8(const std::string& src_str);
GDCPP_API std::string GbkToUtf8(const char* src_str);

GDCPP_API std::string Utf8ToGbk(const std::string& src_str);
GDCPP_API std::string Utf8ToGbk(const char* src_str);

#if defined(_MSC_VER) && defined(_UNICODE)
#include <atlstr.h>
/// @brief utf16 String转utf8 std::string
/// @param wstr utf16 String
/// @return utf8 std::string
static inline std::string CStringToUtf8(const CString& wstr)
{
	auto size = wstr.GetLength();
	if (size == 0) return std::string();
	const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, size, NULL, 0, NULL, NULL);
	std::string strTo(size_needed, 0);
	WideCharToMultiByte(CP_UTF8, 0, (const wchar_t*)wstr, size, &strTo[0], size_needed, NULL, NULL);
	return strTo;
}

/// @brief utf8 std::string转utf16 CString
/// @param str utf8 std::string
/// @return utf16 CString
static inline CString CStringFromUtf8(const std::string& str)
{
	if (str.empty()) return CString();
	int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
	CString wstrTo;
	auto buf = wstrTo.GetBufferSetLength(size_needed);
	MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), buf, size_needed);
	wstrTo.ReleaseBuffer();
	return wstrTo;
}

/// @brief utf8 const char *转utf16 CString
/// @param str utf8 const char *
/// @return utf16 CString
static inline CString CStringFromUtf8(const char* str)
{
	int len = int(strlen(str));
	if (len == 0) return CString();
	int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
	CString wstrTo;
	auto buf = wstrTo.GetBufferSetLength(size_needed);
	MultiByteToWideChar(CP_UTF8, 0, str, len, buf, size_needed);
	wstrTo.ReleaseBuffer();
	return wstrTo;
}
#endif

#endif //_STRING_CONVERT_H_