///////////////////////////////////////////////////////////////////////////////
//  CFilePath.cpp

#ifdef WIN32
#include <windows.h>
#include <shlobj.h>
#endif

#include "../../Independent/CharacterCode/IsCode.h"
#include "CFilePath.h"

namespace filesystem {

std::string		CFilePath::m_RootFolderPath;

CFilePath::CFilePath(void)
{
}

CFilePath::~CFilePath()
{
}

// ルートフォルダパスの設定
void CFilePath::SetRootFolderPath(const std::string& RootFolderPath)
{
	m_RootFolderPath = RootFolderPath;
}

//
void CFilePath::SetBaseFolderPath(void)
{
	m_FilePath = m_RootFolderPath;

	DeleteSeparator();
}

// 実行ファイルのパスを設定する
void CFilePath::SetExeFilePath(void)
{
#ifdef WIN32
	char Path[MAX_PATH + 1] = "";
	::GetModuleFileName(NULL, Path, MAX_PATH);

	m_FilePath = Path;
#endif
	DeleteSeparator();
}

//
void CFilePath::SetTemporaryFolderPath(void)
{
#ifdef WIN32
	char TemporaryFolderName[MAX_PATH + 1] = "";
	::GetTempPath(MAX_PATH, TemporaryFolderName);

	m_FilePath = TemporaryFolderName;
#endif

	DeleteSeparator();
}

void CFilePath::SetPersonalFolderPath(void)
{
#ifdef WIN32
	char Path[MAX_PATH + 1] = "";
	if (::SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, Path) == S_OK) {
		m_FilePath = Path;

		DeleteSeparator();
	}
	else {
		// 取得に失敗した場合は、ベースフォルダパスにする
		SetBaseFolderPath();
	}
#endif
}

void CFilePath::SetAppDataFolderPath(void)
{
#ifdef WIN32
	char Path[MAX_PATH + 1] = "";
	if (::SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, Path) == S_OK) {
		m_FilePath = Path;

		DeleteSeparator();
	}
	else {
		// 取得に失敗した場合は、ベースフォルダパスにする
		SetBaseFolderPath();
	}
#endif
}

// ファイル名の連結
// 終端にパス区切り文字が無ければ追加してから連結する
void CFilePath::AddFileName(const std::string& FileName)
{
	AddSeparator();

	m_FilePath += FileName;
}

// フォルダ名の連結
// 終端にパス区切り文字が無ければ追加してから連結する
void CFilePath::AddFolderName(const std::string& FolderName)
{
	AddSeparator();

	m_FilePath += FolderName;
}

//
const std::string& CFilePath::GetString(void) const
{
	return m_FilePath;
}

const char* CFilePath::c_str(void) const
{
	return m_FilePath.c_str();
}

std::string CFilePath::GetParentPath(void) const
{
	const std::string::size_type LastSeparatorIndex = GetLastSeparatorIndex();

	if (LastSeparatorIndex != std::string::npos) {
		// 最後のパス区切り文字は含めない
		return m_FilePath.substr(0, LastSeparatorIndex);
	}

	// パス区切り文字が無かった場合は、空文字列を返す

	return std::string();
}

std::string CFilePath::GetChildFileName(void) const
{
	const std::string::size_type LastSeparatorIndex = GetLastSeparatorIndex();

	if (LastSeparatorIndex != std::string::npos) {
		// 最後のパス区切り文字は含めない
		return m_FilePath.substr(LastSeparatorIndex + 1);
	}

	// パス区切り文字が無かった場合は、そのまま返す

	return m_FilePath;
}

//
std::string::size_type CFilePath::GetLastSeparatorIndex(void) const
{
	const std::string::size_type Length = m_FilePath.length();

	std::string::size_type LastIndex = std::string::npos;

	std::string::size_type Index;
	for (Index = 0; Index < Length; ) {
		if (IsKanji(m_FilePath[Index])) {
			Index += 2;
		}
		else {
			if (m_FilePath[Index] == '\\') LastIndex = Index;

			Index++;
		}
	}

	return LastIndex;
}

//
void CFilePath::AddSeparator(void)
{
	// ベースフォルダが空文字列の場合は先頭にセパレータを追加しない
	if (m_FilePath.empty()) return;

	//
	const int Length = static_cast<int>(m_FilePath.length());

	bool Exist = false;

	int i;
	for (i = 0; i < Length; ) {
		if (IsKanji(m_FilePath[i])) {
			i += 2;
			Exist = false;
		}
		else {
			if (m_FilePath[i] == '\\') Exist = true;
			else Exist = false;

			i++;
		}
	}

	if (!Exist) {
		m_FilePath += "\\";
	}
}

void CFilePath::DeleteSeparator(void)
{
	const int Length = static_cast<int>(m_FilePath.length());

	if (Length == 3 && IsAlpha(m_FilePath[0]) && m_FilePath[1] == ':' && m_FilePath[2] == '\\') {
		// ドライブルートの場合はセパレータ文字を削除しない
		return;
	}

	// 最後の【 \ 】を探す
	bool Exist = false;

	for (int i = 0; i < Length; ) {
		if (IsKanji(m_FilePath[i])) {
			i += 2;
			Exist = false;
		}
		else {
			if (m_FilePath[i] == '\\') Exist = true;
			else Exist = false;

			i++;
		}
	}

	if (Exist) {
		m_FilePath.pop_back();
	}
}

} // end of namespace filesystem

