/*-----------------------------------------------------------------------------
[名称]	ToolBarManager.cpp
[概要]	ツールバー管理クラスの実装
[備考]	なし
[履歴]	2003-02-26	NC		コメント付加(moralog)
-----------------------------------------------------------------------------*/


//-----------------------------------------------------------------------------
// インクルード
//-----------------------------------------------------------------------------
#include "stdafx.h"
#define	APSTUDIO_INVOKED	// リソースIDの設定をちょっと覗き見たい
#include "resource.h"
#include "shitarabian.h"
#include "ToolBarManager.h"
#include "MainFrm.h."
#include "ExeCommon.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


/*-----------------------------------------------------------------------------
[名称]	唯一インスタンスの取得
[機能]	唯一インスタンスの取得。
[戻値]	CToolBarManager*	唯一インスタンス [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CToolBarManager* CToolBarManager::GetInstance()
{
	static	CToolBarManager	insToolBarManager;
	return( &insToolBarManager );
}

/*-----------------------------------------------------------------------------
[名称]	コンストラクタ
[機能]	インスタンスの生成。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CToolBarManager::CToolBarManager()
{

}


/*-----------------------------------------------------------------------------
[名称]	デストラクタ
[機能]	インスタンスの破棄。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CToolBarManager::~CToolBarManager()
{
	int	idxItem;
	for( idxItem=0 ; idxItem<m_apToolBarz.GetSize() ; idxItem++ )
	{
		delete m_apToolBarz[ idxItem ];
	}

	for( idxItem=0 ; idxItem<m_apDllComboBoxz.GetSize() ; idxItem++ )
	{
		CComboBox*	pCombo = (CComboBox*)m_apDllComboBoxz[ idxItem ];
		delete pCombo;
	}

	m_apToolBarz.RemoveAll();
	m_aINSTANCEz.RemoveAll();
	m_apDllComboBoxz.RemoveAll();
}


/*-----------------------------------------------------------------------------
[名称]	ツールバーの追加
[機能]	ツールバーを追加する。
[戻値]	BOOL	処理結果 [-] (TRUE:成功、FALSE:失敗)
[備考]	リソースIDはDLLのもの。
		この関数をコールするとき、かならずリソースは
		DLLのリソースをさしている必要がある。
		（要するにプラグインから呼ばれるための関数ということ）
		キーワード→::AfxGetResourceHandle()
-----------------------------------------------------------------------------*/
BOOL	CToolBarManager::EntryToolBar(
	int				idResource		// リソースID [DLL内の] (-) :-
)
{
	// DLLについて、ツールバーが未登録のときのみ追加
	int	idxToolBar = InstanceToIndex( ::AfxGetResourceHandle() );
	if( idxToolBar == -1 )
	{
		// メインフレーム取得
		CMainFrame*	pWnd;
		{
			CWinApp*		pApp = AfxGetApp();
			pWnd = (CMainFrame*)(pApp->GetMainWnd());
		}

		// ツールバー構築
		CToolBar*	pToolBar = new CToolBar;
		{
			if (!pToolBar->CreateEx(pWnd, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
				| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
				!pToolBar->LoadToolBar(idResource))
			{
				return( FALSE );      // 作成に失敗
			}
			pToolBar->EnableDocking(CBRS_ALIGN_ANY);
			pWnd->DockControlBar(pToolBar);

			// ツールバーアイコンのフルカラー化
			{
				// ツールバーに２５６色のイメージ
				// http://www.hcn.zaq.ne.jp/no-ji/reseach/991111.htm

				CImageList* pImgList = pToolBar->GetToolBarCtrl().GetImageList();

				IMAGEINFO	tInfo;
				pImgList->GetImageInfo( 0, &tInfo );
				int nBtnCnt = pToolBar->GetToolBarCtrl().GetButtonCount();	//ボタンの数
				int iBtnWidth = tInfo.rcImage.right - tInfo.rcImage.left;	// 画像幅
				int iBtnHeight = tInfo.rcImage.bottom - tInfo.rcImage.top;	// 画像高さ

				//ツールバーのイメージリストを初期化
				pImgList->DeleteImageList();
				pImgList->Create( iBtnWidth, iBtnHeight, ILC_COLOR24 | ILC_MASK, nBtnCnt, nBtnCnt );
				pToolBar->GetToolBarCtrl().SetImageList(pImgList);

				//CToolBarCtrlからビットマップを追加
				pToolBar->GetToolBarCtrl().AddBitmap( nBtnCnt, idResource );
			}

			// ツールバー位置を行儀よくそろえる
			((CMainFrame*)pWnd)->DockControlBarLeftOf( pToolBar );

			// ボタンにコマンドIDを割り当てる
			CToolBarCtrl&	ToolBarCtrl = pToolBar->GetToolBarCtrl();
			int	idxButton;
			for( idxButton=0 ; idxButton<ToolBarCtrl.GetButtonCount() ; idxButton++ )
			{
				// コマンドIDを割り振る
				int		idNextCommand = ::UniqueCommandID();
				ToolBarCtrl.SetCmdID( idxButton, idNextCommand );
				ToolBarCtrl.EnableButton( idNextCommand, TRUE );

				TRACE("CToolBarManager::EntryToolBar- ToolBarCtrl.CommandToIndex(idNextCommand) ) = %d\n",ToolBarCtrl.CommandToIndex(idNextCommand) );
			}
		}
		m_apToolBarz.Add( pToolBar );
		m_aINSTANCEz.Add( ::AfxGetResourceHandle() );
	}

	return( TRUE );
}


/*-----------------------------------------------------------------------------
[名称]	コンボボックスの作成
[機能]	ツールバー上のボタンをコンボボックスに変身させる。
[戻値]	CComboBox*		コンボボックス [-] (-)
[備考]	この関数をコールするときにさしているリソースのDLLツールバーが対象。
		（要するにプラグインから呼ばれるための関数ということ）
-----------------------------------------------------------------------------*/
CComboBox* CToolBarManager::SpawnComboBox(
	int		idxButton,		// ボタン番号 [-] (-) :-
	int		iWidth,			// コンボボックスの大きさ [pixel] (-) :-
	BOOL	bEdit			// 入力可能有無 [-] (TRUE:入力可、FALSE:入力不可) :-
)
{
	// ツールバーを探す
	CToolBar*	pBar = NULL;
	int	idxToolBar = InstanceToIndex( ::AfxGetResourceHandle() );
	if ( idxToolBar >= 0 )
	{
		pBar = m_apToolBarz[idxToolBar];

		// ツールバーの、該当するボタンをコンボボックスに変更
		// セパレータにする
		pBar->SetButtonInfo(
			idxButton,
			IDC_COMBO_SUBSTRING,
			TBBS_SEPARATOR,
			iWidth
		);

		// セパレータの上にコンボボックスを貼り付ける
		CRect rect;
		pBar->GetItemRect( idxButton, &rect );
		rect.top = 3; //適当に位置を計算します
		rect.bottom = rect.top + 200;
		int		idCommand = GetCommandIDFromButtonIndex( ::AfxGetResourceHandle(), idxButton );
		{
			int		iFlag = CBS_AUTOHSCROLL | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL;
			if ( bEdit )
			{
				iFlag |= CBS_DROPDOWN;
			}
			else
			{
				iFlag |= CBS_DROPDOWNLIST;
			}

			CManagedCombo*	pCombo = new CManagedCombo;
			if ( pCombo->Create(
					iFlag,
					rect,
					pBar,
					idCommand
				)
			)
			{
				pCombo->SetFont( CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)) );

				// ManagedComboのお約束（通知先設定）
				pCombo->m_pMainFrame = (CMainFrame*)::AfxGetApp();

				// アレイに格納
				m_apDllComboBoxz.Add( pCombo );
				return( pCombo );
			}
			delete pCombo;
		}
	}
	return( NULL );
}


