#if !defined(BROWDRMN_H) && !defined(__BEDRC__)
#define BROWDRMN_H
//========================================================================================
//
//     File:			BROwDrMn.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	September 29, 1990
//
//     COPYRIGHT 1990-1993 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 BROWDRMN_K
#include "BROwDrMn.k"
#endif

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

#ifndef BRVIEW_H
#include "BRView.h"
#endif

//========================================================================================
//	Forward class declarations
//========================================================================================
class BR_CMenuPane;
class BR_CFramedBitmap;
class BR_CBitmap;

//========================================================================================
//	BR_SBedMacOwnerDrawMDEFHeader
//
// A unique MDEF is allocated for every owner-Draw menu because the pointer
// to the menu object is pushed onto the stack by the MDEF code.
//========================================================================================

#ifdef BR_BUILD_MAC
class BR_COwnerDrawMenu;

struct BR_SBedMacOwnerDrawMDEFHeader
{
	short popRTS;
	short push;
	BR_COwnerDrawMenu* ownerDrawMenu;
	short pushRTS;
	short jump;
	long address;
};
#endif

//========================================================================================
//	BR_SOwnerDrawMenuResource
//========================================================================================
struct BR_SOwnerDrawMenuResource : BR_SPullDownMenuResource
{
	unsigned short fNumberOfRows;
	unsigned short fNumberOfColumns;
	unsigned short fStartCommand;
};

//========================================================================================
//	BR_COwnerDrawMenu
//
//  an abstract base class for imlementing owner-Draw menus:
// 	a kind of menus which can Draw whatever they wish in every menu item.  An
// 	OD-menu is responsible for measuring item sizes and drawing individual items
//========================================================================================
class BR_COwnerDrawMenu : public BR_CPullDownMenu
{
public:
	virtual void GetItemSize(BR_CMenuPane& menuPane,
							 BR_CRectangle& area,
							 BR_CBureaucrat::CommandId commandId) const = 0;
	virtual void GetItemFrame(BR_CMenuPane& menuPane,
							  BR_CRectangle& area,
							  BR_CBureaucrat::CommandId commandId) const = 0;

	void AddNewItem(unsigned short nRow,
					unsigned short nColumn);
	void GetItemRowColumn(BR_CBureaucrat::CommandId commandId,
						  unsigned short& nRow,
						  unsigned short& nColumn) const;
	BR_CBureaucrat::CommandId GetStartCmd() const;

	// This is used to do keyboard selection in OD-menus
	virtual BR_Boolean GetItemByCharacter(BR_StringCharacter character,
									  BR_CBureaucrat::CommandId& commandId) const;

	// Inherited methods
	virtual void AddMenu(BR_CPullDownMenu* Menu,
						 ItemPosition beforePos);

public:											// Implementation
	// Moved here because Zortech (on PC) sees protected DrawItem() method.
	void DrawItem(BR_CMenuPane& pane,
				  BR_CRectangle& area,
				  BR_CBureaucrat::CommandId commandId,
				  unsigned short stateP);

protected:
	BR_COwnerDrawMenu(const BR_CModule& module,
					  BR_ResourceId nameResourceId,
					  BR_CBureaucrat::CommandId startCommandP,
					  unsigned short nRowsP,
					  unsigned short nColumnsP);

	BR_COwnerDrawMenu(BR_CApplication& app,
					  BR_CMenu& parentMenu,
					  const BR_CModule& module,
					  BR_SResource& resource);

	virtual~ BR_COwnerDrawMenu();

	unsigned short GetRows() const;
	unsigned short GetColumns() const;

	// Info methods that give you state of the current item
	BR_Boolean IsDrawSelected() const;
	BR_Boolean IsDrawGrayedOut() const;
	BR_Boolean IsDrawChecked() const;

	// This method actually draws an item
	virtual void DrawItem(BR_CMenuPane& pane,
						  BR_CRectangle& area,
						  BR_CBureaucrat::CommandId commandId) = 0;
	void InitOwnerDraw();

protected:
	unsigned short fNumberOfRows;						// # of rows in the menu
	unsigned short fNumberOfColumns;					// # of columns

private:
	BR_CBureaucrat::CommandId fStartCommand;			// Start command used to calc cmdIds
	unsigned short fOwnerDrawMenuState;								// Owner-Draw item state: Windows::ODS_xxx

	// Inherited methods
	virtual void AddMenu(BR_CPullDownMenu* menu);

	//----------------------------------------------------------------------------------------
	//	Macintosh
	//----------------------------------------------------------------------------------------
#ifdef BR_BUILD_MAC
public:
	virtual BR_CBureaucrat::CommandId GetItemCmd(ItemPosition itemPos) const;

	void DrawWholeMenu(BR_CMenuPane& pane,
					   BR_CRectangle& rect);	// ?INTERNAL?
	short Pick(BR_CMenuPane& pane,
			   BR_CRectangle& area,
			   BR_CPoint& mousePt,
			   ItemPosition item);				// ?INTERNAL?
	unsigned short GetItemState(ItemPosition position);	// ?INTERNAL?

