//////////////////////////////////////////
// TradFilerProc.h
// Copyright (c) 05/13/2020 by BCCSkelton
//////////////////////////////////////////

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

	//コモンコントロールの初期化
	InitCommonControls();

	//ツールバー登録−Init(hWnd, hIinstance, ID, Style)
	TBar.Init(m_hWnd, m_hInstance, TOOLBAR, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS);
	//ツールバーボタン用ビットマップ追加（カスタムツールバーボタンを使用）
	TBar.AddBmp(m_hInstance, "IDI_TBAR", 7);
	//ツールバーボタン追加
	TBBUTTON tbb[11];
	ZeroMemory(tbb, sizeof(tbb));
	tbb[0].iBitmap = TBar.m_id;
	tbb[0].fsState = TBSTATE_ENABLED;
	tbb[0].fsStyle = TBSTYLE_BUTTON;
	tbb[0].idCommand = IDM_EXIT;
	tbb[1].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[2].iBitmap = TBar.m_id + 1;
	tbb[2].fsState = TBSTATE_ENABLED;
	tbb[2].fsStyle = TBSTYLE_BUTTON;
	tbb[2].idCommand = IDM_EXE;
	tbb[3].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[4].iBitmap = TBar.m_id + 2;
	tbb[4].fsState = TBSTATE_ENABLED;
	tbb[4].fsStyle = TBSTYLE_BUTTON;
	tbb[4].idCommand = IDM_DEL;
	tbb[5].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[6].iBitmap = TBar.m_id + 3;
	tbb[6].fsState = TBSTATE_ENABLED;
	tbb[6].fsStyle = TBSTYLE_BUTTON;
	tbb[6].idCommand = IDM_COPY;
	tbb[7].iBitmap = TBar.m_id + 4;
	tbb[7].fsState = TBSTATE_ENABLED;
	tbb[7].fsStyle = TBSTYLE_BUTTON;
	tbb[7].idCommand = IDM_CUT;
	tbb[8].iBitmap = TBar.m_id + 5;
	tbb[8].fsState = TBSTATE_ENABLED;
	tbb[8].fsStyle = TBSTYLE_BUTTON;
	tbb[8].idCommand = IDM_RENAME;
	tbb[9].fsStyle = TBSTYLE_SEP;	//セパレーター
	tbb[10].iBitmap = TBar.m_id + 6;
	tbb[10].fsState = TBSTATE_ENABLED;
	tbb[10].fsStyle = TBSTYLE_BUTTON;
	tbb[10].idCommand = IDM_VERSION;
	TBar.AddButtons(11, tbb);

	//ステータスバー登録−Init(hWnd, hIinstance, ID, (以下省略可）Style)
	SBar.Init(m_hWnd, m_hInstance, STATUSBAR);
	//ステータスバー区画設定
	int sec[2] = {200, -1};
	SBar.SetSection(2, sec);
	//ステータスバー文字列設定
	SBar.SetText(0, "TradFiler Ver 1.0");

	//ツリービューイメージリストへのイメージの追加
	tv.AddBitmap(MAKEINTRESOURCE(IDI_CFOLDER), m_hInstance, RGB(16, 16, 16));
	tv.AddBitmap(MAKEINTRESOURCE(IDI_OFOLDER), m_hInstance, RGB(16, 16, 16));
	tv.AddBitmap(MAKEINTRESOURCE(IDI_FILE), m_hInstance, RGB(16, 16, 16));
	//ツリービューの作成
	tv.Create(m_hWnd, m_hInstance, IDC_TREEVIEW);
	tv.SetFont(9, "ＭＳ 明朝");
	//ツリービューアイテムの追加（ビットマップ付）
	g_hRoot = tv.InsertItem(g_Root.ToChar(), TVI_LAST, TVI_ROOT, 0, 1);

	//CHISTORY変数のiniファイル設定
	char *pt;
	if(pt = strstr(g_CmdLine, "TradFiler.exe")) {
		lstrcpy(pt, "init.ini");
		history.SetPath(g_CmdLine);
		history.SetMenu(GetSubMenu(GetSubMenu(GetMenu(m_hWnd), 0), 8));
		history.Init();
	}

	return TRUE;
}

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

	if(wParam == IDC_TREEVIEW) {
		switch(((TV_DISPINFO*)lParam)->hdr.code) {
			//メッセージを解読し、選択変更があれば
			case TVN_SELCHANGED: {
				//選択アイテムを取得
				g_hSelected = tv.GetSelection();
				//選択アイテムの情報を取得
				char Buff[MAX_PATH];
				LPTV_ITEM tvitem_pt = tv.GetItem(g_hSelected, Buff, MAX_PATH);
				int DorF = tvitem_pt->iImage;	//tvitem_pt->iImageの値を記録
				CSTR Path = g_Root;
				//ルートでなければ親を辿り、ルートまでのパスをPathに記録
				if(g_hSelected != g_hRoot) {
					HTREEITEM hParent, hChild = g_hSelected;
					CSTR temp = Buff;
					//選択アイテムから
					while(hParent = tv.GetParent(hChild)) {
						tv.GetItem(hParent, Buff, MAX_PATH);
						temp = "\\" + temp;
						temp = Buff + temp;
						hChild = hParent;
					}
					Path = temp;
				}
				//パスはステータスバーに表示
				SBar.SetText(1, Path.ToChar());
				SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)Path.ToChar());	//ToolTipをつける
				//選択アイテムに子がいればファイルではなく、展開の必要もないので戻る
				if(tv.GetChild(g_hSelected)) return FALSE;
				//アイコンからフォールダーかファイルかを判別
				if(DorF < 2) {	//フォールダーアイテム
					//パス名から、ファイル情報を取得
					Path = Path + "\\*.*";	//ファイル名ベースにしないと機能しない
					WIN32_FIND_DATA fd;
					HANDLE hFind = FindFirstFile(Path.ToChar(), &fd);
					if(hFind == INVALID_HANDLE_VALUE) {
						MessageBox(m_hWnd, "このフォールダーにはファイル等がありません", "エラー", MB_OK | MB_ICONERROR);
						FindClose(hFind);
						return FALSE;
					}
					else {	//子を追加する
						//ツリービューアイテムの追加（ビットマップ付）
						do {
							if(*fd.cFileName != '.') {
								if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)	// Directory
									tv.InsertItem(fd.cFileName, TVI_LAST, g_hSelected, 0, 1);
								else												// Files
									tv.InsertItem(fd.cFileName, TVI_LAST, g_hSelected, 2, 2);
							}
						} while (FindNextFile(hFind, &fd));
					}
					FindClose(hFind);
					g_SelectedFile = "";	//フォールダーの場合は処理対象外でヌル
					return TRUE;
				}
				else {	//ファイルアイテム−処理対象でパス、ファイル名を記録
					g_SelectedFile = Path;
					return TRUE;
				}
			}
			case TVN_ENDLABELEDIT: {
				//ラベル編集完了
				TreeView_SetItem(tv.m_hWnd, &((TV_DISPINFO*)lParam)->item);
				//ファイル名を新しいラベル名に変更
				char oldfn[MAX_PATH], newfn[MAX_PATH];
				SendMessage(SBar.m_hWnd, SB_GETTEXT, 1, (LPARAM)oldfn);
				lstrcpy(newfn, oldfn);
				char *fn;
				for(fn = newfn + lstrlen(newfn) - 1; *fn != '\\'; fn--);
				*++fn = 0;
				lstrcat(newfn, ((TV_DISPINFO*)lParam)->item.pszText);
				if(!MoveFile(oldfn, newfn)) {
					MessageBox(m_hWnd, "ファイル名を変更できませんでした", "エラー", MB_OK | MB_ICONERROR);
				}
				else {
					//パスはステータスバーに表示
					SBar.SetText(1, newfn);	//新ファイル名に変更
					SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)newfn);	//ToolTipをつける
					g_SelectedFile = newfn;	//新ファイル名に変更
				}
				//ラベル編集を不可に戻す
				g_Style ^= TVS_EDITLABELS;
				SetWindowLong(tv.m_hWnd, GWL_STYLE, g_Style);
				//ラベル編集ボタンを利用可能にする
				SendMessage(TBar.m_hWnd, TB_ENABLEBUTTON, IDM_RENAME, MAKELONG(TRUE, 0));
				return TRUE;
			}
			case NM_RCLICK: {	//右クリックしたら
				//ウインドウの位置情報を取得
				RECT rec;
				GetWindowRect(m_hWnd, &rec);
				//ポップアップメニューの表示場所を設定
				POINT pt;
				GetCursorPos(&pt);
				//ポップアップメニューの表示
				TrackPopupMenu(GetSubMenu(GetMenu(m_hWnd), 0), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, m_hWnd, &rec);
				break;
			}
			case NM_DBLCLK: {	//ダブルクリックしたら
				//選択アイテムの情報を取得
				LPTV_ITEM tvitem_pt = tv.GetItem(g_hSelected, NULL, 0);
				//ファイルであればOnExeへ
				if(tvitem_pt->iImage >= 2)
					OnExe();
				break;
			}
		}
	}
	if(((LPNMHDR)lParam)->code == TTN_NEEDTEXT) {
		((LPTOOLTIPTEXT)lParam)->hinst = m_hInstance;
		switch(((LPTOOLTIPTEXT)lParam)->hdr.idFrom) {
		case IDM_EXE:
			((LPTOOLTIPTEXT)lParam)->lpszText = "実行";
			break;
		case IDM_DEL:
			((LPTOOLTIPTEXT)lParam)->lpszText = "削除";
			break;
		case IDM_CUT:
			((LPTOOLTIPTEXT)lParam)->lpszText = "ファイルの移動";
			break;
		case IDM_COPY:
			((LPTOOLTIPTEXT)lParam)->lpszText = "ファイルのコピー";
			break;
		case IDM_RENAME:
			((LPTOOLTIPTEXT)lParam)->lpszText = "ファイル名変更";
			break;
		case IDM_VERSION:
			((LPTOOLTIPTEXT)lParam)->lpszText = "バージョン情報";
			break;
		case IDM_EXIT:
			((LPTOOLTIPTEXT)lParam)->lpszText = "終了";
			break;
		}
		return TRUE;
	}
	return FALSE;
}

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

	TBar.AutoSize();
	SBar.AutoSize();
	//ツリービューをクライアント領域にあわせる
	RECT rec;
	int tbhigh, w = LOWORD(lParam), h = HIWORD(lParam);
	GetWindowRect(TBar.m_hWnd, &rec);
	tbhigh = rec.bottom - rec.top;
	GetWindowRect(SBar.m_hWnd, &rec);
	h -= (tbhigh + rec.bottom - rec.top);
	tv.Move(0, tbhigh, w, h);
	return TRUE;
}

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

	if(MessageBox(m_hWnd, "終了しますか", "終了確認",
					MB_YESNO | MB_ICONQUESTION) == IDYES) {
		//処理をするとDestroyWindow、PostQuitMessageが呼ばれる
		history.WriteIni();	//履歴をiniファイルに書き込む
		return TRUE;
	}
	else
		//そうでなければウィンドウではDefWindowProc関数をreturn、ダイアログではreturn FALSEとなる。
		return FALSE;
}

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

	//選択アイテムの情報を取得
	char Name[MAX_PATH];
	LPTV_ITEM tvitem_pt = tv.GetItem(g_hSelected, Name, MAX_PATH);
	//フォールダーであれば戻る
	if(tvitem_pt->iImage < 2) {
		MessageBox(m_hWnd, "選択されているのはフォールダーです", "エラー", MB_OK | MB_ICONERROR);
		return FALSE;
	}
	if(*g_SelectedFile.ToChar()) {
		if(WinExec(g_SelectedFile.ToChar(), SW_SHOWNORMAL) < 32) {
			if(MessageBox(m_hWnd, "実行可能ファイルではありません。関連付けられたプログラムで開きますか？",
				"エラー", MB_YESNO | MB_ICONERROR) == IDYES) {
				char Path[MAX_PATH];
				lstrcpy(Path, g_SelectedFile.ToChar());
                char *pt = strstr(Path, Name);
				if(pt--) *pt = 0;
				char ExeFile[MAX_PATH];
				if ((int)FindExecutable(Name, Path, ExeFile) > 32) {
					CSTR Cmd = "\"";				//実行ファイルパス、名を「"」で囲む
					Cmd = Cmd + ExeFile;
					Cmd = Cmd + "\" \"";			//データファイルパス、名を「"」で囲む
					Cmd = Cmd + g_SelectedFile;
					Cmd = Cmd + "\"";
					WinExec(Cmd.ToChar(), SW_SHOWNORMAL);
				}
				else
					MessageBox(m_hWnd, "関連付けられたプログラムがありません", "エラー", MB_OK | MB_ICONERROR);
			}
		}
		else
			history.AddItem(g_SelectedFile.ToChar());	//実行ファイルを履歴に記録
	}
	else
		MessageBox(m_hWnd, "ファイルが選択されていません", "エラー", MB_OK | MB_ICONERROR);
	return TRUE;
}