/*-----------------------------------------------------------------------------
[名称]	ツールバーの表示制御
[機能]	ツールバーの表示非表示制御。
[戻値]	BOOL	処理結果 [-] (TRUE:成功、FALSE:失敗)
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL	CToolBarManager::ShowToolBar(
	BOOL			bShow	// I  :表示有無 [-] (TRUE:表示、FALSE:非表示)
)
{
	int	idxToolBar = InstanceToIndex( ::AfxGetResourceHandle() );
	if ( idxToolBar >= 0 )
	{
		CMainFrame*	pWnd;
		{
			CWinApp*		pApp = ::AfxGetApp();
			pWnd = (CMainFrame*)(pApp->GetMainWnd());
		}
		pWnd->ShowControlBar(
			m_apToolBarz[idxToolBar],
			bShow,
			0
		);
	}
	return( TRUE );
}


/*-----------------------------------------------------------------------------
[名称]	DLL→ツールバー番号
[機能]	ツールバー番号の取得。
[戻値]	int		ツールバー番号 [-] (0〜)
[備考]	なし
-----------------------------------------------------------------------------*/
int	CToolBarManager::InstanceToIndex(
	HINSTANCE	hDll		// I  :DLLハンドル [-] (-) :-
)
{
	int	idxToolBar;
	for( idxToolBar=0 ; idxToolBar<m_apToolBarz.GetSize() ; idxToolBar++ )
	{
		if( m_aINSTANCEz[idxToolBar] == hDll )
		{
			return( idxToolBar );
		}
	}
	return( -1 );
}


