//********************************************************************************
CBCGPBaseRibbonElement* CBCGPRibbonBackstageViewPanel::MouseButtonDown (CPoint point)
{
	CBCGPBaseRibbonElement* pHit = CBCGPRibbonMainPanel::MouseButtonDown (point);
	if (pHit == NULL || pHit->IsDisabled())
	{
		return NULL;
	}

	if (!m_rectPageTransition.IsRectEmpty())
	{
		StopPageTransition();
		OnPageTransitionFinished();

		if (pHit->GetRect().PtInRect(point))
		{
			SelectView(pHit);
			return pHit;
		}

		return NULL;
	}

	m_bSelectedByMouseClick = TRUE;
	SelectView(pHit);

	return pHit;
}
//*******************************************************************************
HRESULT CBCGPRibbonTabsGroup::accDoDefaultAction(VARIANT varChild)
{
	if (varChild.vt != VT_I4)
	{
		return E_INVALIDARG;
	}

	if (varChild.lVal != CHILDID_SELF)
	{
		int nIndex = (int)varChild.lVal - 1;
		if (nIndex < 0 || nIndex >= m_arButtons.GetSize())
		{
			return E_INVALIDARG;
		}

		CBCGPBaseRibbonElement* pElem = m_arButtons[nIndex];
		if (pElem != NULL)
		{
			ASSERT_VALID (pElem);

			pElem->OnAccDefaultAction();
			return S_OK;
		}
	}

	return S_FALSE;
}
//********************************************************************************
CSize CBCGPRibbonButtonsGroup::GetRegularSize (CDC* pDC)
{
	ASSERT_VALID (this);

	const BOOL bIsOnStatusBar = IsStatusBarMode();

	CSize size (0, 0);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->SetInitialMode (TRUE);
		pButton->OnCalcTextSize (pDC);

		CSize sizeButton = pButton->GetSize (pDC);
		
		size.cx += sizeButton.cx;
		size.cy = max (size.cy, sizeButton.cy);
	}

	if (bIsOnStatusBar)
	{
		size.cx += 2;
	}

	if (!IsQAT() && !bIsOnStatusBar && m_pParentMenu == NULL)
	{
		size.cx += CBCGPVisualManager::GetInstance ()->GetRibbonButtonsGroupHorzMargin() * 2;
	}

	return size;
}
//**********************************************************************
void CBCGPRibbonCustomizeQATPage::OnAdd() 
{
	CBCGPBaseRibbonElement* pCmd = m_wndCommandsList.GetSelected ();
	if (pCmd == NULL)
	{
		return;
	}

	ASSERT_VALID (pCmd);

	if (pCmd->IsSeparator () && m_wndQATList.GetCount () == 0)
	{
		// Don't add separator to the empty QAT
		MessageBeep ((UINT)-1);
		return;
	}
	
	if (!m_wndQATList.AddCommand (pCmd, TRUE, FALSE))
	{
		return;
	}

	int nSel = m_wndCommandsList.GetCurSel ();
	if (nSel < m_wndCommandsList.GetCount () - 1)
	{
		m_wndCommandsList.SetCurSel (nSel + 1);
	}

	OnSelchangeQATCommands();
	OnSelchangeCommandsList();
}
void CBCGPRibbonConstructor::ConstructCategoryBackstage (CBCGPRibbonBar& bar, const CBCGPRibbonInfo::XCategoryBackstage& info) const
{
	CBCGPRibbonBackstageViewPanel* pPanel = CreateCategoryBackstage (bar, info);
	ASSERT_VALID (pPanel);

	CBCGPRibbonCategory* pCategory = bar.GetBackstageCategory ();
	ASSERT_VALID (pCategory);

	const_cast<CBCGPToolBarImages&>(info.m_SmallImages.m_Image).CopyTo (pCategory->GetSmallImages ());

	int i = 0;
	for (i = 0; i < info.m_arElements.GetSize (); i++)
	{
		if (info.m_arElements[i]->GetElementName ().Compare (CBCGPRibbonInfo::s_szButton_Command) == 0)
		{
			CBCGPBaseRibbonElement* pElement = 
				CreateElement (*(const CBCGPRibbonInfo::XElement*)info.m_arElements[i]);

			if (pElement != NULL)
			{
				ASSERT_VALID (pElement);

				pElement->SetBackstageViewMode ();
				pPanel->CBCGPRibbonMainPanel::Add (pElement);
			}
		}
	}
}
	virtual void OnDraw (CDC* pDC)
	{
		ASSERT_VALID (pDC);

		CBCGPBaseRibbonElement* pElement = (CBCGPBaseRibbonElement*) m_dwData;
		ASSERT_VALID (pElement);

		CBCGPToolbarMenuButton dummy;

		dummy.m_strText = m_strText;

		CString strValue = pElement->GetText ();

		if (strValue.GetLength () > nMaxValueLen)
		{
			strValue = strValue.Left (nMaxValueLen - 1);
		}

		if (!strValue.IsEmpty ())
		{
			dummy.m_strText += _T('\t');
			dummy.m_strText += strValue;
		}

		dummy.m_bMenuMode = TRUE;
		dummy.m_pWndParent = GetParentWnd ();

		if (pElement->IsVisible ())
		{
			dummy.m_nStyle |= TBBS_CHECKED;
		}

		dummy.OnDraw (pDC, m_rect, NULL, TRUE, FALSE, m_bIsHighlighted);
	}