bool CMyWnd::OnDel() {

	if(*g_SelectedFile.ToChar()) {
		CSTR msg = g_SelectedFile;
		msg = msg + "\nを削除します。よろしいですか？";
		int yn = MessageBox(m_hWnd, msg.ToChar(), "ファイル削除", MB_YESNO | MB_ICONWARNING);
		if(yn == IDYES) {
			DeleteFile(g_SelectedFile.ToChar());
			tv.DeleteItem(g_hSelected);
			return TRUE;
		}
	}
	else
		MessageBox(m_hWnd, "ファイルが選択されていません", "エラー", MB_OK | MB_ICONERROR);
	return FALSE;
}

bool CMyWnd::OnCut() {

	//対象ファイルが選択されていたら
	if(*g_SelectedFile.ToChar()) {
		CSTR msg = g_SelectedFile;
		msg = msg + " ⇒ ";
		char Target[MAX_PATH] = {0};
		lstrcpy(Target, cmndlg.GetPath(m_hWnd, "移動先"));
		if(!*Target) {
			msg = "移動先が指定されませんでした。";
			MessageBox(m_hWnd, msg.ToChar(), "移動先指定失敗", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		msg = msg + Target;
		SBar.SetText(1, msg.ToChar());	//ファイル移動確認用
		SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)msg.ToChar());	//ToolTipをつける
		char *fn, *item;
		for(fn = g_SelectedFile.ToChar() + lstrlen(g_SelectedFile.ToChar()) - 1; *fn != '\\'; fn--);
		lstrcat(Target, fn);	//"\(file name)"を指している
		fn++;					//'\'を指しているので一つ進める
		for(item = Target + lstrlen(Target) - 1; item >= Target && *item != '\\'; item--);
		item++;	//Targetや'\'から一つ戻っているのを戻す
		//ファイルのコピー
		MoveFile(g_SelectedFile.ToChar(), Target);
		//コピー先のアイテムを追加
		HTREEITEM add = tv.FindItem(g_hRoot, item);
		if(add)
			tv.InsertItem(fn, TVI_LAST, add, 2, 2);
		//元のファイルとツリービューのアイテムを削除
		DeleteFile(g_SelectedFile.ToChar());
		tv.DeleteItem(g_hSelected);
		return TRUE;
	}
	else
		MessageBox(m_hWnd, "ファイルが選択されていません", "エラー", MB_OK | MB_ICONERROR);
	return FALSE;
}

