///////////////////////////////
// ECCSkelton
// CTREEVIEWクラス定義ファイル
// Copyright (c) August, 2022
//        By Ysama
///////////////////////////////

class CTREEVIEW : public CCTRL
{
public:
	HIMAGELIST m_hIList;				//ツリービュー用イメージリスト
	int m_imgw;							//イメージリスト用イメージの幅
	int m_imgh;							//イメージリスト用イメージの高さ
	int m_imgnum;						//イメージリスト用イメージの最大数
	int m_ext;							//イメージリスト用イメージの拡張数
	TVITEMW m_tvItem;					//アイテム情報構造体
	TVINSERTSTRUCTW m_tvInst;			//アイテム追加構造体

public:
	CTREEVIEW();						//コンストラクター（１）
	CTREEVIEW(int, int, int, UINT, int);		//コンストラクター（２）
	~CTREEVIEW();						//デストラクター
	bool Create(HWND, HINSTANCE, HMENU, int, 
				int, int, int);			//CTREEVIEWコントロール作成関数
	void Move(int, int, int, int);		//TreeViewコントロールの移動
	int AddBitmap(LPCTSTR, HINSTANCE,
					COLORREF);			//イメージリストへのビットマップ登録
	UINT GetCount();					//アイテム数を取得
	HTREEITEM GetRoot();				//ルートを取得する
	HTREEITEM GetSelection();			//現在選択されているアイテムを取得
	HTREEITEM GetParent(HTREEITEM);		//指定されたアイテムの親を取得
	HTREEITEM GetNext(HTREEITEM);		//指定されたアイテムの次の兄弟を取得
	HTREEITEM GetChild(HTREEITEM);		//指定されたアイテムの最初の子を取得
	LPTV_ITEM GetItem(HTREEITEM, WCHAR*, int);	//アイテム情報の取得
	HTREEITEM GetNextItem(HTREEITEM, UINT);	//UINTで指定した関係のアイテムを取得
	HTREEITEM FindItem(HTREEITEM, WCHAR*);	//HTREEITEM以下でWCHAR*で指定した文字列のアイテムを取得
	bool SelectItem(HTREEITEM);			//HTREEITEMで指定したアイテムを選択
	HTREEITEM InsertItem(WCHAR*, HTREEITEM,
				HTREEITEM, int, int);	//アイテム追加
	bool SetItem(HTREEITEM);			//m_tvItemのデータを予めセットして実行する
	bool DeleteAllItems();				//全てのアイテムを削除
	bool DeleteItem(HTREEITEM);			//指定したアイテムを削除
	bool Expand(HTREEITEM, UINT);		//アイテムを展開する
	bool SortChildren(HTREEITEM);		//子供達をソートする
};

//コンストラクター（１）
CTREEVIEW::CTREEVIEW() {

	m_hWnd			= 0;
	m_dwExStyle		= WS_EX_CLIENTEDGE;
	m_lpClassName	= L"SYSTREEVIEW32";
	m_dwStyle		= WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS;
	m_hIList = ImageList_Create(m_imgw = 0, m_imgh = 0, ILC_COLOR4 | ILC_MASK, m_imgnum = 0, m_ext = 0);
}

//コンストラクター（２）
CTREEVIEW::CTREEVIEW(int imgw, int imgh, int imgnum, UINT col, int ext) {

	m_hWnd			= 0;
	m_dwExStyle		= WS_EX_CLIENTEDGE;
	m_lpClassName	= L"SYSTREEVIEW32";
	m_dwStyle		= WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS;
	m_hIList = ImageList_Create(m_imgw = imgw, m_imgh = imgh, col, m_imgnum = imgnum, m_ext = ext);
}

//デストラクター
CTREEVIEW::~CTREEVIEW() {

	//すべてのツリービューアイテムを削除
	TreeView_DeleteAllItems(m_hWnd);
	//ツリービューで作成したイメージリストを廃棄する
	ImageList_Destroy(m_hIList);
}

//CTREEVIEWコントロール作成関数
bool CTREEVIEW::Create(HWND hWnd, HINSTANCE hInstance, HMENU ID,
				int x = 0, int y = 0, int w = 0, int h = 0) {

	m_hInstance = hInstance;
	bool res = CCTRL::Create(L"", m_dwStyle, m_dwExStyle, hWnd, ID, x, y, w, h);
	//ツリービューにイメージコントロールをセット
	TreeView_SetImageList(m_hWnd, m_hIList, TVSIL_NORMAL);
	return res;
}

//CTREEVIEWコントロールの移動
void CTREEVIEW::Move(int x, int y, int w, int h) {

	MoveWindow(m_hWnd, x, y, w, h, TRUE);
}

//イメージリストへのビットマップ登録
int CTREEVIEW::AddBitmap(LPCTSTR ID, HINSTANCE hInstance,
							COLORREF cMask = RGB(0, 0, 0)) {

	HBITMAP hBmp = LoadBitmap(hInstance, ID);
	int ret = ImageList_AddMasked(m_hIList, hBmp, cMask);
	DeleteObject(hBmp);
	return ret;			//-1は失敗
}

//アイテム数を取得
UINT CTREEVIEW::GetCount() {

	return TreeView_GetCount(m_hWnd);
}