/*-----------------------------------------------------------------------------
[名称]	コマンドID→DLLハンドル、ボタン番号
[機能]	DLLハンドルと、そのツールバーのボタン番号の取得。
[戻値]	HINSTANCE	DLLハンドル [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
HINSTANCE	CToolBarManager::GetDLLHandleFromButton(
	int		idCommand,			// I  :コマンドID [-] (-) :-
	int*	pidxButton			//   O:ボタン番号 [-] (-) :-
)
{
	int	idxToolBar;
	for( idxToolBar=0 ; idxToolBar<m_apToolBarz.GetSize() ; idxToolBar++ )
	{
		CToolBarCtrl&	ToolBarCtrl = m_apToolBarz[idxToolBar]->GetToolBarCtrl();
		int	idxButton;
		for( idxButton=0 ; idxButton<ToolBarCtrl.GetButtonCount() ; idxButton++ )
		{
			TBBUTTON	tButton;
			ToolBarCtrl.GetButton(
				idxButton,
				&tButton
			);

			if( tButton.idCommand == idCommand )
			{
				*pidxButton = idxButton;
				return( m_aINSTANCEz[idxToolBar] );
			}
		}
	}
	return( NULL );
}


/*-----------------------------------------------------------------------------
[名称]	DLLハンドル、ボタン番号→コマンドID
[機能]	コマンドIDの取得。
[戻値]	int		コマンドID [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
int CToolBarManager::GetCommandIDFromButtonIndex(
	HINSTANCE	hDll,			// I  :DLLハンドル [-] (-) :-
	int			idxButton		// I  :ボタン番号 [-] (-) :-
)
{
	int	idxToolBar = InstanceToIndex( hDll );
	if( idxToolBar < m_apToolBarz.GetSize() )
	{
		CToolBarCtrl&	ToolBarCtrl = m_apToolBarz[idxToolBar]->GetToolBarCtrl();
		TBBUTTON	tButton;
		tButton.idCommand = 0;
		ToolBarCtrl.GetButton(
			idxButton,
			&tButton
		);
		return( tButton.idCommand );
	}
	return( 0 );
}