bool CMyWnd::OnCopy() {

	//対象ファイルが選択されていたら
	if(*g_SelectedFile.ToChar()) {
		CSTR msg = g_SelectedFile;
		msg = msg + " ⇒ ";
		char Target[MAX_PATH] = {0};
		lstrcpy(Target, cmndlg.GetPath(m_hWnd, "コピー先"));
		if(!*Target) {
			msg = "コピー先が指定されませんでした。";
			MessageBox(m_hWnd, msg.ToChar(), "コピー先指定失敗", MB_OK | MB_ICONERROR);
			return FALSE;
		}
		msg = msg + Target;
		SBar.SetText(1, msg.ToChar());	//ファイル移動確認用
		SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)msg.ToChar());	//ToolTipをつける
		char *fn, *item;
		for(fn = g_SelectedFile.ToChar() + lstrlen(g_SelectedFile.ToChar()) - 1; *fn != '\\'; fn--);
		lstrcat(Target, fn);	//"\(file name)"を指している
		fn++;					//'\'を指しているので一つ進める
		for(item = Target + lstrlen(Target) - 1; item >= Target && *item != '\\'; item--);
		item++;	//Targetや'\'から一つ戻っているのを戻す
		//ファイルのコピー
		MoveFile(g_SelectedFile.ToChar(), Target);
		//コピー先のアイテムを追加
		HTREEITEM add = tv.FindItem(g_hRoot, item);
		if(add)
			tv.InsertItem(fn, TVI_LAST, add, 2, 2);
		return TRUE;
	}
	else
		MessageBox(m_hWnd, "ファイルが選択されていません", "エラー", MB_OK | MB_ICONERROR);
	return FALSE;
}

