#if !defined(BRMENU_H) && !defined(__BEDRC__)
#define BRMENU_H
//========================================================================================
//
//     File:			BRMenu.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	September 14, 1990
//
//     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 BROBJECT_H
#include "BRObject.h"
#endif

#ifndef BRRECT_H
#include "BRRect.h"
#endif

#ifndef BRBUREA_H
#include "BRBureau.h"
#endif

#ifndef BRMSTRLI_H
#include "BRMStrLi.h"
#endif

#ifndef BCSTOREU_H
#include "BCStoreU.h"
#endif

#ifndef BCCOLLU_H
#include "BCCollU.h"
#endif

#ifndef BRRESOUR_H
#include "BRResour.h"
#endif

#ifndef BRBEDEXC_H
#include "BRBedExc.h"
#endif

#ifndef BRTSTRS_H
#include "BRTStrs.h"
#endif

#if defined(BR_BUILD_MAC) && !defined(__MENUS__)
#include <Menus.h>
#endif


//========================================================================================
// Forward declaration
//========================================================================================

class BR_CPullDownMenu; 
class BR_CStringList;
class BR_CModule;
class BR_CView;


//========================================================================================
//  Type definitions
//========================================================================================
#ifdef BR_BUILD_MAC
typedef  MenuHandle BR_PlatformMenuHandle;
#endif
#ifdef BR_BUILD_WIN
typedef HMENU BR_PlatformMenuHandle;
#endif

//========================================================================================
// Constants -- Move this to the class scope
//========================================================================================

const unsigned short kInvalidPosition = 0xFFFF;
const unsigned short kMenuNotFound = kInvalidPosition;
const unsigned short kAddAtEnd = kInvalidPosition;


//========================================================================================
// CLASS BR_CBedMenuItemTable
//
// This class implements a table that Contains the tuple (ItemPosition, CommandId |
// submenu, Item) for each item in an menu. When we finally get our new collections, an
// appropriate container should replace this class. Additionally, this class could be
// scoped to BR_CMenu.
//========================================================================================

struct BR_SMenuItemTableData
{
	BR_CObject *fItem;
	
	union
	{
		BR_CBureaucrat::CommandId fCommandId;
		BR_CPullDownMenu *fSubmenu;
	};
	
	// The following two bytes can provide up to 16 bits worth of 'flag' data.
	
	unsigned short fEnabled : 1;
	unsigned short fMarked : 1;
	unsigned short fHasSubmenu : 1;
	unsigned short fUnusedFlags : 14;
};

class BR_CBedMenuItemTable : public BR_CObject
{
public:
	typedef unsigned short int ItemTableItemPosition;
	
	enum { kDefaultGrowIncrement = 8 };
	
	BR_CBedMenuItemTable(size_t growIncrment = kDefaultGrowIncrement);
	BR_CBedMenuItemTable(const BR_CBedMenuItemTable &menuItemTable);
	BR_CBedMenuItemTable &operator=(const BR_CBedMenuItemTable &menuItemTable);
	
	~BR_CBedMenuItemTable();
	
	void AppendItem(BR_CObject *item, BR_CBureaucrat::CommandId commandId);
	void AppendSubmenu(BR_CObject *item, BR_CPullDownMenu *submenu);
	BR_CBureaucrat::CommandId GetCommandId(ItemTableItemPosition position) const;
	BR_Boolean GetEnabledFlag(ItemTableItemPosition position) const;
	BR_CObject *GetItem(ItemTableItemPosition position) const;
	BR_Boolean GetMarkedFlag(ItemTableItemPosition position) const;
	size_t GetNumberOfItems() const;
	ItemTableItemPosition GetPosition(BR_CBureaucrat::CommandId commandId) const;
	BR_CPullDownMenu *GetSubmenu(ItemTableItemPosition position) const;
	void InsertItem(BR_CObject *item, BR_CBureaucrat::CommandId commandId, ItemTableItemPosition position);
	void InsertSubmenu(BR_CObject *item, BR_CPullDownMenu *submenu, ItemTableItemPosition position);
	void Remove(ItemTableItemPosition position);
	void SetEnabledFlag(ItemTableItemPosition position, BR_Boolean flag);
	void SetMarkedFlag(ItemTableItemPosition position, BR_Boolean flag);

private:
	void SetTableSize(size_t numberOfEntries);
	
	size_t fGrowIncrement;
	BR_SMenuItemTableData *fMenuItemTable;
	size_t fNumberOfItems;
	size_t fNumberOfTableEntries;
	
	BR_SETCLASSNAME(BR_CBedMenuItemTable);
};

//----------------------------------------------------------------------------------------
// BR_CBedMenuItemTable::GetNumberOfItems
//----------------------------------------------------------------------------------------

inline size_t BR_CBedMenuItemTable::GetNumberOfItems() const
{
	return fNumberOfItems;
}


//========================================================================================
// STRUCT BR_SMenuResource
//========================================================================================

struct  BR_SMenuResource : BR_SResource
{
};

//========================================================================================
//	CLASS BR_CMenu
//========================================================================================

class BR_CMenu : public BR_CObject
{
public:

	// CFRONT BUG
	// typedef BR_CBedMenuItemTable::ItemTableItemPosition ItemPosition;
	
	typedef unsigned short int ItemPosition;
	typedef unsigned short int MenuId;

	virtual~ BR_CMenu();

