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

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

	//IDC_LISTBOX1のフォント当りのピクセルを調べる
	HWND hWnd = GetDlgItem(m_hWnd, IDC_LISTBOX1);		//リストボックスのハンドル
	HDC hDC = GetDC(hWnd);								//リストボックスのDC取得
	char str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";			//サンプル文字列
	int len = lstrlen(str);								//サンプル文字列の長さ
	GetTextExtentPoint(hDC, str, len, &size);			//sizeは外部変数
	ReleaseDC(hWnd, hDC);								//取得したDCの開放
	//IDC_LISTBOX1の水平スクロールバーをMAX_PATH分利用可能にする
	SendItemMsg(IDC_LISTBOX1, LB_SETHORIZONTALEXTENT, (size.cx * MAX_PATH / len) , (LPARAM)0);
	//「大文字小文字を区別」にチェックを入れる
	SendItemMsg(IDC_CHECKBOX1, BM_SETCHECK, BST_CHECKED, (LPARAM)0);
	return TRUE;
}

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

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

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

	//リストボックス内掃除
	int i = SendItemMsg(IDC_LISTBOX1, LB_GETCOUNT, 0, 0);
    if(i > 0) {
		for(--i; i >= 0; i--)
			SendItemMsg(IDC_LISTBOX1, LB_DELETESTRING, (WPARAM)i, 0);
	}
	//フォールダー選択とフォールダー内ファイルのリストボックス登録
	if(*Path) *Path = 0;	//cmndlg.GetPathキャンセル時、前のデータが残存
	lstrcpy(Path, cmndlg.GetPath(m_hWnd, "ファイルパスの選択"));
	if(!*Path) {
		MessageBox(m_hWnd, "パスが選択されていません", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		lstrcat(Path, "\\");
		CSTR path(Path);
		path = path + "*.*";		//ファイル名ベースにしないと機能しない
		SetListBoxFileNames(path.ToChar());
		return TRUE;
	}
}

