#if !defined(BRBUTTON_H) && !defined(__BEDRC__)
#define BRBUTTON_H
//========================================================================================
//
//     File:			BRButton.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	10/18/90
//
//     COPYRIGHT 1990-93 SYMANTEC CORPORATION. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS
//     RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF COPYRIGHT NOTICE IS
//     PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
//
//     THIS SOFTWARE CONTAINS PROPRIETARY AND CONFIDENTIAL INFORMATION OF SYMANTEC
//     CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
//     EXPRESS WRITTEN PERMISSION OF SYMANTEC CORPORATION.
//
//     RESTRICTED RIGHTS LEGEND
//     Use, duplication, or disclosure by the Government is subject to restrictions as set
//     forth in subparagraph (c)(l)(ii) of the Rights in Technical Data and Computer
//     Software clause at DFARS 252.227-7013. Symantec Corporation, 10201 Torre Avenue,
//     Cupertino, CA 95014.
//
//========================================================================================

#ifndef BRBUTTON_K
#include "BRButton.k"
#endif

#ifndef BRCONTRO_H
#include "BRContro.h"
#endif

#ifndef BRPULLDM_H
#include "BRPullDM.h"
#endif


//========================================================================================
// Forward class declarations
//========================================================================================

class BR_CBitmap;
class BR_CFramedBitmap;


//========================================================================================
//	STRUCT BR_SButtonResource
//========================================================================================

struct BR_SButtonResource : BR_SControlResource
{
    char  fText[128];
};


//========================================================================================
//	CLASS BR_CButton
//
// This is an abstract class that can be used in any pane or window. It handles all mouse
// tracking for you. When you click and release the mouse button on a BR_CButton, the
// button sends a DoCommand() message to its supervisor.
//========================================================================================

class BR_CButton : public BR_CControl
{
public:
	BR_Boolean DrawDisabled() const;
	BR_Boolean DrawFocus() const;
	BR_Boolean DrawSelected() const;

protected:
	BR_CButton(BR_CView* enclosure,
			   BR_CBureaucrat* supervisor,
			   BR_Distance width,
			   BR_Distance height,
			   BR_Coordinate x,
			   BR_Coordinate y,
			   ViewSizing horizontalSizing,
			   ViewSizing verticalSizing,
			   const BR_CColor &backgroundColor,
			   ViewId viewId,
			   ViewStyle viewStyle,
			   const BR_TString<BR_Char>& text);

	BR_CButton(BR_CView* enclosure,
			   BR_CBureaucrat* supervisor,
			   const BR_CModule& module,
			   BR_SResource& resource);

	void	InitButton(BR_CView 		*enclosure,
					   BR_CBureaucrat 	*supervisor,
					   ViewStyle 		viewStyle,
						ViewId			viewId,
						const BR_CCharString255 &text);

	virtual~ BR_CButton();

private:
	unsigned short fState;						// the current state of the button
	BR_SButtonResource* fResource;					// the button's resource information

#ifdef BR_BUILD_MAC
public:
	virtual void DoGoodClick(short partCode);
#endif

#ifdef BR_BUILD_WIN
public:
	long Dispatch(WORD wMessage,
				  WORD wParam,
				  long lParam,
				  BR_Boolean callDefaultProc = TRUE);	// ?INTERNAL?

	long DoDefaultProc(WORD wMessage,
					   WORD wParam,
					   long lParam);					// ?INTERNAL?
#endif

	BR_SETCLASSNAME(BR_CButton);
};

//----------------------------------------------------------------------------------------
// BR_CButton::DrawDisabled
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CButton::DrawDisabled() const
{
	return fState & ODS_DISABLED;
}

//----------------------------------------------------------------------------------------
// BR_CButton::DrawFocus
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CButton::DrawFocus() const
{
	return fState & ODS_FOCUS;
}

//----------------------------------------------------------------------------------------
// BR_CButton::DrawSelected
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CButton::DrawSelected() const
{
	return fState & ODS_SELECTED;
}


//========================================================================================
// STRUCT BR_SCheckedButtonResource
//========================================================================================

struct BR_SCheckedButtonResource : BR_SButtonResource
{
};


//========================================================================================
// CLASS BR_CCheckedButton
//
// An abstract class which must be subclassed in order to create an instance of a checked
// button. You can use a checked button in any pane or window.
//
// The BR_CCheckedButton class contains all the shared properties of the subclasses
// BR_CRadioButton and BR_CCheckBox. When you click and release the mouse button within a
// BR_CCheckedButton, the button sends a DoCommand() message to its supervisor.
//
// Three methods are provided: one for querying the state of the checked button--
// IsChecked() -- and two for toggling its state-- Check() and Uncheck(). Although
// BR_CCheckedButton implements only the methods listed here, you can use the methods it
// inherits from BR_CButton and BR_CControl to manipulate a checked button's title and location.
//========================================================================================

