///////////////////////////////////////////////////////////////////////////////
//  FormatString.cpp

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "../../Independent/CharacterCode/IsCode.h"
#include "FormatString.h"

namespace formatstring {

int PrintInt(char* pOutput, unsigned int OutputSize, const char* pFormat, int Value)
{
#ifdef _MSC_VER
	return sprintf_s(pOutput, OutputSize, pFormat, Value);
#else
	return sprintf(pOutput, pFormat, Value);
#endif

}

int PrintFloat(char* pOutput, unsigned int OutputSize, const char* pFormat, float Value)
{
#ifdef _MSC_VER
	return sprintf_s(pOutput, OutputSize, pFormat, Value);
#else
	return sprintf(pOutput, pFormat, Value);
#endif

}

int PrintString(char* pOutput, unsigned int OutputSize, const char* pFormat, const char* pValue)
{
#ifdef _MSC_VER
	return sprintf_s(pOutput, OutputSize, pFormat, pValue);
#else
	return sprintf(pOutput, pFormat, pValue);
#endif

}

void CopyString(char* pOutput, unsigned int OutputSize, const char* pText)
{
#ifdef _MSC_VER
	strcpy_s(pOutput, OutputSize, pText);
#else
	strcpy(pOutput, pText);
#endif

}

bool ScanInt(const std::string& Text, int& Value)
{
#ifdef _MSC_VER
	if (sscanf_s(Text.c_str(), "%d", &Value) != 1) return false;
#else
	if (sscanf(Text.c_str(), "%d", &Value) != 1) return false;
#endif

	return true;

}

bool ScanUnsignedInt(const std::string& Text, unsigned int& Value)
{
#ifdef _MSC_VER
	if (sscanf_s(Text.c_str(), "%u", &Value) != 1) return false;
#else
	if (sscanf(Text.c_str(), "%u", &Value) != 1) return false;
#endif

	return true;
}

bool ScanHexInt(const std::string& Text, int& Value)
{
#ifdef _MSC_VER
	if (sscanf_s(Text.c_str(), "%x", reinterpret_cast<unsigned int*>(&Value)) != 1) return false;
#else
	if (sscanf(Text.c_str(), "%x", reinterpret_cast<unsigned int*>(&Value)) != 1) return false;
#endif

	return true;
}

bool ScanFloat(const std::string& Text, float& Value)
{
#ifdef _MSC_VER
	if (sscanf_s(Text.c_str(), "%f", &Value) != 1) return false;
#else
	if (sscanf(Text.c_str(), "%f", &Value) != 1) return false;
#endif

	return true;
}

std::string Format(const char* pFormat, ...)
{
	va_list	List;

	va_start(List, pFormat);
	std::string Text = Format(pFormat, List);
	va_end(List);

	return Text;

}

std::string Format(const char* pFormat, va_list& ArgList)
{
	char Buffer[16384];
	Buffer[0] = '\0';

	FormatArgs(Buffer, 16384, pFormat, ArgList);

	return std::string(Buffer);

}

//==================================
std::string ToString(int Value)
{
	return Format("%d", Value);
}

//==================================
std::string ToString(float Value)
{
	return Format("%f", Value);
}

//==================================
std::string ToString(const std::string& Value)
{
	return Format("%s", Value.c_str());
}

int FormatArgs(char* pDest, size_t Size, const char* pFormat, va_list& ArgList)
{
#ifdef _MSC_VER
	return vsprintf_s(pDest, Size, pFormat, ArgList);
#else
	return vsprintf(pDest, pFormat, ArgList);
#endif

}

// 文字列を置換する（マルチバイト対応）
std::string Replace(const std::string& Base, const std::string& Find, const std::string& Text)
{
	std::string Buff;
	const char* pFind = &Find[0];
	const int FindSize = static_cast<int>(Find.size());
	const int Size = static_cast<int>(Base.size() - FindSize);
	for (int i = 0; i <= Size; ++i)
	{
		// 比較
		const int Result = memcmp(&Base[i], pFind, FindSize);

		// 一致しなかったので格納して次へ
		if (Result != 0) {
			Buff += Base[i];
			if (IsKanji(Base[i])) Buff += Base[++i];
			continue;
		}

		// 一致したので置換処理
		Buff += Text;
		i += (FindSize - 1);
	}

	return Buff;
}

//
std::vector<std::string> Split(const std::string& Text, const std::string& Delimiter)
{
	std::vector<std::string> ResultList;

	size_t FindPos = 0;

	for (;;) {
		const auto Pos = Text.find(Delimiter, FindPos);
		if (Pos == std::string::npos) {
			ResultList.push_back(Text.substr(FindPos));
			break;
		}

		ResultList.push_back(Text.substr(FindPos, Pos - FindPos));

		FindPos = Pos + Delimiter.length();
	}

	return ResultList;
}

} // end of namespace formatstring

