//////////////////////////////////////////
// FileNameCleanerProc.h
// Copyright (c) 05/06/2020 by BCCSkelton
//////////////////////////////////////////

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//ウィンドウメッセージ関数
/////////////////////////////////
bool CMyWnd::OnInit(WPARAM wParam, LPARAM lParam) {

	//クライアントエリアサイズを記録
	RECT rec;
	GetClientRect(m_hWnd, &rec);
	m_Width = rec.right - rec.left;
	m_Height = rec.bottom - rec.top;
	return TRUE;
}

bool CMyWnd::OnSize(WPARAM wParam, LPARAM lParam) {

	//コントロールの位置、サイズ変更
	RECT rec;	//矩形取得用
	POINT pt;	//スクリーン座標変換用
	int w, h;	//幅、高さ計算用
	int diffx = LOWORD(lParam) - m_Width;	//前回と今回の差分
	int diffy = HIWORD(lParam) - m_Height;	//前回と今回の差分
	m_Width = LOWORD(lParam);				//今回の幅
	m_Height = HIWORD(lParam);				//今回の高さ
	//左右移動－IDC_SELECT
	GetWindowRect(GetDlgItem(m_hWnd, IDC_SELECT), &rec);	//ウィンドウ位置取得
	w = rec.right - rec.left;
	h = rec.bottom - rec.top;
	pt.x = rec.left;
	pt.y = rec.top;
	ScreenToClient(m_hWnd, &pt);
	MoveWindow(GetDlgItem(m_hWnd, IDC_SELECT), pt.x + diffx, pt.y, w, h, TRUE);
	//幅変更－IDC_EDIT
	GetWindowRect(GetDlgItem(m_hWnd, IDC_EDIT), &rec);	//ウィンドウ位置取得
	w = rec.right - rec.left;
	h = rec.bottom - rec.top;
	pt.x = rec.left;
	pt.y = rec.top;
	ScreenToClient(m_hWnd, &pt);
	MoveWindow(GetDlgItem(m_hWnd, IDC_EDIT), pt.x, pt.y, w + diffx, h, TRUE);
	//幅高さ変更－IDC_FILELIST
	GetWindowRect(GetDlgItem(m_hWnd, IDC_FILELIST), &rec);	//ウィンドウ位置取得
	w = rec.right - rec.left;
	h = rec.bottom - rec.top;
	pt.x = rec.left;
	pt.y = rec.top;
	ScreenToClient(m_hWnd, &pt);
	MoveWindow(GetDlgItem(m_hWnd, IDC_FILELIST), pt.x, pt.y, w + diffx, h + diffy, TRUE);
	//左右上下移動－IDOK
	GetWindowRect(GetDlgItem(m_hWnd, IDOK), &rec);	//ウィンドウ位置取得
	w = rec.right - rec.left;
	h = rec.bottom - rec.top;
	pt.x = rec.left;
	pt.y = rec.top;
	ScreenToClient(m_hWnd, &pt);
	MoveWindow(GetDlgItem(m_hWnd, IDOK), pt.x + diffx, pt.y + diffy, w, h, TRUE);
	//クライアントエリアを再描画
	InvalidateRect(m_hWnd, NULL, TRUE);
	return TRUE;
}

bool CMyWnd::OnClose(WPARAM wPram, LPARAM lParam) {

	//終了確認
	if(MessageBoxW(m_hWnd, L"終了しますか", L"終了確認",
				MB_YESNO | MB_ICONINFORMATION) == IDYES) {
	//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		return TRUE;
	}
	else
		return FALSE;
}

bool CMyWnd::OnDestroy(WPARAM wPram, LPARAM lParam) {

	//ダイアログベースの場合はこれが必要
	PostQuitMessage(0);
	return TRUE;
}

bool CMyWnd::OnMinMax(WPARAM wParam, LPARAM lParam) {

	//典型的なウィンドウのサイズ制限処理
	MINMAXINFO *pmmi;
	pmmi = (MINMAXINFO*)lParam;
	pmmi->ptMinTrackSize.x = MINW + 16;	//クライアントエリア + 16
	pmmi->ptMinTrackSize.y = MINH + 39;	//クライアントエリア + 61
	return FALSE;							//処理はDefWndProcに任す
}