class BR_CCheckedButton : public BR_CButton
{
public:
	virtual BR_Boolean IsChecked() const;
	virtual void Check(BR_Boolean checked = TRUE);
	virtual void Uncheck();

protected:
	BR_CCheckedButton(BR_CView* enclosure,
					  BR_CBureaucrat* supervisor,
					  BR_Distance width,
					  BR_Distance height,
					  BR_Coordinate x,
					  BR_Coordinate y,
					  ViewSizing horizontalSizing,
					  ViewSizing verticalSizing,
					  ViewId viewId,
					  ViewStyle style,
					  const BR_TString<BR_Char>& text);

	BR_CCheckedButton(BR_CView* enclosure,
					  BR_CBureaucrat* supervisor,
					  const BR_CModule& module,
					  BR_SResource& resource);

	virtual~ BR_CCheckedButton();

#ifdef BR_BUILD_MAC
protected:
	virtual void DoGoodClick(short partCode);		// ?INTERNAL?
#endif

private:
	short fDummy;							// (SCpp bug#4)
	
	BR_SETCLASSNAME(BR_CCheckedButton);
};



//========================================================================================
// STRUCT BR_SPushButtonResource
//========================================================================================

struct BR_SPushButtonResource : BR_SButtonResource
{
    BR_ResourceId fBitmapResourceId;
};


//========================================================================================
// CLASS BR_CPushButton
//
// A Push button is a button that the user can select to carry out a specific action. The
// button normally contains text that indicates to the user what the button does. When the
// user clicks on a Push button, the application usually carries out the associated
// action. If a Push button is declared as the default Push button, associated keyboard
// events will select it, provided no other pushbutton has the focus.
//========================================================================================

class BR_CPushButton : public BR_CButton
{
public:
	BR_CPushButton(BR_CView* enclosure,
				   BR_CBureaucrat* supervisor,
				   BR_Distance width,
				   BR_Distance height,
				   BR_Coordinate x,
				   BR_Coordinate y,
				   ViewSizing horizontalSizing,
				   ViewSizing verticalSizing,
				   ViewId viewId,
				   const BR_TString<BR_Char>& text,
				   BR_Boolean isDefaultButton = FALSE);

	BR_CPushButton(BR_CView* enclosure,
				   BR_CBureaucrat* supervisor,
				   BR_Coordinate x,
				   BR_Coordinate y,
				   ViewSizing horizontalSizing,
				   ViewSizing verticalSizing,
				   ViewId viewId,
				   const BR_CModule& resourceModule,
				   BR_ResourceId resourceId,
				   BR_Boolean isDefaultButton = FALSE);

	BR_CPushButton(BR_CView* enclosure,
				   BR_CBureaucrat* supervisor,
				   const BR_CModule& module,
				   BR_SResource& resource);

	virtual~ BR_CPushButton();

	virtual void Draw(BR_CCanvas &canvas, const BR_CRectangle& area);
	void MakeDefault(BR_Boolean isDefaultButton);
	void SetDefaultButton(BR_Boolean isDefaultButton);
	BR_Boolean IsDefault() const;
	virtual void ReceiveFocus();
	virtual void LoseFocus(BR_CView *viewReceivingFocus);
	virtual void DrawButtonFocus(BR_CCanvas &canvas, const BR_CRectangle& size);

protected:
	BR_CFramedBitmap* GetBitmap() const;

private:
	BR_CFramedBitmap* fBitmap;
		// the bitmap that represents the Push button. Note that it is used to represent
        // all five visual states: active, selected, disabled, default and default pushed.
        // The first fifth is displayed when active, the second fifth when selected, the
        // middle when disabled, the fourth fifth when default and the rightmost one when
        // default pushed

	BR_Boolean fIsDefault:8;

	void ButtonDeactivate();
	virtual void AdjustSizeToBitmap();
	virtual void LoadBitmap(BR_CFramedBitmap*& bitmap,
							const BR_CModule& module,
							BR_ResourceId resourceId);

//----------------------------------------------------------------------------------------
// Macintosh
//----------------------------------------------------------------------------------------
#ifdef BR_BUILD_MAC
public:
	virtual void MacCreateDefaultButtonAdorner(BR_CView* adornerEnclosure);
	
#endif

