//
//	ToolLib_FileSelect.cpp
//
//	エディター共通処理 - ツールのGUIのファイル選択
//
//	* Tue Apr 18 21:46:46 JST 2017 Naoyuki Sawa
//	- 1st リリース。
//	* Wed Apr 19 22:11:14 JST 2017 Naoyuki Sawa
//	- 「①DxLibに依存しないようにする」と「②C言語でコンパイル出来るようにする」を対応しました。
//	  詳細は、/clip/ToolLib/README.TXT の、同日のコメントを参照して下さい。
//	* Thu Apr 20 21:31:57 JST 2017 Naoyuki Sawa
//	- 当ライブラリが生成するオブジェクトの識別子を、整数ハンドル⇒ポインタに変更しました。
//	  オリジナル版では生成したオブジェクトを固定長配列に格納して管理していたのですが、メモリ節約のためにリストで管理するように変更し、そのためには整数ハンドルよりもポインタの方が都合が良いからです。
//	  尚、フォントハンドルと文字列入力ハンドルは、当ライブラリが生成するオブジェクトではなくバックエンドのオブジェクトなので、今回の変更には関係無く整数ハンドルのままです。
//
#include "clip.h"
#ifdef  TOOLLIB_USE_STRINGINPUT
//*****************************************************************************
//	定数、マクロ、構造体
//*****************************************************************************
#define TOOL_NAME_X	(4)				//┬名前を描画する座標。
#define TOOL_NAME_Y	(0)				//┘
#define TOOL_PATH_X	(4)				//┬パス表示領域の左上座標。
#define TOOL_PATH_Y	(18)				//┘
#define TOOL_PATH_W	(242)				//┬パス表示領域のサイズ。
#define TOOL_PATH_H	(17)				//┘
#define TOOL_BUTTON_Y	(TOOL_PATH_Y+TOOL_PATH_H+4)	//ボタン表示領域のY座標。
#define TOOL_BUTTON_W	(42)				//┬ボタン表示領域のサイズ。
#define TOOL_BUTTON_H	(20)				//┘
#define TOOL_OPEN_X	(4)				//「参照」ボタンのX座標。
#define TOOL_APPLY_X	(TOOL_OPEN_X+TOOL_BUTTON_W+4)	//「適用」ボタンのX座標。
//-----------------------------------------------------------------------------
//ファイル選択構造体
/*typedef*/ struct _SToolFileSelect {
	SToolVisible*		TVisible;	//関連付けられている表示状態情報。
	SToolWindow*		TWindow;	//関連付けられているウインドウ情報。
	SToolButton*		OpenTButton;	//「参照」ボタン情報。
	SToolButton*		ApplyTButton;	//「適用」ボタン情報。
	SToolStringInput*	TStringInput;	//ファイルパス編集用文字列入力情報。
	POINT			Position;	//表示座標。
	char*			Name;		//名前の文字列が格納されているメモリアドレスを保存しているポインタ。
	int			Visible;	//表示状態。
	int			EndFlag;	//ファイル選択処理が終了しているかどうか。
} /*SToolFileSelect*/;
//*****************************************************************************
//	ローカル変数
//*****************************************************************************
static GSList*	g_TFileSelect;
//*****************************************************************************
//	ローカル関数宣言
//*****************************************************************************
static void ToolFileSelect_Step(SToolFileSelect* TFileSelect, double StepTime);
static void ToolFileSelect_Draw(SToolFileSelect* TFileSelect);
//*****************************************************************************
//	アプリケーション用関数
//*****************************************************************************
//ファイル選択処理情報を作成する。
//[in]
//	Name			名前の文字列が格納されたメモリアドレス。
//	x,y			ファイル選択処理の表示をする座標。
//[out]
//	戻り値			ファイル選択処理情報。
SToolFileSelect* ToolFileSelect_Create(const char* Name, int x, int y) {
	SToolFileSelect* TFileSelect;
	//新しいボタン情報を格納するためのメモリの確保。
	TFileSelect = calloc(1, sizeof(SToolFileSelect));
	if(!TFileSelect) { DIE(); }
	//確保したメモリ領域を保存。
	g_TFileSelect = g_slist_append(g_TFileSelect, TFileSelect);
	//「参照」ボタンを作成。
	TFileSelect->OpenTButton  = ToolButton_Create(0, "参照", 0, 0, TOOL_BUTTON_W, TOOL_BUTTON_H);
	//「適用」ボタンを作成。
	TFileSelect->ApplyTButton = ToolButton_Create(0, "適用", 0, 0, TOOL_BUTTON_W, TOOL_BUTTON_H);
	//ファイルパス編集用文字列入力情報を作成。
	TFileSelect->TStringInput = ToolStringInput_Create(NULL, x + TOOL_PATH_X, y + TOOL_PATH_Y, 0, 100, TOOL_PATH_W);
	//情報を初期化。
//不要	TFileSelect->TVisible = NULL;
//不要	TFileSelect->TWindow  = NULL;
	TFileSelect->Visible  = 1;
//不要	TFileSelect->EndFlag  = 0;
	if(Name) {
		TFileSelect->Name = strdup(Name);
		if(!TFileSelect->Name) { DIE(); }
	}
	ToolFileSelect_SetPosition(TFileSelect, x, y);
	//ファイル選択処理情報を返す。
	return TFileSelect;
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報を削除する。
//[in]
//	TFileSelect		ファイル選択処理情報。
void ToolFileSelect_Delete(SToolFileSelect* TFileSelect) {
	//ボタン情報や文字列入力情報の削除。
	ToolButton_Delete(TFileSelect->OpenTButton);
	ToolButton_Delete(TFileSelect->ApplyTButton);
	ToolStringInput_Delete(TFileSelect->TStringInput);
	//名前保存用にメモリを確保していた場合は解放。
	free(TFileSelect->Name);
	//確保していたメモリを解放する。
	g_TFileSelect = g_slist_remove(g_TFileSelect, TFileSelect);
	free(TFileSelect);
}
//-----------------------------------------------------------------------------
//全てのファイル選択処理情報を削除する。
void ToolFileSelect_Delete_All() {
	//有効な全てのファイル選択処理を削除する。
	while(g_TFileSelect) { ToolFileSelect_Delete(g_TFileSelect->data); }
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報に関連付ける表示状態情報をセットする。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	TVisible		表示状態情報。
void ToolFileSelect_SetVisibleHandle(SToolFileSelect* TFileSelect, SToolVisible* TVisible) {
	//表示状態情報の保存。
	TFileSelect->TVisible = TVisible;
	//ボタン情報や文字列入力情報にも表示状態情報を登録。
	ToolButton_SetVisibleHandle(TFileSelect->OpenTButton, TVisible);
	ToolButton_SetVisibleHandle(TFileSelect->ApplyTButton, TVisible);
	ToolStringInput_SetVisibleHandle(TFileSelect->TStringInput, TVisible);
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報と関連付けるウインドウ情報を設定する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	TWindow			ウインドウ情報。
void ToolFileSelect_SetWindow(SToolFileSelect* TFileSelect, SToolWindow* TWindow) {
	//ウインドウ情報の保存。
	TFileSelect->TWindow = TWindow;
	//ボタン情報や文字列入力情報にもウインドウ情報を登録。
	ToolButton_SetWindow(TFileSelect->OpenTButton, TWindow);
	ToolButton_SetWindow(TFileSelect->ApplyTButton, TWindow);
	ToolStringInput_SetWindow(TFileSelect->TStringInput, TWindow);
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報の表示位置を変更する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	x,y			変更後の座標。
void ToolFileSelect_SetPosition(SToolFileSelect* TFileSelect, int x, int y) {
	//座標を保存。
	TFileSelect->Position.x = x;
	TFileSelect->Position.y = y;
	//ボタン情報や文字列入力情報の座標も変更。
	ToolButton_SetPosition(     TFileSelect->OpenTButton,  x +  TOOL_OPEN_X, y + TOOL_BUTTON_Y);
	ToolButton_SetPosition(     TFileSelect->ApplyTButton, x + TOOL_APPLY_X, y + TOOL_BUTTON_Y);
	ToolStringInput_SetPosition(TFileSelect->TStringInput, x +  TOOL_PATH_X, y +   TOOL_PATH_Y);
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報の表示状態を変更する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	Visible			新しい表示状態。
void ToolFileSelect_SetVisible(SToolFileSelect* TFileSelect, int Visible) {
	//非表示の場合は文字列入力ハンドルのアクティブ状態も解除する。
	if(!Visible) { ToolStringInput_ResetActive(TFileSelect->TStringInput); }
	//新しい表示状態を保存する。
	TFileSelect->Visible = Visible;
	//ボタン情報や文字列入力情報の表示状態も変更。
	ToolButton_SetVisible(     TFileSelect->OpenTButton,  Visible);
	ToolButton_SetVisible(     TFileSelect->ApplyTButton, Visible);
	ToolStringInput_SetVisible(TFileSelect->TStringInput, Visible);
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報の表示状態を取得する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//[out]
//	戻り値			表示状態。(0以外:表示,0:非表示)
int ToolFileSelect_GetVisible(SToolFileSelect* TFileSelect) {
	//表示状態が0の場合は0を返す。
	if(!TFileSelect->Visible) { return 0; }
	//関連付けられているウインドウ情報の表示状態が0の場合は0を返す。
	if(!ToolWindow_GetVisible(TFileSelect->TWindow)) { return 0; }
	//表示状態情報が登録されていて、且つ表示状態情報の表示状態が0の場合は0を返す。
	if(!ToolVisible_GetVisible(TFileSelect->TVisible)) { return 0; }
	//ここにきていたら非表示ではないということなので0以外を返す。
	return 1;
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報の選択処理が完了しているかどうかを取得する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	Reset			処理が完了しているかどうかのフラグを倒すかどうか。
//[out]
//	戻り値			処理が完了しているかどうか。(0以外:完了している,0:まだ終わっていない)
int ToolFileSelect_CheckEnd(SToolFileSelect* TFileSelect, int Reset) {
	//処理が完了しているかどうかのフラグをローカル変数にコピーしておく。
	int Result = TFileSelect->EndFlag;
	//フラグをリセットする指定だった場合は完了フラグを倒す。
	if(Reset) { TFileSelect->EndFlag = 0; }
	//処理が完了しているかどうかのフラグをコピーしておいたローカル変数の内容を返す。
	return Result;
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報のファイルパスを設定する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	FilePath		ファイルパス文字列が格納されたメモリ領域の先頭アドレス。
void ToolFileSelect_SetPath(SToolFileSelect* TFileSelect, const char* FilePath) {
	//ファイルパス編集用の文字列入力情報にパスをセットする。
	ToolStringInput_SetString(TFileSelect->TStringInput, FilePath ? FilePath : "");
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報のファイルパスを取得する。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	DestBuffer		ファイルパスを格納するバッファの先頭アドレス。
void ToolFileSelect_GetPath(SToolFileSelect* TFileSelect, char* DestBuffer) {
	//ファイルパス編集用の文字列入力情報の文字列を取得する。
	ToolStringInput_GetString(TFileSelect->TStringInput, DestBuffer);
}
//-----------------------------------------------------------------------------
//全てのファイル選択処理情報の状態推移処理を行う。
//[in]
//	StepTime		進める時間。(単位:秒)
void ToolFileSelect_Step_All(double StepTime) {
	GSList* list = g_TFileSelect;
	while(list) {
		ToolFileSelect_Step(list->data, StepTime);
		list = list->next;
	}
}
//-----------------------------------------------------------------------------
//全てのファイル選択処理情報の描画移処理を行う。
void ToolFileSelect_Draw_All() {
	GSList* list = g_TFileSelect;
	while(list) {
		ToolFileSelect_Draw(list->data);
		list = list->next;
	}
}
//*****************************************************************************
//	ローカル関数
//*****************************************************************************
//ファイル選択処理情報の状態推移処理を行う。
//[in]
//	TFileSelect		ファイル選択処理情報。
//	StepTime		進める時間。(単位:秒)
static void ToolFileSelect_Step(SToolFileSelect* TFileSelect, double StepTime) {
	//非表示状態の場合は何もせず終了。
	if(!ToolFileSelect_GetVisible(TFileSelect)) { return; }	//ここまで
	//ファイルパス編集用の文字列入力情報処理が完了していたらファイル選択処理も完了状態にする。
	if(ToolStringInput_CheckEnd(TFileSelect->TStringInput, 1)) { TFileSelect->EndFlag = 1; }
	//「適用」ボタンが押されたらファイル選択処理を完了状態にする。
	if(ToolButton_GetClick(TFileSelect->ApplyTButton, 1)) { TFileSelect->EndFlag = 1; }
	//「参照」ボタンが押されたらファイル選択ダイアログを表示する。
	if(ToolButton_GetClick(TFileSelect->OpenTButton, 1)) {
		OPENFILENAME ofn;
		char FullPath[1024], FileName[1024];
		memset(&ofn, 0, sizeof ofn);
		memset(FullPath, 0, sizeof FullPath);
		memset(FileName, 0, sizeof FileName);
		ofn.lStructSize    = sizeof ofn;
		ofn.hwndOwner      = ToolFunc_GetMainWindowHandle();
		ofn.lpstrFilter    = "All Files(*.*)\0*.*\0";
		ofn.lpstrFile      = FullPath;
		ofn.nMaxFile       = sizeof(FullPath);
		ofn.lpstrFileTitle = FileName;
		ofn.nMaxFileTitle  = sizeof(FileName);
		ofn.lpstrTitle     = "開く";
		ofn.Flags          = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
		ofn.lpstrDefExt    = "";
		if(GetOpenFileName(&ofn)) {
			//ファイル選択ダイアログで選択されたファイルのパスをファイルパス編集用文字列入力情報に反映する。
			ToolStringInput_SetString(TFileSelect->TStringInput, FullPath);
		}
	}
}
//-----------------------------------------------------------------------------
//ファイル選択処理情報を画面に描画する。
//[in]
//	TFileSelect		ファイル選択処理情報。
static void ToolFileSelect_Draw(SToolFileSelect* TFileSelect) {
	int WinDrawX, WinDrawY;
	//非表示状態の場合は何もせず終了。
	if(!ToolFileSelect_GetVisible(TFileSelect)) { return; }	//ここまで
	//ウインドウ情報に関連付けられている場合はウインドウ情報の座標を取得する。
	if(TFileSelect->TWindow) {
		ToolWindow_GetDrawLeftUpPos(TFileSelect->TWindow, &WinDrawX, &WinDrawY);
		//ウインドウ情報を基にした描画範囲制限設定を行う。
		ToolWindow_SetupDrawArea(TFileSelect->TWindow);
	} else {
		WinDrawX = 0;
		WinDrawY = 0;
	}
	//名前の描画。
	ToolFunc_DrawStringToHandle(TFileSelect->Position.x + WinDrawX + TOOL_NAME_X,
	                            TFileSelect->Position.y + WinDrawY + TOOL_NAME_Y,
	                            TFileSelect->Name,
	                            ToolFunc_GetColor(255,255,255),
	                            ToolStatic_GetNormalFontHandle());
	//描画範囲制限を元に戻す。
	ToolFunc_SetDrawAreaFull();
}
#endif//TOOLLIB_USE_STRINGINPUT
