/////////////////////////////////////
// ECCSkelton
// CARGクラス定義ファイル
// Copyright (c) August, 2022
//        By Ysama
//
//Note: GetCommandLineWの引数
// (1) 実行プログラムパス、ファイル名
// → 常に""で囲まれる
// (2)引数
// → 空白文字がある場合""で囲まれる
/////////////////////////////////////

class CARG
{
public:
	int		m_Argc;					//コマンドライン引数の数
	CSTR	m_Argv[128];			//コマンドライン引数配列（コマンドラインの最大長が8,191）
	CSTR	m_Drive;				//第１引数のドライブ
	CSTR	m_Path;					//第１引数のパス
	CSTR	m_FileName;				//第１引数のファイル名
	CSTR	m_Ext;					//第１引数の拡張子

	CARG();							//コマンドラインを分解
	CARG(WCHAR*);					//引数を分解（ドライブ名、パス、ファイル名分析用）
	int c() {return m_Argc;}
	WCHAR* v(int i) {return m_Argv[i].ToChar();}
	WCHAR* Drive() {return m_Drive.ToChar();}
	WCHAR* Path() {return m_Path.ToChar();}
	WCHAR* FileName() {return m_FileName.ToChar();}
	WCHAR* Ext() {return m_Ext.ToChar();}
	WCHAR* GetLongName(WCHAR*);		//引数にスペースがあればダブルコーテーションをつける
	WCHAR* GetQuatoOff(WCHAR*);		//引数にダブルコーテーションがあればこれをとる
	CARG& operator = (WCHAR*);
};

//コマンドラインを分解
CARG::CARG() {

	//ロケールを指定（日本）
	setlocale(LC_ALL, "JPN");
	//コマンドラインをBuffにコピーする
	CSTR Buff(GetCommandLineW());
	//スペース文字で区切られた文字列（""で囲まれたものを含む）を切り出す
	for(m_Argc = 0; Buff.Next(m_Argv[m_Argc]); m_Argc++);
	//コマンド文字列(m_Argv[0])を分解する
	Buff = m_Argv[0].ToChar();
	//文字列の先頭（sp）と末尾(ep）のポインターを設定する
	WCHAR* sp = (WCHAR*)Buff.ToChar();
	WCHAR* ep = (WCHAR*)Buff.ToChar() + lstrlenW(Buff.ToChar()) - 1;
	WCHAR* last = 0;				//最後の'\'を指すポインター
	if(*sp == L'\"' && *ep == L'\"')
		*ep = L'\0';				//「""」で囲まれていれば外す（NULLを指す）
	//文字列の'\'を探す
	while(sp < ep) {
		if(*sp == L'\\')
			last = sp;				//spを進め、'\'があればその位置をlastに記録
		sp++;						//spを進める
	}
	if(!last) {						//'\'が無かった場合、lastは0である為
		MessageBoxW(NULL, L"文字列の構文が違法です", L"エラー", MB_OK | MB_ICONERROR);
		return;
	}
	*last = L'\0';					//パスとファイル名を切り離す
	//第１引数のファイル名を取り出す
	m_FileName = (last + 1);
	//第１引数の拡張子を取り出す
	WCHAR* p = StrStrW(m_FileName.ToChar(), L".");
	p ? (m_Ext = (p + 1)) : (m_Ext = L"\0");
	//第１引数のパス名を取り出す
	m_Path = Buff;
	for(p =  Buff.ToChar(); *p && *p != L':'; p++);
	if(*p == L':') {
		*(p + 1) = NULL;
		//第１引数のドライブ名を取り出す
		m_Drive = Buff;
	}
	else
		m_Drive = L"\0";
}

//引数を分解（ドライブ名、パス、ファイル名分析用）
CARG::CARG(WCHAR* str) {

	//ロケールを指定（日本）
	setlocale(LC_ALL, "JPN");
	//strをBuffにコピーする
	CSTR Buff(str);
	//スペース文字で区切られた文字列（""で囲まれたものを含む）を切り出す
	for(m_Argc = 0; Buff.Next(m_Argv[m_Argc]); m_Argc++);
	//コマンド文字列(m_Argv[0])を分解する
	Buff = m_Argv[0].ToChar();
	//文字列の先頭（sp）と末尾(ep）のポインターを設定する
	WCHAR* sp = (WCHAR*)Buff.ToChar();
	WCHAR* ep = (WCHAR*)Buff.ToChar() + lstrlenW(Buff.ToChar()) - 1;
	WCHAR* last = 0;				//最後の'\'を指すポインター
	if(*sp == L'\"' && *ep == L'\"')
		*ep = L'\0';				//「""」で囲まれていれば外す（NULLを指す）
	//文字列の'\'を探す
	while(sp < ep) {
		if(*sp == L'\\')
			last = sp;				//spを進め、'\'があればその位置をlastに記録
		sp++;						//spを進める
	}
	if(!last) {						//'\'が無かった場合、lastは0である為
		MessageBoxW(NULL, L"文字列の構文が違法です", L"エラー", MB_OK | MB_ICONERROR);
		return;
	}
	*last = L'\0';					//パスとファイル名を切り離す
	//第１引数のファイル名を取り出す
	m_FileName = (last + 1);
	//第１引数の拡張子を取り出す
	WCHAR* p = StrStrW(m_FileName.ToChar(), L".");
	p ? (m_Ext = (p + 1)) : (m_Ext = L"\0");
	//第１引数のパス名を取り出す
	m_Path = Buff;
	for(p =  Buff.ToChar(); *p && *p != L':'; p++);
	if(*p == L':') {
		*(p + 1) = NULL;
		//第１引数のドライブ名を取り出す
		m_Drive = Buff;
	}
	else
		m_Drive = L"\0";
}

//引数にスペースがあればダブルコーテーションをつける
WCHAR* CARG::GetLongName(WCHAR* str) {

	static WCHAR Buff[MAX_PATH];
	bool IsSpace = FALSE;
	for(int i = lstrlenW(str) - 1; i > 0; i--)
		if(iswspace(str[i])) {
			IsSpace = TRUE;
			break;
		}
	if(IsSpace) {
		Buff[0] = L'\"';
		lstrcatW(Buff, str);
		lstrcatW(Buff, L"\"");
		return Buff;
	}
	else
		return str;
}

//引数にダブルコーテーションがあればこれをとる
WCHAR* CARG::GetQuatoOff(WCHAR* str) {

	if(*str == L'\"') {
		lstrcpy(str, str + 1);
		WCHAR* cp = str + lstrlenW(str) - 1;
		if(*cp == L'\"')
			*cp= L'\0';
	}
	return str;
}

//文字列の代入
CARG& CARG::operator = (WCHAR* cp) {

	CARG arg(cp);
	m_Argc = arg.m_Argc;			//コマンドライン引数の数
	for(int i = 0; i < m_Argc; i++)
		m_Argv[i] = arg.m_Argv[i];	//コマンドライン引数
	m_Drive = arg.m_Drive;			//第１引数のドライブ
	m_Path = arg.m_Path;			//第１引数のパス
	m_FileName = arg.m_FileName;	//打１引数のファイル名
	m_Ext = arg.m_Ext;			//打１引数の拡張子
	return *this;
}
