//////////////////////////////////////////////////////////////////////////////////
// $Source: /cvsroot/cdx/cdx3.0/addons/CDXBitmapMenu/cdxmenubutton.cpp,v $
// $Author: hebertjo $
//
// $Log: cdxmenubutton.cpp,v $
// Revision 1.1.1.1  2000/04/22 16:51:05  hebertjo
// Initial checkin of v3.0 to SourceForge CVS.
//
// Revision 1.1.1.1  1999/05/04 23:59:24  bsimser
// Imported addons
//
// $Revision: 1.1.1.1 $
//////////////////////////////////////////////////////////////////////////////////

#include "CDX.h"
#include "cdxbitmap.h"

#define         MID_POINT(m,n)                  (m+n)/2
#define         DEFAULT_TOOLTIP_Y_OFFSET        -15
#define         DEFAULT_TOOLTIP_TIME            1000

UINT CDXMenuButton::m_DownButtonID=0;
void CDXMenuButton::ResetButton()
{
	CDXMenuButton::m_DownButtonID=0;
}


CDXMenuButton::CDXMenuButton()
{
	//	Initialize
	m_DrawState = BUTTON_FLAG;
	m_ButtonID = 0;
	m_pSubMenu = NULL;
	m_pFNMouseMove = CDXMenuButton::ButtonMenuMouseMove;
    m_pToolTipCtrl = NULL;

    m_pFNMouseEnter = m_pFNMouseLeave = NULL;
}


CDXMenuButton::~CDXMenuButton()
{
    if(m_pToolTipCtrl)
    {
        delete m_pToolTipCtrl;
    }
}


void CDXMenuButton::RegisterMouseEnter(MOUSECALLBACK pfnMouseEnter)
{
    m_pFNMouseEnter = pfnMouseEnter;
}


void CDXMenuButton::RegisterMouseLeave(MOUSECALLBACK pfnMouseLeave)
{
    m_pFNMouseLeave = pfnMouseLeave;
}


void CDXMenuButton::ButtonItem(CDXMenu* pSubMenu)
{
	// Set sub menu
	m_pSubMenu = pSubMenu;
}


void CDXMenuButton::SetButton(UINT buttonID, POINT pt)
{
    SetButtonID(buttonID);
    SetButtonPos(pt);
}


//
//	Note:	The button ID must be greater than 0.
//
//////////////////////////////////////////////////
void CDXMenuButton::SetButtonID(UINT buttonID)
{
    m_ButtonID = buttonID;
}


//
//	Purpose:	Get the point which is inside the parameter pRect
//
/////////////////////////////////////////////////////////////////
POINT CDXMenuButton::GetPtInButton(RECT* pRect)
{
    POINT pt;
    pt.x = MID_POINT(pRect->right, pRect->left);
    pt.y = MID_POINT(pRect->bottom, pRect->top);
    return pt;

}


//
//
//	Return:	<0 if sub menu doesn't need to be drawn, >=0 otherwise
//
/////////////////////////////////////////////////////////////
HRESULT CDXMenuButton::MouseMove(POINT pt, int newState)
{
	return (this->*m_pFNMouseMove)(pt, newState);
}


HRESULT CDXMenuButton::GetButtonState(int newState)
{
	// waiting for up button
	if (m_DownButtonID==m_ButtonID)
	{
		// if new button is flag, it implies the down button has been released.
		// if new button is up button, we got it.
		if ( (newState==BUTTON_UP) ||
			 (newState==BUTTON_FLAG) )
		{
			m_DownButtonID = 0;
			m_DrawState = BUTTON_UP;

			if (newState==BUTTON_UP)
			{
				CDXMenuButton::ResetButton();
                m_ButtonTimer.Kill();
				return m_ButtonID;
			}

		} else {
			m_DrawState = BUTTON_DOWN;
		}

	} else {

		// if we currently draw a up button and received a down button and 
		// no button held the down button
		if ( (m_DrawState==BUTTON_UP) &&
			 (newState==BUTTON_DOWN) &&
			 (!m_DownButtonID) )
		{
			m_DownButtonID = m_ButtonID;
			m_DrawState = BUTTON_DOWN;

		} else {
			m_DrawState = BUTTON_UP;
		}

	}
	return -1;
}


//
//	Purpose:	Handling the mouse move for the button.
//
////////////////////////////////////////////////////////////////////
HRESULT CDXMenuButton::ButtonMenuMouseMove(POINT pt, int newState)
{
	if (IsInButton(pt))
	{
		// Lock the time for tooptip
        if ( (m_ButtonTimer.LockTime()) &&
             (m_pFNMouseEnter) )
        {
            (*m_pFNMouseEnter)(pt, m_ButtonID);
        }

		if (m_pSubMenu)
		{
			// Check submenu next time
			m_pFNMouseMove = SubMenuMouseMove;
			m_DrawState = BUTTON_UP;
			return 0;

		} else {
			return GetButtonState(newState);
		}

	}

    if ( (m_ButtonTimer.Kill()) &&
         (m_pFNMouseLeave) )
    {
        (*m_pFNMouseLeave)(pt, m_ButtonID);
    }
	m_DrawState = BUTTON_FLAG;
	return -1;
}


//
//	Purpose:	Handling the mouse move for submenu of the button.
//
////////////////////////////////////////////////////////////////////
HRESULT CDXMenuButton::SubMenuMouseMove(POINT pt, int newState)
{
	// It is important to check the submenu button first.
	int retVal=m_pSubMenu->MouseMove(newState, &pt);
	if (IsInButton(pt))
	{
		return 0;
	}

	if (!m_pSubMenu->IsInMenu(pt))
	{
		if (retVal<0)
		{
			m_pFNMouseMove = ButtonMenuMouseMove;
			m_DrawState = BUTTON_FLAG;
			return -1;
		}
		return retVal;
	}

	return ( (retVal>0)? retVal:0 );
}


void CDXMenuButton::DrawToolTip(CDXSurface* lpDDS, RECT* pDestRect)
{
    if(!m_ButtonTimer.IsInTime(DEFAULT_TOOLTIP_TIME, 0) && m_pToolTipCtrl && m_pToolTipCtrl->IsEnabled())
    {
        //draw tooltip just above menu button
		m_pToolTipCtrl->Draw(lpDDS, pDestRect->left, pDestRect->top+DEFAULT_TOOLTIP_Y_OFFSET);
    }
}