/////////////////////////////////
//主ウィンドウCMyWndの関数の定義
//メニュー項目、コントロール関数
/////////////////////////////////
bool CMyWnd::OnSelect() {

	//ファイル名クリーニングを行うフォールダーの選択
	WCHAR* fp = g_Cmndlg.GetPath(m_hWnd,
					L"ファイル名クリーニングを行うフォールダーの選択");
	//パス名を記録
	if(fp) {
		lstrcpyW(g_Path, fp);
		SendMessageW(GetDlgItem(m_hWnd, IDC_EDIT), WM_SETTEXT, 0, (LPARAM)g_Path);
	}
	else {
		MessageBoxW(m_hWnd, L"キャンセルされました", L"エラー",
					MB_OK | MB_ICONERROR);
		return FALSE;
	}
	//フォールダー名のチェック
	if(CheckName(g_Path)) {
		MessageBoxW(m_hWnd, L"フォールダー名をチェックしました。\n"\
					"続いてフォールダー内のファイルをチェックします。",
					L"成功", MB_OK | MB_ICONINFORMATION);
		SendMessageW(GetDlgItem(m_hWnd, IDC_EDIT), WM_SETTEXT, 0, (LPARAM)g_Cleaned);
		lstrcpyW(g_Path, g_Cleaned);	//g_Pathに修正版を記録
	}
	else {
		MessageBoxW(m_hWnd, L"フォールダー名のクリーニングに失敗しました。",
					L"失敗", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	//ファイル名のチェック
    if(CheckFiles(g_Path)) {
		SendMessageW(GetDlgItem(m_hWnd, IDC_FILELIST), WM_SETTEXT, 0, (LPARAM)g_OriginalList.ToChar());
		MessageBoxW(m_hWnd, L"これらファイル名をチェックしました。\n"\
					"最終ファイル名を表示します。",
					L"成功", MB_OK | MB_ICONINFORMATION);
		SendMessageW(GetDlgItem(m_hWnd, IDC_FILELIST), WM_SETTEXT, 0, (LPARAM)g_CleanedList.ToChar());
		return TRUE;
	}
	else {
		MessageBoxW(m_hWnd, L"ファイル名のクリーニングに失敗しました。",
					L"失敗", MB_OK | MB_ICONERROR);
		return FALSE;
	}
}

bool CMyWnd::OnOk() {

	SendMsg(WM_CLOSE, 0, 0);
	return TRUE;
}

///////////////////////////////
//ユーザー関数定義
//CheckName - フォールダー名、
//ファイル名に禁則文字が入って
//いるかチェックする
//無ければTRUEを返し、あれば
//削除結果を返す（TRUE、FALSE）
///////////////////////////////
bool CMyWnd::CheckName(WCHAR* name) {

	lstrcpyW(g_Original, name);
	//Unicodeの一般句読点(U+2000 - U+206F)がファイル名に含まれていれば、除去してRenameする
	int taboo = 0;
	WCHAR* sp = g_Original;
	WCHAR* dp = g_Cleaned;
	while(*sp != L'\0'){
		if(*sp >= 0x2000 && *sp <= 0x206F) {
			sp++;
			taboo++;
		}
		*dp++ = *sp++;	//g_Originalを修正してg_Cleanedへコピー
	}
	*dp = *sp;	//NULL終端をコピー
	WCHAR mes[MAX_PATH];
	if(taboo) {
		wsprintfW(mes, L"Unicodeの一般句読点(U+2000 - U+206F)文字が%d個見つかりました。削除しますか？", taboo);
		if(MessageBoxW(m_hWnd, mes, L"確認", MB_YESNO | MB_ICONQUESTION) == IDYES) {
			if(!ShellRename(g_Original, g_Cleaned))
				return FALSE;
		}
		else {
			MessageBoxW(m_hWnd, L"Unicodeの一般句読点(U+2000 - U+206F)文字が残ったままです", L"警告",
						MB_YESNO | MB_ICONQUESTION);
			return FALSE;
		}
	}
	return TRUE;
}

///////////////////////////////
//ユーザー関数定義
//GetFileName - 1 フォールダーの
//ファイル名を列挙して、禁則文字
//が入っているかチェックする
///////////////////////////////
bool CMyWnd::CheckFiles(WCHAR* path) {

	//g_OriginalList、g_CleanedListの初期化
	g_OriginalList = L"";
	g_CleanedList = L"";
	//フォールダー内ファイルのチェック
	CSTRW fl(path);
	fl = fl + L"\\*.*";
	WIN32_FIND_DATAW fd;
	HANDLE hFind = FindFirstFileW(fl.ToChar(), &fd);
	if (hFind == INVALID_HANDLE_VALUE) {
		MessageBoxW(m_hWnd, L"ファイル情報取得失敗", L"エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		while(FindNextFileW(hFind, &fd)) {
			//フォールダの場合は何もしない
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
			//ファイルの場合、g_Originalにファイル名をコピーしてCheckNameに掛ける
			else {
				//オリジナルリストの作成
				g_OriginalList = g_OriginalList + path;
				g_OriginalList = g_OriginalList + L"\\";
				g_OriginalList = g_OriginalList + fd.cFileName;
				g_OriginalList = g_OriginalList + L"\r\n";
				//Unicodeの一般句読点除去と修正版リストの作成
				fl = path;
				fl = fl + L"\\";
				fl = fl + fd.cFileName;
				if(CheckName(fl.ToChar())) {
					g_CleanedList = g_CleanedList + g_Cleaned;
					g_CleanedList = g_CleanedList + L"\r\n";
				}
				else
					MessageBoxW(m_hWnd, L"Unicodeの一般句読点除去に失敗しました", g_Original,
								MB_OK | MB_ICONEXCLAMATION);
			}
		}
	}
	FindClose(hFind);
	return TRUE;
}

//////////////////////////////////////////////
//ユーザー関数定義
//ShellExecuteExを起動し、プロセスの終了を待つ
//////////////////////////////////////////////
bool CMyWnd::ShellRename(WCHAR* original, WCHAR* clean) {

	//SHFileOperationを使う
	SHFILEOPSTRUCTW fop;
	ZeroMemory(&fop, sizeof(SHFILEOPSTRUCTW));
	fop.wFunc = FO_RENAME;
	//wFunc－実行したい機能を指定
	//FO_COPY	コピー
	//FO_DELETE	削除
	//FO_MOVE	移動
	//FO_RENAME	名前の変更
	fop.pFrom = original;
	fop.pTo   = clean;
	if(!SHFileOperationW(&fop)) {
		MessageBoxW(m_hWnd, L"SHFileOperationで名前変更しました", L"成功", MB_OK | MB_ICONINFORMATION);
		return TRUE;
	}
		else {
		MessageBoxW(m_hWnd, L"SHFileOperationの名前変更に失敗しました", L"失敗", MB_OK | MB_ICONERROR);
		return FALSE;
	}
}
