//
//	ToolLib_SpaceManage.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"
//*****************************************************************************
//	定数、マクロ、構造体
//*****************************************************************************
//スペース管理情報構造体
/*typedef*/ struct _SToolSpaceManage {
	GSList*		Space;			//登録されているスペース情報へのアドレスを格納しているポインタ変数。
	int		NextSpace;		//次のスペースに割り当てるスペース座標。
	int		TotalLockSpace;		//固定で確保されている総スペースサイズ。
	int		TotalSpace;		//総スペースサイズ。
	int		InitTotalSpace;		//初期化時の総スペースサイズ。
} /*SToolSpaceManage*/;
//*****************************************************************************
//	ローカル変数
//*****************************************************************************
static GSList*	g_TSpaceManage;
//*****************************************************************************
//	アプリケーション用関数
//*****************************************************************************
//スペース管理情報を作成する。
//[in]
//	TotalSpace		総スペースサイズ。
//[out]
//	戻り値			スペース管理情報。
SToolSpaceManage* ToolSpaceManage_Create(int TotalSpace) {
	SToolSpaceManage* TSpaceManage;
	//新しいスペース管理情報を格納するためのメモリの確保。
	TSpaceManage = calloc(1, sizeof(SToolSpaceManage));
	if(!TSpaceManage) { DIE(); }
	//確保したメモリ領域を保存。
	g_TSpaceManage = g_slist_append(g_TSpaceManage, TSpaceManage);
	//情報を初期化。
//不要	TSpaceManage->NextSpace      = 0;
//不要	TSpaceManage->TotalLockSpace = 0;
	TSpaceManage->TotalSpace     = TotalSpace;
	TSpaceManage->InitTotalSpace = TotalSpace;
	//スペース管理情報を返す。
	return TSpaceManage;
}
//-----------------------------------------------------------------------------
//スペース管理情報を削除する。
//[in]
//	TSpaceManage		スペース管理情報。
void ToolSpaceManage_Delete(SToolSpaceManage* TSpaceManage) {
	//登録されているスペース情報へのアドレスを格納しているポインタ変数のリストを解放する。
	g_slist_free(TSpaceManage->Space);
	//確保していたメモリを解放する。
	g_TSpaceManage = g_slist_remove(g_TSpaceManage, TSpaceManage);
	free(TSpaceManage);
}
//-----------------------------------------------------------------------------
//全てのスペース管理情報を削除する。
void ToolSpaceManage_Delete_All() {
	//有効な全てのスペース管理を削除する。
	while(g_TSpaceManage) { ToolSpaceManage_Delete(g_TSpaceManage->data); }
}
//-----------------------------------------------------------------------------
//スペース管理情報にスペース情報を追加する。
//[in]
//	TSpaceManage		スペース管理情報。
//	Space			スペース情報構造体のアドレス。
//	UseSpace		使用するスペースサイズ。-1を指定すると残りのスペース全てを割り当てる。
//	LockSpace		スペースが固定タイプかどうか。(0以外:固定タイプ,0:通常タイプ)
void ToolSpaceManage_AddSpace(SToolSpaceManage* TSpaceManage, SToolSpace* Space, int UseSpace, int LockSpace) {
	//使用するスペースサイズが-1だった場合は残りの全てのスペースを割り当てる。
	if(UseSpace == -1) { UseSpace = TSpaceManage->TotalSpace - TSpaceManage->NextSpace; }
	//情報を初期化。
	Space->LockSpace    = LockSpace;
	Space->UseSpace     = UseSpace;
	Space->InitUseSpace = UseSpace;
	Space->SpaceStart   = TSpaceManage->NextSpace;
	//次のスペースに割り当てるスペース開始位置を使用されるスペース分だけ移動する。
	TSpaceManage->NextSpace += UseSpace;
	//固定型スペースの場合は固定型スペースの総サイズに追加するスペースサイズを加算する。
	if(LockSpace) { TSpaceManage->TotalLockSpace += UseSpace; }
	//スペース管理情報にスペース情報を追加する。
	TSpaceManage->Space = g_slist_append(TSpaceManage->Space, Space);
}
//-----------------------------------------------------------------------------
//総スペースサイズを変更する。
//[in]
//	TSpaceManage		スペース管理情報。
//	TotalSpace		総スペースサイズ。
void ToolSpaceManage_ChangeTotalSpace(SToolSpaceManage* TSpaceManage, int TotalSpace) {
	int FreeSpace, NextFreeSpace, SpaceStart;
	GSList* list;
	//今までの総スペースサイズでの固定型ではないスペースのサイズを算出。
	FreeSpace = TSpaceManage->InitTotalSpace - TSpaceManage->TotalLockSpace;
	//新しい総スペースサイズでの固定型ではないスペースのサイズを算出。
	NextFreeSpace =               TotalSpace - TSpaceManage->TotalLockSpace;
	//スペースの数だけ繰り返し。
	SpaceStart = 0;
	for(list = TSpaceManage->Space; list; list = list->next) {
		SToolSpace* Space = list->data;
		//スペース開始位置のセット。
		Space->SpaceStart = SpaceStart;
		//固定型スペースではない場合は総スペースサイズに対する割合から新しいスペースサイズを決定する。
		if(!Space->LockSpace) { Space->UseSpace = Space->InitUseSpace * NextFreeSpace / FreeSpace; }
		//スペース開始位置を移動する。
		SpaceStart += Space->UseSpace;
	}
	//新しい総スペースサイズを保存。
	TSpaceManage->TotalSpace = TotalSpace;
}
//-----------------------------------------------------------------------------
//総スペースサイズを取得する。
//[in]
//	TSpaceManage		スペース管理情報。
//[out]
//	戻り値			総スペースサイズ。
int ToolSpaceManage_GetTotalSpace(SToolSpaceManage* TSpaceManage) {
	return TSpaceManage->TotalSpace;
}
//-----------------------------------------------------------------------------
//次のスペース情報に割り当てる開始位置を取得する。
//[in]
//	TSpaceManage		スペース管理情報。
//[out]
//	戻り値			スペースの開始位置。
int ToolSpaceManage_GetNextSpace(SToolSpaceManage* TSpaceManage) {
	return TSpaceManage->NextSpace;
}