	BR_SETCLASSNAME(BR_CPushButton);
};

//----------------------------------------------------------------------------------------
// BR_CPushButton::IsDefault
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CPushButton::IsDefault() const
{
	return fIsDefault;
}

//----------------------------------------------------------------------------------------
// BR_CPushButton::GetBitmap
//----------------------------------------------------------------------------------------

inline BR_CFramedBitmap* BR_CPushButton::GetBitmap() const
{
    return fBitmap;
}


//========================================================================================
// STRUCT BR_SPopUpMenuResource
//========================================================================================

struct BR_SPopUpMenuResource : BR_SPushButtonResource
{
    BR_ResourceId fMenuResourceId;
};


//========================================================================================
// CLASS cPupUpMenu
//
// Creates a button that, when clicked on, gives a pulldown menu. Pop-up menus are always
// attached to pushbuttons.
//
// The DoClick() method should be overridden to specify the behavior associated with the
// popup menu. DokeyDown() can also be used to notify a popup menu object that should be
// displayed.
//========================================================================================

class BR_CPopUpMenu : public BR_CPushButton
{
public:
	BR_CPopUpMenu(BR_CView* enclosure,
				  BR_CBureaucrat* supervisor,
				  BR_Coordinate x,
				  BR_Coordinate y,
				  ViewSizing horizontalSizing,
				  ViewSizing verticalSizing,
				  ViewId viewId,
				  const BR_CModule& module,
				  BR_ResourceId resourceId);

	BR_CPopUpMenu(BR_CView* enclosure,
				  BR_CBureaucrat* supervisor,
				  BR_Distance width,
				  BR_Distance height,
				  BR_Coordinate x,
				  BR_Coordinate y,
				  ViewSizing horizontalSizing,
				  ViewSizing verticalSizing,
				  ViewId viewId,
				  BR_CMenu* menu,
				  const BR_TString<BR_Char>& text);

	BR_CPopUpMenu(BR_CView* enclosure,
				  BR_CBureaucrat* supervisor,
				  BR_Distance width,
				  BR_Distance height,
				  BR_Coordinate x,
				  BR_Coordinate y,
				  ViewSizing horizontalSizing,
				  ViewSizing verticalSizing,
				  ViewId viewId,
				  const BR_TString<BR_Char>& text);

	BR_CPopUpMenu(BR_CView* enclosure,
				  BR_CBureaucrat* supervisor,
				  const BR_CModule& module,
				  BR_SResource& resource);

	virtual~ BR_CPopUpMenu();
	
	void DoClick(const BR_CPoint& point, KeyModifiers keyFlags);
	virtual BR_Boolean DoKeyDown(Key key,
								 unsigned short repeatCount,
								 BR_Boolean callSupervisor = TRUE);

	void InsertMenuCmd(CommandId commandId,
					   const BR_TString<BR_Char>& string,
					   CommandId commandInsertBefore);
	void InsertMenuCmd(CommandId commandId,
					   const BR_CStringList& list,
					   CommandId commandInsertBefore);
	void InsertMenuCmd(CommandId commandId,
					   const BR_CModule& module,
					   BR_ResourceId wResId,
					   CommandId commandInsertBefore);
	void InsertSeparator(BR_CMenu::ItemPosition position);
	void RemoveMenuCmd(CommandId commandId);
	void RemoveMenuItem(BR_CMenu::ItemPosition position);
	void AddMenu(BR_CPullDownMenu* menu);
	void AddMenu(BR_CPullDownMenu* menu, CommandId beforeId);
	void RemoveMenu(BR_CPullDownMenu& menu);
	void EnableCmd(CommandId commandId, BR_Boolean state = TRUE);
	void DisableCmd(CommandId commandId);
	void EnableMenuItem(BR_CMenu::ItemPosition position, BR_Boolean state = TRUE);
	void DisableMenuItem(BR_CMenu::ItemPosition position);
	void GetCmdText(unsigned short commandIdOrPosition,
					BR_TString<BR_Char>& string,
					BR_Boolean byPosition = FALSE) const;
	void SetCmdText(CommandId commandId, const BR_TString<BR_Char>& string);
	void ToggleCmdText(CommandId commandId,
					   BR_ResourceId resourceId,
					   BR_CMultiStringList::StringId stringId,
					   BR_Boolean state);
	void CheckCmd(CommandId commandId, BR_Boolean check = TRUE);
	void UncheckCmd(CommandId commandId);
	unsigned short GetItemCount() const;
	BR_CMenu::ItemPosition GetMenuPos(const BR_CPullDownMenu& menu) const;

private:
	void ShowPopUpMenu();