	virtual void Measure(BR_CMenuPane& pane,
						 BR_CPoint& aPoint);	// ?INTERNAL?
	virtual unsigned short GetItemFromLoc(BR_CMenuPane& menuPane,
								  BR_CRectangle& area,
								  BR_CPoint& mousePt);// ?INTERNAL?
	virtual BR_CPullDownMenu* BedMacFindMenuItem(BR_CBureaucrat::CommandId commandId,
												 BR_CMenu::ItemPosition& position);// ?INTERNAL?

	// Overridden because Commands is not used in BR_COwnerDrawMenu
	virtual void InsertCmd(BR_CBureaucrat::CommandId cmdID,
						   ItemPosition position);
	virtual void AppendCmd(BR_CBureaucrat::CommandId cmdID);
	virtual void RemoveCmd(ItemPosition position);

private:
	Handle fMenuDefProc;						// The unique MDEF procedure.
	Handle fOldMenuDefProc;						// Save the original menu def proc
	long fCheckFlags[4];						// We can have up to 128 items (I think it's enough)	
#endif

	BR_SETCLASSNAME(BR_COwnerDrawMenu);
};

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::GetStartCmd
//----------------------------------------------------------------------------------------
inline BR_CBureaucrat::CommandId BR_COwnerDrawMenu::GetStartCmd() const
{
	return fStartCommand;
}

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::GetRows
//----------------------------------------------------------------------------------------
inline unsigned short BR_COwnerDrawMenu::GetRows() const
{
	return fNumberOfRows;
}

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::GetColumns
//----------------------------------------------------------------------------------------
inline unsigned short BR_COwnerDrawMenu::GetColumns() const
{
	return fNumberOfColumns;
}

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::IsDrawSelected
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_COwnerDrawMenu::IsDrawSelected() const
{
	return (fOwnerDrawMenuState & ODS_SELECTED);
}

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::IsDrawGrayedOut
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_COwnerDrawMenu::IsDrawGrayedOut() const
{
	return (fOwnerDrawMenuState & ODS_GRAYED);
}

//----------------------------------------------------------------------------------------
//	BR_COwnerDrawMenu::IsDrawChecked
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_COwnerDrawMenu::IsDrawChecked() const
{
	return (fOwnerDrawMenuState & ODS_CHECKED);
}

//========================================================================================
//	BR_CMenuPane
//========================================================================================
class BR_CMenuPane : public BR_CView
{
public:
	virtual~ BR_CMenuPane();
	virtual void DoDraw();
	BR_COwnerDrawMenu* GetMenu() const;

public:
	// Inherited methods
	virtual void PreDraw();
	virtual void PostDraw();

	//----------------------------------------------------------------------------------------
	//	Macintosh
	//----------------------------------------------------------------------------------------
#ifdef BR_BUILD_MAC
public:
	BR_CMenuPane(BR_CView* enclosure,
				 BR_COwnerDrawMenu* menu,
				 const BR_CRectangle& area);
	virtual BR_CWindow* GetWindow() const;
private:
	BR_COwnerDrawMenu* fOwnerDrawMenu;
	BR_CRectangle fOwnerDrawRect;
#endif

	//----------------------------------------------------------------------------------------
	//	Windows
	//----------------------------------------------------------------------------------------
#ifdef BR_BUILD_WIN
public:
	unsigned short GetItem() const;
	void MeasureItem();
	BR_CMenuPane(BR_CView* enclosure,
				 LPDRAWITEMSTRUCT drawItemStruct);

	BR_CMenuPane(BR_CView* enclosure,
				 LPMEASUREITEMSTRUCT drawItemStruct);
private:
	LPDRAWITEMSTRUCT fWinDrawDataStruct;		// Data passed with WM_DRAWITEM
	LPMEASUREITEMSTRUCT fWinMeasureDataStruct;	// Data passed with WM_MEASUREITEM
	BR_Boolean fCascading;

	BR_Boolean IsCascadingMenu() const;
#endif

	BR_SETCLASSNAME(BR_CMenuPane);
};



#ifdef BR_BUILD_MAC
//----------------------------------------------------------------------------------------
//	BR_CMenuPane::GetMenu
//----------------------------------------------------------------------------------------
inline BR_COwnerDrawMenu *BR_CMenuPane::GetMenu() const
{
	return fOwnerDrawMenu;
}
#endif

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
//	BR_CMenuPane::IsCascadingMenu
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_CMenuPane::IsCascadingMenu() const
{
	return fCascading;
}
#endif

//========================================================================================
//	CLASS BR_CBitmapMenu
//
//		an OD-menu that draws pieces of a bitmap in every menu item.
// 		All items are assumes to be of equal size.  A bitmap can contain parts
// 		that represent items in disabled/checked/selected states.  These parts are
// 		optional -- BR_CBitmapMenu does some default drawing
//========================================================================================

