void Toolbar::updateSeparator( unsigned int& index, ItemPtr item, TBBUTTONINFO& info )
{
	int width = item->exist( "width" )	?	atoi( (*item)[ "width" ].c_str() )	:
											6;
	if( ( info.fsStyle & BTNS_SEP ) == 0 //  not a separator
		|| info.lParam != 0 // a place-holder separator
		|| info.iImage != width ) // width, will be configurable in future
	{
		TBBUTTON button;
		memset(	&button, 0, sizeof(button) );
		button.iBitmap = width; // width of the separatar, could be configurable in future
		button.idCommand = 0;
		button.fsState = 0;
		button.fsStyle = BTNS_SEP;
		button.dwData = 0;
		button.iString = -1;

		sendMessage( TB_INSERTBUTTON, index, (LPARAM)&button );
	}
	TBBUTTONINFO buttonInfo = { sizeof( buttonInfo ), TBIF_BYINDEX | TBIF_STATE };
	buttonInfo.fsState = 0;
	if ( sendMessage( WM_CGUITOOLBAR_USE_WRAP, 0, 0 ) &&
		( info.fsState & TBSTATE_WRAP ) )
		buttonInfo.fsState |= TBSTATE_WRAP;

	if( forceChanged_ || info.fsState != buttonInfo.fsState )
		sendMessage( TB_SETBUTTONINFO, index, (LPARAM)&buttonInfo );
}
int Toolbar::getImageIndex( ItemPtr item )
{
	if( imageIndices_.find( item.getObject() ) == imageIndices_.end() )
	{
		COLORREF transparency = RGB( 192, 192, 192 );
		if( item->exist( "transparency" ) )
		{
			std::string color = (*item)[ "transparency" ];
			if( std::count( color.begin(), color.end(), ',' ) == 2 )
			{
				BYTE r = atoi( color.c_str() );
				BYTE g = atoi( color.c_str() + color.find( ',' ) + 1 );
				std::string::size_type next = color.find( ',' ) + 1;
				BYTE b = atoi( color.c_str() + color.find( ',', next ) + 1 );
				transparency = RGB( r, g, b );
			}
		}
		BitmapPtr bitmap = Manager::instance().bitmaps().get( (*item)["imageNormal"], transparency );
		result_ = ImageList_Add( normalImageList_, (*bitmap), NULL );
		if( item->exist( "imageHot" ) )
			ImageList_Add( hotImageList_,
				*Manager::instance().bitmaps().get( (*item)["imageHot"], transparency ), NULL );
		else
			ImageList_Add( hotImageList_,
				*Manager::instance().bitmaps().get( (*item)["imageNormal"], transparency, "HOVER" ), NULL );

		if( item->exist( "imageDisabled" ) )
			ImageList_Add( disabledImageList_,
				*Manager::instance().bitmaps().get( (*item)["imageDisabled"], transparency ), NULL );
		else
			ImageList_Add( disabledImageList_,
				*Manager::instance().bitmaps().get( (*item)["imageNormal"], transparency, "DISABLED" ), NULL );
		imageIndices_[ item.getObject() ] = result_;
	}
	return imageIndices_[ item.getObject() ];
}
void Toolbar::updateExpandedChoice( unsigned int& index, ItemPtr item, TBBUTTONINFO& info )
{
	struct PatchDisplayName
	{
		std::string operator()( std::string name )
		{
			std::string::iterator iter = name.begin();
			while( iter != name.end() )
			{
				if( *iter == '&' )
					name.erase( iter );
				else
					++iter;
			}
			return name;
		}
	}
	PatchDisplayName;
	HWND combobox = (HWND)info.lParam;
	if( ( info.fsStyle & BTNS_SEP ) == 0 || // not a place holder
		info.lParam == 0 ) // do not contain a combo box
	{
		int width = item->exist( "width" )	?	atoi( (*item)[ "width" ].c_str() )	:
												150;
		combobox = CreateWindow( "COMBOBOX", "",
			CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE,
			0, 0, width, 1,
			toolbar_, NULL, GetModuleHandle( NULL ), NULL );
		SendMessage( combobox, WM_SETFONT,
			SendMessage( toolbar_, WM_GETFONT, 0, 0 ),
			FALSE );
		TBBUTTON button;
		memset(	&button, 0, sizeof(button) );
		button.iBitmap = width; // width of the combobox, MUST be configurable in future
		button.idCommand = 0;
		button.fsState = 0;
		button.fsStyle = BTNS_SEP;
		button.dwData = (DWORD)combobox;
		button.iString = -1;

		sendMessage( TB_INSERTBUTTON, index, (LPARAM)&button );
	}
	{// set the position & size
		RECT rectButton, rectWin;
		sendMessage( TB_GETITEMRECT, index, (LPARAM)&rectButton );
		GetWindowRect( combobox, &rectWin );
		ScreenToClient( toolbar_, (POINT*)&rectWin );
		MoveWindow( combobox, rectButton.left, rectButton.top,
			rectButton.right - rectButton.left, ( rectButton.bottom - rectButton.top ) * 20, TRUE );
	}
	int comboIndex = 0;
	unsigned int subitemIndex = 0;
	while( comboIndex < SendMessage( combobox, CB_GETCOUNT, 0, 0 ) &&
		subitemIndex < item->num() )
	{
		ItemPtr subitem = (*item)[ subitemIndex ];
		char* buffer = (char*)_alloca( SendMessage( combobox, CB_GETLBTEXTLEN, comboIndex, 0 ) + 1 );
		SendMessage( combobox, CB_GETLBTEXT, comboIndex, (LPARAM)buffer );
		if( SendMessage( combobox, CB_GETITEMDATA, comboIndex, 0 ) != subitem->commandID() ||
			buffer != subitem->displayName() )
		{
			SendMessage( combobox, CB_INSERTSTRING, comboIndex,
				(LPARAM)PatchDisplayName( subitem->displayName() ).c_str() );
			SendMessage( combobox, CB_SETITEMDATA, comboIndex, subitem->commandID() );
		}
		if( subitem->update() && !SendMessage( combobox, CB_GETDROPPEDSTATE, 0, 0 ) )
			SendMessage( combobox, CB_SETCURSEL, comboIndex, 0 );
		++comboIndex;
		++subitemIndex;
	}
	while( comboIndex < SendMessage( combobox, CB_GETCOUNT, 0, 0 ) )
		SendMessage( combobox, CB_DELETESTRING, comboIndex, 0 );
	while( subitemIndex < item->num() )
	{
		ItemPtr subitem = (*item)[ subitemIndex ];
		SendMessage( combobox, CB_INSERTSTRING, comboIndex,
			(LPARAM)PatchDisplayName( subitem->displayName() ).c_str() );
		SendMessage( combobox, CB_SETITEMDATA, comboIndex, subitem->commandID() );
		if( subitem->update()  && !SendMessage( combobox, CB_GETDROPPEDSTATE, 0, 0 ) )
			SendMessage( combobox, CB_SETCURSEL, comboIndex, 0 );
		++comboIndex;
		++subitemIndex;
	}
	EnableWindow( combobox, item->update() && item->num() && isEnabled() );
}