//*****************************************************************************
void CBCGPRibbonButtonsGroup::SetOriginal (CBCGPBaseRibbonElement* pOriginal)
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::SetOriginal (pOriginal);

	CBCGPRibbonButtonsGroup* pOriginalGroup =
		DYNAMIC_DOWNCAST (CBCGPRibbonButtonsGroup, pOriginal);

	if (pOriginalGroup == NULL)
	{
		return;
	}

	ASSERT_VALID (pOriginalGroup);

	if (pOriginalGroup->m_arButtons.GetSize () != m_arButtons.GetSize ())
	{
		ASSERT (FALSE);
		return;
	}

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->SetOriginal (pOriginalGroup->m_arButtons [i]);
	}
}
//*****************************************************************************
void CBCGPRibbonButtonsGroup::CopyFrom (const CBCGPBaseRibbonElement& s)
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::CopyFrom (s);

	CBCGPRibbonButtonsGroup& src = (CBCGPRibbonButtonsGroup&) s;

	RemoveAll ();

	for (int i = 0; i < src.m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pSrcElem = src.m_arButtons [i];
		ASSERT_VALID (pSrcElem);

		CBCGPBaseRibbonElement* pElem =
			(CBCGPBaseRibbonElement*) pSrcElem->GetRuntimeClass ()->CreateObject ();
		ASSERT_VALID (pElem);

		pElem->CopyFrom (*pSrcElem);

		m_arButtons.Add (pElem);
	}

	src.m_Images.CopyTo (m_Images);
	src.m_HotImages.CopyTo (m_HotImages);
	src.m_DisabledImages.CopyTo (m_DisabledImages);
}
//******************************************************************************
BOOL CBCGPRibbonButtonsGroup::ReplaceByID (UINT uiCmdID, CBCGPBaseRibbonElement* pElem)
{
	ASSERT_VALID (this);
	ASSERT_VALID (pElem);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		if (pButton->GetID () == uiCmdID)
		{
			pElem->CopyFrom (*pButton);
			m_arButtons [i] = pElem;

			delete pButton;
			return TRUE;
		}

		if (pButton->ReplaceByID (uiCmdID, pElem))
		{
			return TRUE;
		}
	}
	
	return FALSE;
}
//********************************************************************************
void CBCGPRibbonButtonsGroup::OnDraw (CDC* pDC)
{
	ASSERT_VALID (this);
	ASSERT_VALID (pDC);

	if (m_rect.IsRectEmpty ())
	{
		return;
	}

	//-----------------------
	// Fill group background:
	//-----------------------
	COLORREF clrText = 
		CBCGPVisualManager::GetInstance ()->OnDrawRibbonButtonsGroup (
		pDC, this, m_rect);

	COLORREF clrTextOld = (COLORREF)-1;
	if (clrText != (COLORREF)-1)
	{
		clrTextOld = pDC->SetTextColor (clrText);
	}

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		if (pButton->m_rect.IsRectEmpty ())
		{
			continue;
		}

		CString strText = pButton->m_strText;
		BOOL bIsDisabled = pButton->IsDisabled();

		if ((IsQAT() || m_bIsRibbonTabElements) && pButton->m_pRibbonBar != NULL && pButton->m_pRibbonBar->IsBackstageViewActive())
		{
			pButton->m_bIsDisabled = TRUE;
		}

		if (pButton->GetImageSize (CBCGPBaseRibbonElement::RibbonImageSmall) 
			!= CSize (0, 0))
		{
			pButton->m_strText.Empty ();
		}

		pButton->OnDraw (pDC);

		pButton->m_strText = strText;
		pButton->m_bIsDisabled = bIsDisabled;
	}

	if (clrTextOld != (COLORREF)-1)
	{
		pDC->SetTextColor (clrTextOld);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::CleanUpSizes ()
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->CleanUpSizes ();
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::GetItemIDsList (CList<UINT,UINT>& lstItems) const
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->GetItemIDsList (lstItems);
	}
}
//********************************************************************************
void CBCGPRibbonButtonsGroup::OnShow (BOOL bShow)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->OnShow (bShow);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::AddToKeyList (CArray<CBCGPRibbonKeyTip*,CBCGPRibbonKeyTip*>& arElems)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->AddToKeyList (arElems);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::GetElementsByName (LPCTSTR lpszName, 
		CArray<CBCGPBaseRibbonElement*, CBCGPBaseRibbonElement*>& arButtons, DWORD dwFlags)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->GetElementsByName (lpszName, arButtons, dwFlags);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::GetElementsByID (UINT uiCmdID, 
	CArray<CBCGPBaseRibbonElement*, CBCGPBaseRibbonElement*>& arElements)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->GetElementsByID (uiCmdID, arElements);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::GetVisibleElements (
	CArray<CBCGPBaseRibbonElement*, CBCGPBaseRibbonElement*>& arElements)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->GetVisibleElements (arElements);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::SetCustom()
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::SetCustom();

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->SetCustom();
	}
}
//*****************************************************************************
void CBCGPRibbonButtonsGroup::SetParentMenu (CBCGPRibbonPanelMenuBar* pMenuBar)
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::SetParentMenu (pMenuBar);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->SetParentMenu (pMenuBar);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::OnChangeVisualManager()
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::OnChangeVisualManager();

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->OnChangeVisualManager();
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::OnRTLChanged(BOOL bIsRTL)
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::OnRTLChanged (bIsRTL);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->OnRTLChanged (bIsRTL);
	}
}
//*************************************************************************************
void CBCGPRibbonButtonsGroup::SetParentCategory (CBCGPRibbonCategory* pCategory)
{
	ASSERT_VALID (this);

	CBCGPBaseRibbonElement::SetParentCategory (pCategory);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->SetParentCategory (pCategory);
	}
}
//********************************************************************************
void CBCGPRibbonButtonsGroup::OnUpdateCmdUI (CBCGPRibbonCmdUI* pCmdUI,
											CFrameWnd* pTarget,
											BOOL bDisableIfNoHndler)
{
	ASSERT_VALID (this);

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pButton->OnUpdateCmdUI (pCmdUI, pTarget, bDisableIfNoHndler);
	}
}
void CBCGPRibbonConstructor::ConstructElement (CBCGPBaseRibbonElement& element, const CBCGPRibbonInfo::XElement& info) const
{
	if (info.GetElementName ().Compare (CBCGPRibbonInfo::s_szButton_Main) == 0 &&
		element.IsKindOf (RUNTIME_CLASS (CBCGPRibbonMainButton)))
	{
		ConstructBaseElement (element, info);

		const CBCGPRibbonInfo::XElementButtonMain& infoElement = 
			(const CBCGPRibbonInfo::XElementButtonMain&)info;

		CBCGPRibbonMainButton* pElement = (CBCGPRibbonMainButton*)&element;
		ASSERT_VALID (pElement);

		const_cast<CBCGPToolBarImages&>(infoElement.m_Image.m_Image).CopyTo (pElement->m_Image);
		const_cast<CBCGPToolBarImages&>(infoElement.m_ImageScenic.m_Image).CopyTo (pElement->m_ImageScenic);
	}
	else if (info.GetElementName ().Compare (CBCGPRibbonInfo::s_szButton_Launch) == 0 &&
			 element.IsKindOf (RUNTIME_CLASS (CBCGPRibbonLaunchButton)))
	{
		ConstructBaseElement (element, info);
	}
	else if (info.GetElementName ().Compare (CBCGPRibbonInfo::s_szGroup) == 0 &&
			 element.IsKindOf (RUNTIME_CLASS (CBCGPRibbonButtonsGroup)))
	{
		const CBCGPRibbonInfo::XElementGroup& infoElement = 
			(const CBCGPRibbonInfo::XElementGroup&)info;

		CBCGPRibbonButtonsGroup* pElement = (CBCGPRibbonButtonsGroup*)&element;
		ASSERT_VALID (pElement);

		const_cast<CBCGPToolBarImages&>(infoElement.m_Images.m_Image).CopyTo (pElement->m_Images);

		for (int i = 0; i < infoElement.m_arButtons.GetSize (); i++)
		{
			CBCGPBaseRibbonElement* pButton = CreateElement 
				(*(const CBCGPRibbonInfo::XElement*)infoElement.m_arButtons[i]);

			if (pButton != NULL)
			{
				ASSERT_VALID (pButton);
				pElement->AddButton (pButton);
			}
		}
	}
	else
	{
		ASSERT (FALSE);
	}
}
//*************************************************************************************
int CBCGPRibbonButtonsGroup::AddToListBox (CBCGPRibbonCommandsListBox* pWndListBox, BOOL bDeep)
{
	ASSERT_VALID (this);

	int nIndex = -1;

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		nIndex = pButton->AddToListBox (pWndListBox, bDeep);
	}

	return nIndex;
}
//*************************************************************************************
CBCGPGridRow* CBCGPRibbonButtonsGroup::AddToTree (CBCGPGridCtrl* pGrid, CBCGPGridRow* pParent)
{
	ASSERT_VALID (this);

	CBCGPGridRow* pRow = NULL;

	for (int i = 0; i < m_arButtons.GetSize (); i++)
	{
		CBCGPBaseRibbonElement* pButton = m_arButtons [i];
		ASSERT_VALID (pButton);

		pRow = pButton->AddToTree(pGrid, pParent);
	}

	return pRow;
}
//******************************************************************************
void CBCGPRibbonQuickStep::CopyFrom(const CBCGPBaseRibbonElement& src)
{
    ASSERT_VALID(this);

    CBCGPRibbonPaletteIcon::CopyFrom(src);
    m_bIsDisabled = src.IsDisabled();
}
//*****************************************************************************
void CBCGPRibbonQuickStepsButton::CopyFrom (const CBCGPBaseRibbonElement& s)
{
    ASSERT_VALID (this);

    CBCGPRibbonPaletteButton::CopyFrom (s);

    if (!s.IsKindOf (RUNTIME_CLASS (CBCGPRibbonQuickStepsButton)))
    {
        return;
    }

    CBCGPRibbonQuickStepsButton& src = (CBCGPRibbonQuickStepsButton&) s;

    RemoveAll ();

    for (int i = 0; i < src.m_arIcons.GetSize(); i++)
    {
        CBCGPRibbonQuickStep* pButton = new CBCGPRibbonQuickStep();

        pButton->CopyFrom(*src.m_arIcons[i]);
        pButton->m_pOwner = this;

        m_arIcons.Add(pButton);
    }
}
//******************************************************************************
int CBCGPRibbonCommandsListBox::GetCommandIndex (UINT uiID) const
{
	ASSERT_VALID (this);

	for (int i = 0; i < GetCount (); i++)
	{
		CBCGPBaseRibbonElement* pCommand = (CBCGPBaseRibbonElement*) GetItemData (i);
		ASSERT_VALID (pCommand);

		if (pCommand->GetID () == uiID)
		{
			return i;
		}
	}

	return -1;
}
//**********************************************************************
void CBCGPRibbonCustomizeQATPage::OnSelchangeCommandsList() 
{
	BOOL bEnableAddButton = TRUE;

	CBCGPBaseRibbonElement* pCmd = m_wndCommandsList.GetSelected ();
	if (pCmd == NULL)
	{
		bEnableAddButton = FALSE;
	}
	else
	{
		ASSERT_VALID (pCmd);
		bEnableAddButton = 
			pCmd->GetID () == 0 || m_wndQATList.GetCommandIndex (pCmd->GetID ()) < 0;
	}

	m_wndAdd.EnableWindow (bEnableAddButton);
}