class BR_CBitmapMenu : public BR_COwnerDrawMenu
{
public:
	typedef unsigned short int BitmapMenuBitmapFlags;

public:
	BR_CBitmapMenu(BR_CApplication& app,
				   const BR_CModule& module,
				   BR_ResourceId mameResId,
				   BR_CBureaucrat::CommandId startCommand,
				   unsigned short numberOfRows,
				   unsigned short numberOfColumns,
				   BR_ResourceId bmpResId,
				   BitmapMenuBitmapFlags wfFlagsP);

	BR_CBitmapMenu(BR_CApplication& app,
				   BR_CMenu& parentMenu,
				   const BR_CModule& module,
				   BR_SResource& resource);

	virtual~ BR_CBitmapMenu();

	virtual void DrawItem(BR_CMenuPane& pane,
						  BR_CRectangle& area,
						  BR_CBureaucrat::CommandId commandId);

	virtual void GetItemSize(BR_CMenuPane& menuPane,
							 BR_CRectangle& area,
							 BR_CBureaucrat::CommandId commandId) const;
	virtual void GetItemFrame(BR_CMenuPane& menuPane,
							  BR_CRectangle& area,
							  BR_CBureaucrat::CommandId commandId) const;

	void InitBitmapMenu(BR_CApplication& app,
						const BR_CModule& module,
						BR_ResourceId nameResId,
						unsigned short numberOfRows,
						unsigned short numberOfColumns);

protected:
	BR_CFramedBitmap* GetBitmap() const;

	void GetCheckMarkSize(BR_CRectangle& checkMarkRect) const;
	void DrawCheckMark(BR_CMenuPane& menuPane,
					   BR_CRectangle& itemArea);

private:
	BR_CFramedBitmap* fBitmap;				// Bitmap which gets drawin in the menu
	BitmapMenuBitmapFlags fBitmapMenuFlags;				// BMPMENU_xxx |ed together
	unsigned short fSelectedOffset;					// Offset into `selected' part of the
	//   bitmap -- for optimization of DrawItem()
	unsigned short fGrayedOutOffset;					// --"-- `grayed out' part
	unsigned short fCheckedOffset;					// --"-- `checked' part
	static BR_CBitmap* gCheckMarkBitmap;				// A bitmap used to Draw check-mark
	static unsigned short gNumberOfInstances;			// Counter of instances of this class.
	//   Used to make sure we only load one
	//   bitmap and use it for all menus

	void LoadCheckMark(BR_CApplication& app);
	BR_CFramedBitmap* LoadBitmap(BR_CAppDesktop *desktop,
								 const BR_CModule& module,
								 BR_ResourceId bmpResId,
								 unsigned short numberOfRows,
								 unsigned short numberOfColumns);
	BR_CBitmap& GetCheckMarkBitmap() const;
	BR_Boolean HaveSelectedBmp() const;
	BR_Boolean HaveCheckedBmp() const;
	BR_Boolean HaveGrayedOutBmp() const;


	BR_SETCLASSNAME(BR_CBitmapMenu);
};

//----------------------------------------------------------------------------------------
//	BR_CBitmapMenu::GetCheckMarkBitmap
//----------------------------------------------------------------------------------------
inline BR_CBitmap& BR_CBitmapMenu::GetCheckMarkBitmap(void) const
{
	return (*gCheckMarkBitmap);
}


//----------------------------------------------------------------------------------------
//	BR_CBitmapMenu::HaveSelectedBmp
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_CBitmapMenu::HaveSelectedBmp(void) const
{
	return (fBitmapMenuFlags & kHasSelectedBitmap);
}


//----------------------------------------------------------------------------------------
//	BR_CBitmapMenu::HaveCheckedBmp
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_CBitmapMenu::HaveCheckedBmp(void) const
{
	return (fBitmapMenuFlags & kHasCheckedBitmap);
}


//----------------------------------------------------------------------------------------
//	BR_CBitmapMenu::HaveGrayedOutBmp
//----------------------------------------------------------------------------------------
inline BR_Boolean BR_CBitmapMenu::HaveGrayedOutBmp(void) const
{
	return (fBitmapMenuFlags & kHasGrayedOutBitmap);
}

//----------------------------------------------------------------------------------------
//	BR_CBitmapMenu::GetBitmap
//----------------------------------------------------------------------------------------
inline BR_CFramedBitmap* BR_CBitmapMenu::GetBitmap() const
{
	return fBitmap;
}

//========================================================================================
//	BR_SBitmapMenuResource
//========================================================================================
struct BR_SBitmapMenuResource : BR_SOwnerDrawMenuResource
{
	BR_ResourceId fBitmapResourceId;							// ResId of the bitmap
	BR_CBitmapMenu::BitmapMenuBitmapFlags wfFlags;		// Bitmap usage fFlags
};

#endif