//ルートを取得する
HTREEITEM CTREEVIEW::GetRoot() {

	return TreeView_GetRoot(m_hWnd);
}

//現在選択されているアイテムを取得
HTREEITEM CTREEVIEW::GetSelection() {

	return TreeView_GetSelection(m_hWnd);
}

//指定されたアイテムの親を取得
HTREEITEM CTREEVIEW::GetParent(HTREEITEM hitem) {

	return TreeView_GetParent(m_hWnd, hitem);
}

//指定されたアイテムの次の兄弟を取得
HTREEITEM CTREEVIEW::GetNext(HTREEITEM hitem) {

	return TreeView_GetNextSibling(m_hWnd, hitem);
}

//指定されたアイテムの最初の子を取得
HTREEITEM CTREEVIEW::GetChild(HTREEITEM hitem) {

	return TreeView_GetChild(m_hWnd, hitem);
}

//アイテム情報の取得
LPTV_ITEM CTREEVIEW::GetItem(HTREEITEM hitem, WCHAR* Buff = 0, int size = 0) {

	m_tvItem.hItem = hitem;
	if(!Buff) {
		m_tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM |
						TVIF_SELECTEDIMAGE | TVIF_STATE;
	}
	else {
		m_tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM |
						TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_TEXT;
		m_tvItem.cchTextMax = size;
		m_tvItem.pszText = Buff;
	}
	TreeView_GetItem(m_hWnd, &m_tvItem);
	return &m_tvItem;
}

//UINTで指定した関係のアイテムを取得
HTREEITEM CTREEVIEW::GetNextItem(HTREEITEM hitem, UINT flag = TVGN_NEXT) {

	return TreeView_GetNextItem(m_hWnd, hitem, flag);
}

//WCHAR*で指定した文字列のアイテムを取得
HTREEITEM CTREEVIEW::FindItem(HTREEITEM hitem, WCHAR* text) {

	HTREEITEM hSelected = hitem, hFound;
	TVITEMW tvitem;					//TV_ITEM構造体
	WCHAR Buff[MAX_PATH];			//文字列長はMAX_PATH限度
	while(hSelected) {				//最後まで見つからなければhSelectedは0になる
		tvitem.hItem = hSelected;
		tvitem.mask = TVIF_TEXT;
		tvitem.pszText = Buff;
		tvitem.cchTextMax = MAX_PATH;
		TreeView_GetItem(m_hWnd, &tvitem);
		if(!lstrcmpW(Buff, text)) {	//取得した文字列が同じ場合
			return hSelected;
		}
		else {						//同じでない場合
			//子がいれば再起呼出でサーチ、見つかれば終了
			if(tvitem.cChildren) {
				if((hFound = FindItem(GetChild(hSelected), text)))
					return hFound;
			}
			//矢張り見つからなければ次を探す
			hSelected = GetNext(hSelected);
		}
	}
	return NULL;					//全てのSiblingに無ければNULLを返す
}

//HTREEITEMで指定したアイテムを選択
bool CTREEVIEW::SelectItem(HTREEITEM hitem) {

	return TreeView_SelectItem(m_hWnd, hitem);
}

//アイテム追加
HTREEITEM CTREEVIEW::InsertItem(WCHAR* Title,
								HTREEITEM InsAfter = TVI_LAST,
								HTREEITEM Parent = TVI_ROOT,
								int Image = -1,
								int SelImage = -1) {

	ZeroMemory(&m_tvInst, sizeof(TV_INSERTSTRUCT));
	m_tvInst.hInsertAfter = InsAfter;
	m_tvInst.hParent = Parent;
	m_tvInst.item.pszText = Title;
	if(Image == -1) {
		m_tvInst.item.mask = TVIF_TEXT;
	}
	else {
		m_tvInst.item.mask = TVIF_TEXT | TVIF_IMAGE;
		m_tvInst.item.iImage = Image;
		if(SelImage != -1) {
			m_tvInst.item.mask |= TVIF_SELECTEDIMAGE;
			m_tvInst.item.iSelectedImage = SelImage;
		}
	}
	return TreeView_InsertItem(m_hWnd, &m_tvInst);
}

//m_tvItemのデータを予めセットして実行する
bool CTREEVIEW::SetItem(HTREEITEM hitem) {

	m_tvItem.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE | TVIF_PARAM |
					TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_TEXT;
	m_tvItem.hItem = hitem;
	return TreeView_SetItem(m_hWnd, &m_tvItem);
}

//全てのアイテムを削除
bool CTREEVIEW::DeleteAllItems() {

	return TreeView_DeleteAllItems(m_hWnd);
}

//指定したアイテムを削除
bool CTREEVIEW::DeleteItem(HTREEITEM hitem) {

	return TreeView_DeleteItem(m_hWnd, hitem);
}

//アイテムを展開する
bool CTREEVIEW::Expand(HTREEITEM hitem, UINT flag = TVE_TOGGLE) {

	return TreeView_Expand(m_hWnd, hitem, flag);
}

//子供達をソートする
bool CTREEVIEW::SortChildren(HTREEITEM hitem) {

	return TreeView_SortChildren(m_hWnd, hitem, 0);
}