	BR_CMenu* fMenu;

#ifdef BR_BUILD_WIN
public:
	virtual long Dispatch(WORD wMessage,
						  WORD wParam,
						  long lParam,
						  BR_Boolean callDefaultProc = TRUE);		// ?INTERNAL?
	virtual BR_Boolean DoMenuChar(WORD wParam,
								  long lParam,
								  BR_CMenu& menu,
								  long& returnValue);				// ?INTERNAL?
#endif

	BR_SETCLASSNAME(BR_CPopUpMenu);
};

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::InsertMenuCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
								  const BR_TString<BR_Char>& string,
								  BR_CBureaucrat::CommandId cmdInsertBefore)
{
	fMenu->InsertMenuCmd(commandId, string, cmdInsertBefore);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::InsertMenuCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
								  const BR_CStringList& list,
								  BR_CBureaucrat::CommandId cmdInsertBefore)
{
	fMenu->InsertMenuCmd(commandId, list, cmdInsertBefore);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::InsertMenuCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
								  const BR_CModule& module,
								  BR_ResourceId resourceId,
								  BR_CBureaucrat::CommandId cmdInsertBefore)
{
	fMenu->InsertMenuCmd(commandId, module, resourceId, cmdInsertBefore);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::InsertSeparator
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::InsertSeparator(unsigned short position)
{
	fMenu->InsertSeparator(position);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::RemoveMenuCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::RemoveMenuCmd(BR_CBureaucrat::CommandId commandId)
{
	fMenu->RemoveMenuCmd(commandId);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::RemoveMenuItem
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::RemoveMenuItem(BR_CMenu::ItemPosition position)
{
	fMenu->RemoveMenuItem(position);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::AddMenu
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::AddMenu(BR_CPullDownMenu* menu)
{
	fMenu->AddMenu(menu);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::AddMenu
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::AddMenu(BR_CPullDownMenu* menu,
							BR_CBureaucrat::CommandId beforeId)
{
	fMenu->AddMenu(menu, beforeId);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::RemoveMenu
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::RemoveMenu(BR_CPullDownMenu& menu)
{
	fMenu->RemoveMenu(menu);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::EnableCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::EnableCmd(BR_CBureaucrat::CommandId commandId,
							  			BR_Boolean state)
{
	fMenu->EnableCmd(commandId, state);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::DisableCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::DisableCmd(BR_CBureaucrat::CommandId commandId)
{
	fMenu->DisableCmd(commandId);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::EnableMenuItem
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::EnableMenuItem(unsigned short position,
								   BR_Boolean state)
{
	fMenu->EnableMenuItem(position, state);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::DisableMenuItem
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::DisableMenuItem(unsigned short position)
{
	fMenu->DisableMenuItem(position);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::GetCmdText
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::GetCmdText(BR_CBureaucrat::CommandId commandId,
							   			BR_TString<BR_Char>& string,
							   			BR_Boolean byPosition) const
{
	fMenu->GetCmdText(commandId, string, byPosition);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::SetCmdText
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::SetCmdText(BR_CBureaucrat::CommandId commandId,
							   			const BR_TString<BR_Char>& string)
{
	fMenu->SetCmdText(commandId, string);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::ToggleCmdText
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::ToggleCmdText(BR_CBureaucrat::CommandId commandId,
								  			BR_ResourceId resourceId,
								  			BR_CMultiStringList::StringId stringId,
								  			BR_Boolean state)
{
	fMenu->ToggleCmdText(commandId, resourceId, stringId, state);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::CheckCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::CheckCmd(BR_CBureaucrat::CommandId commandId,
							 BR_Boolean check)
{
	fMenu->CheckCmd(commandId, check);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::UncheckCmd
//----------------------------------------------------------------------------------------

inline void BR_CPopUpMenu::UncheckCmd(BR_CBureaucrat::CommandId commandId)
{
	CheckCmd(commandId, FALSE);
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::GetItemCount
//----------------------------------------------------------------------------------------

inline unsigned short BR_CPopUpMenu::GetItemCount() const
{
	return fMenu->GetItemCount();
}

//----------------------------------------------------------------------------------------
// BR_CPopUpMenu::GetMenuPos
//----------------------------------------------------------------------------------------

inline BR_CMenu::ItemPosition BR_CPopUpMenu::GetMenuPos(const BR_CPullDownMenu& menu) const
{
	return fMenu->GetMenuPos(menu);
}

#endif