	virtual unsigned short GetName(BR_TString<BR_Char>& buffer) const;
	virtual void InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
							   const BR_TString<BR_Char>& string,
							   BR_CBureaucrat::CommandId cmdInsertBefore);
	virtual void InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
							   const BR_CStringList& list,
							   BR_CBureaucrat::CommandId cmdInsertBefore);
	virtual void InsertMenuCmd(BR_CBureaucrat::CommandId commandId,
							   const BR_CModule& module,
							   BR_ResourceId resourcdId,
							   BR_CBureaucrat::CommandId cmdInsertBefore);
	virtual void InsertSeparator(ItemPosition position);
	virtual void RemoveMenuCmd(BR_CBureaucrat::CommandId commandId);
	virtual void RemoveMenuItem(ItemPosition position);
	virtual void RemoveMenu(BR_CPullDownMenu& menu);

	virtual BR_CBureaucrat::CommandId GetItemCmd(ItemPosition position) const;

	virtual void AddMenu(BR_CPullDownMenu* menu);
	virtual void AddMenu(BR_CPullDownMenu* menu,
						 ItemPosition beforePosition);

	virtual void EnableCmd(BR_CBureaucrat::CommandId commandId,
						   BR_Boolean state = TRUE);
	virtual void DisableCmd(BR_CBureaucrat::CommandId commandId);
	virtual void EnableMenuItem(ItemPosition position,
								BR_Boolean state = TRUE);
	virtual void DisableMenuItem(ItemPosition position);
	virtual BR_Boolean IsCmdEnabled(BR_CBureaucrat::CommandId commandId);
	virtual BR_Boolean IsItemEnabled(ItemPosition position);

	// This interface to the following 3 methods should be changed. We should get the text
    // by Position. If the user wants it by CommandId they can call
    // GetCommandId(position).
	
	virtual void GetCmdText(unsigned short commandIdOrPosition,
							BR_TString<BR_Char>& string,
							BR_Boolean byPosition = FALSE) const;
	virtual void SetCmdText(unsigned short commandIdOrPosition,
							const BR_TString<BR_Char>& string,
							BR_Boolean byPosition = FALSE);
	virtual void ToggleCmdText(unsigned short commandIdOrPosition,
							   BR_ResourceId resourceId,
							   BR_CMultiStringList::StringId stringId,
							   BR_Boolean state,
							   BR_Boolean byPosition = FALSE);

	virtual unsigned short GetItemCount() const;
	virtual ItemPosition GetMenuPos(const BR_CPullDownMenu& menu) const;
	virtual BR_CPullDownMenu* GetSubMenu(ItemPosition position) const;

	virtual void CheckCmd(BR_CBureaucrat::CommandId commandId,
						  BR_Boolean check = TRUE);
	virtual void UncheckCmd(BR_CBureaucrat::CommandId commandId);
	virtual void CheckMenuItem(ItemPosition position,
							   BR_Boolean check = TRUE);
	virtual void UncheckMenuItem(ItemPosition position);
	virtual BR_Boolean IsCmdChecked(BR_CBureaucrat::CommandId commandId);
	virtual BR_Boolean IsItemChecked(ItemPosition position);

	void DeleteAll();
	BR_Boolean Show(BR_CView& pane,
					BR_Coordinate x,
					BR_Coordinate y);

	BR_PlatformMenuHandle GetHandle() const;
	void SetHandle(BR_PlatformMenuHandle menuHandle);

	BR_CPullDownMenu *BedHandleToPullDown(BR_PlatformMenuHandle menuHandle) const;
	const BC_TCollection<BR_CPullDownMenu *> *BedGetPullDown() const;
	void BedSetShouldDelete(BR_Boolean shouldDelete);

protected:
	BR_CMenu(BR_Boolean create);

	BR_CBedMenuItemTable fItemTable;


private:
	BR_PlatformMenuHandle fMenuHandle;								// The native menu handle
	short fPopItem;
	BR_Boolean fDelete;							
		// If allocates MSWindows fMemory
	BC_TUnboundedCollection<BR_CPullDownMenu *, BC_CUnmanaged> fPullDownList;
		// Keeps track of menu structure

#ifdef BR_BUILD_MAC
public:
	BR_CPullDownMenu *BedMacIdToPullDown(MenuId menuId) const;
	short BedMacPosToId(ItemPosition position) const;
	virtual BR_CPullDownMenu* BedMacFindMenuItem(BR_CBureaucrat::CommandId commandId,
												 ItemPosition& position);
#endif

#ifdef BR_BUILD_WIN
public:
	void BedWinAddToPullDownList(BR_CPullDownMenu *menu);
	virtual ItemPosition BedWinGetBaseId() const;
#endif

	BR_SETCLASSNAME(BR_CMenu);
};

//----------------------------------------------------------------------------------------
// BR_CMenu::BedGetPullDown
//----------------------------------------------------------------------------------------

inline const BC_TCollection<BR_CPullDownMenu *> *BR_CMenu::BedGetPullDown() const
{
	return &fPullDownList;
}

//----------------------------------------------------------------------------------------
// BR_CMenu::BedGetHandle
//----------------------------------------------------------------------------------------

inline BR_PlatformMenuHandle BR_CMenu::GetHandle() const
{
	return fMenuHandle;
}

//----------------------------------------------------------------------------------------
// BR_CMenu::BedSetHandle
//----------------------------------------------------------------------------------------

inline void BR_CMenu::SetHandle(BR_PlatformMenuHandle menuHandle)
{
	fMenuHandle = menuHandle;
}

//----------------------------------------------------------------------------------------
// BR_CMenu::BedSetShouldDelete
//----------------------------------------------------------------------------------------

inline void BR_CMenu::BedSetShouldDelete(BR_Boolean shouldDelete)
{
	fDelete = shouldDelete;
}


#endif