bool CMyWnd::OnRename() {

	if(g_hSelected) {
		//ラベル編集を可能にする
		g_Style = GetWindowLong(tv.m_hWnd, GWL_STYLE);
		g_Style |= TVS_EDITLABELS;
		SetWindowLong(tv.m_hWnd, GWL_STYLE, g_Style);
		//ラベル編集開始
		TreeView_EditLabel(tv.m_hWnd, g_hSelected);
		//ラベル編集ボタンを利用不可にする
		SendMessage(TBar.m_hWnd, TB_ENABLEBUTTON, IDM_RENAME, MAKELONG(FALSE, 0));
		return TRUE;
	}
	return FALSE;
}

bool CMyWnd::OnExit() {

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

bool CMyWnd::OnVersion() {

	versiondlg.DoModal(m_hWnd, "IDD_VERSION", versiondlgProc);
	return TRUE;
}

bool CMyWnd::OnDefault(WPARAM wParam) {	//WM_COMMANDの特殊処理

	char menuitem[MAX_PATH];
	int num = LOWORD(wParam) - IDM_HISTORY;
	if(num >= 0 && num < ITEM_MAX) {
		MENUITEMINFO mii = {0};	//ZeroMemory(&mii, sizeof(MENUITEMINFO));と同じ初期設定
		mii.cbSize		= sizeof(MENUITEMINFO);
		mii.fMask		= MIIM_ID | MIIM_TYPE;
		mii.fType		= MFT_STRING;
		mii.dwTypeData	= NULL;
		if(GetMenuItemInfo(GetSubMenu(GetSubMenu(GetMenu(m_hWnd), 0), 8), num, TRUE, &mii)) {
			mii.fType		= MFT_STRING;
			mii.dwTypeData	= menuitem;
			mii.cch++;
			if(GetMenuItemInfo(GetSubMenu(GetSubMenu(GetMenu(m_hWnd), 0), 8), num, TRUE, &mii)) {
				WinExec(mii.dwTypeData, SW_SHOWNORMAL);
			}
		}
	}
	return TRUE;
}

///////////////////////////////
//ユーザーダイアログの関数定義
//コントロール関数
///////////////////////////////
bool VERSIONDLG::OnIdok() {

	EndModal(TRUE);
	return TRUE;
}