bool CMyWnd::OnButton2() {

	//「大文字小文字を区別」の状態を確認し、記録UorLに記録
	int UorL = SendItemMsg(IDC_CHECKBOX1, BM_GETCHECK, 0, (LPARAM)0);
	//リストボックスから元のファイル名を取得
	int n = SendItemMsg(IDC_LISTBOX1, LB_GETCOUNT, 0, 0);
    if(!n) {
		MessageBox(m_hWnd, "ファイルがありません", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		//検索文字と置換文字をエディットボックスから取得
		char EDIT1[MAX_PATH / 2], EDIT2[MAX_PATH / 2];
		GetWindowText(GetDlgItem(m_hWnd, IDC_EDIT1), EDIT1, (LPARAM)MAX_PATH / 2);
		if(!*EDIT1) {
			MessageBox(m_hWnd, "変換対象文字が未入力です。", "エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		else
			if(!UorL)	//大文字小文字を区別しないならば、EDIT1の文字列を小文字化する
				CharLower(EDIT1);
		GetWindowText(GetDlgItem(m_hWnd, IDC_EDIT2), EDIT2, (LPARAM)MAX_PATH / 2);
		if(!*EDIT2) {
			MessageBox(m_hWnd, "変換文字が未入力です。", "エラー", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		//リストボックスから元のファイル名リストをコンマ（','）区切りで作成
		char buff1[MAX_PATH], buff2[MAX_PATH], temp[MAX_PATH];
		OldFiles = "";	//初期化
		NewFiles = "";	//初期化
		TBRFiles = "";	//初期化
		for(int i = 0; i < n; i++) {
			SendItemMsg(IDC_LISTBOX1, LB_GETTEXT, (WPARAM)i, (LPARAM)buff1);
			OldFiles = OldFiles + buff1;
			OldFiles = OldFiles + ",";
			if(!UorL) {	//大文字小文字を区別しないならば、buff1の文字列を小文字化する
				lstrcpy(temp, buff1);
				CharLower(buff1);
			}
			//置換して、新しいファイル名リストをコンマ（','）区切りで作成
			if(InstrRep(buff1, EDIT1, EDIT2, buff2) > 0) {
				NewFiles = NewFiles + buff2;	//変更後ファイル名
				NewFiles = NewFiles + ",";		//コンマ区切り
				if(!UorL) 						//小文字化したbuff1を元に戻す
					lstrcpy(buff1, temp);
				TBRFiles = TBRFiles + buff1;	//対応する旧ファイル名
				TBRFiles = TBRFiles + ",";		//コンマ区切り
			}
		}
	}
	showdlg.DoModal(m_hWnd, "IDD_SHOW", showdlgProc);
	return TRUE;
}

bool CMyWnd::OnButton3() {

	//ファイル名変更実行
	CSTR buff, buff1, buff2;
	while(TBRFiles.Next(buff1)) {
		buff = Path;
		buff = buff + buff1;
		buff1 = buff;
		NewFiles.Next(buff2);
		buff = Path;
		buff = buff + buff2;
		buff2 = buff;
		if(!MoveFile(buff1.ToChar(), buff2.ToChar()))
			MessageBox(m_hWnd, "ファイル名を変更できませんでした。", "ERROR", MB_OK | MB_ICONERROR);
	}
	//リストボックスとエディットボックスの掃除
	int i = SendItemMsg(IDC_LISTBOX1, LB_GETCOUNT, 0, 0);
    if(i > 0) {
		for(--i; i >= 0; i--)
			SendItemMsg(IDC_LISTBOX1, LB_DELETESTRING, (WPARAM)i, 0);
	}
	SetWindowText(GetDlgItem(m_hWnd, IDC_EDIT1), "");
	SetWindowText(GetDlgItem(m_hWnd, IDC_EDIT2), "");
	//修正後ファイルのリスト
	buff = Path;
	buff = buff + "*.*";
	SetListBoxFileNames(buff.ToChar());
	//終了確認
	if(MessageBox(m_hWnd, "終了しますか", "終了確認",
				MB_YESNO | MB_ICONINFORMATION) == IDYES) {
	//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		SendMsg(WM_CLOSE, 0, 0);
		return TRUE;
	}
	else
		return FALSE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool SHOWDLG::OnInit(WPARAM wParam, LPARAM lParam) {

	//リストボックス内掃除
	int i = SendItemMsg(IDC_LISTBOX10, LB_GETCOUNT, 0, 0);
    if(i > 0) {
		for(--i; i >= 0; i--)
			SendItemMsg(IDC_LISTBOX10, LB_DELETESTRING, (WPARAM)i, 0);
	}
	//IDC_LISTBOX10の水平スクロールバーを利用可能にする
	SendItemMsg(IDC_LISTBOX10, LB_SETHORIZONTALEXTENT, size.cx * MAX_PATH * MAX_PATH, (LPARAM)0);
	//変更予定ファイル名の登録
	CSTR Name, List(NewFiles);
	for(int i = 0; List.Next(Name); i++)
		SendItemMsg(IDC_LISTBOX10, LB_INSERTSTRING, i, (LPARAM)Name.ToChar());
	return TRUE;
}

bool SHOWDLG::OnIdok() {

	showdlg.EndModal(TRUE);
	return TRUE;
}

///////////////////////////////
//ユーザー関数定義
///////////////////////////////
bool CMyWnd::SetListBoxFileNames(char* path) {

	WIN32_FIND_DATA fd;
	HANDLE hFind = FindFirstFile(path, &fd);
	if (hFind == INVALID_HANDLE_VALUE) {
		MessageBox(m_hWnd, "ファイル情報取得失敗", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	else {
		int i = 0;
		do {
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);	// Directory
			else {													// Files
				SendItemMsg(IDC_LISTBOX1, LB_INSERTSTRING, i++, (LPARAM)fd.cFileName);
			}
		} while (FindNextFile(hFind, &fd));
	}
	FindClose(hFind);
	return TRUE;
}

char* CMyWnd::InstrRep(char* s1, char* s2, char* s3 = 0, char* s4 = 0) {

	char *p1, *p2, *findp = 0;		// Pointers to s1
	if(!*s2) return (char*)-1;		// If s2 is NULL string, returns -1
	p1 = s1; p2 = s2;
	do {
		if(findp) {
			if(!*p2) {				// Matching cimplete
				if(s3) {			// Replacing procedure
					int i;
					for(i = 0; i < (findp - s1); i++)
						s4[i] = s1[i];
					s4[i] = 0;		// Null termination
					strcat(s4, s3);	// Copying s3 in place of s2
					strcat(s4, p1);	// Copying the rest of s1
				}				
				return findp;
			}
			else 					// *s2 is not NULL == did not match
				if(*p1 != *p2) {
					p2 = s2;				// Resetting and repeat
					findp = 0;
				}
		}
		if(*p1 == *p2) {			// 同時に\0の場合が対応されていない
			if(!findp)
				findp = p1;			// Record p1 where s2 is found only once
			++p2;
		}
	} while(*p1++);
	return 0;
}
