#if !defined(BRAPPLIC_H) && !defined(__BEDRC__)
#define BRAPPLIC_H
//========================================================================================
//
//     File:			BRApplic.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	8/15/90
//
//     COPYRIGHT 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 BCSTOREU_H
#include "BCStoreU.h"
#endif

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

#ifndef   BRMODULE_H
#include "BRModule.h"
#endif

#ifndef BRCHORE_H
#include "BRChore.h"
#endif

#ifndef BRDOCUM_H
#include "BRDocume.h"
#endif

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

#ifndef   BRINFILE_H
#include "BRInFile.h"
#endif

#ifndef   BRFILEFI_H
#include "BRFileFi.h"
#endif


#ifdef BR_BUILD_MAC

#ifndef   BRTIMQUE_H
#include "BRTimQue.h"
#endif

#ifndef __EVENTS__
#include <Events.h>
#endif

#endif


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

class BR_CClipboard;
class BR_CPrinter;
class cResInfo;
class BR_CChore;
class BR_CSFPDialogInfo;
class BR_CAppDesktop;
class BR_CView;
class BR_CSystem;
class BR_CModule;
class BR_CAppDirector;
class BR_CWindow;
class BR_CDialogBox;
class BR_CMessanger;


//========================================================================================
//	CLASS BR_CEventLoopContext
//========================================================================================

class BR_CEventLoopContext : public BR_CObject
{
	friend class BR_CApplication;

public:
	BR_CEventLoopContext(BR_CApplication* application);
	BR_CEventLoopContext(BR_CApplication* application,
						 const BR_CWindow& window);
	~BR_CEventLoopContext();
	BR_Boolean IsContextChanged() const;

private:
	BR_CApplication* fApplication;
	BR_CEventLoopContext* fPreviousEventLoopContext;


#ifdef BR_BUILD_MAC
public:
	void ContextHasChanged();

private:
	BR_Boolean 	fMacContextHasChanged;
	WindowPtr	fMessageWindow;
#endif


#ifdef BR_BUILD_WIN
private:
	WORD 	fWinQuitMessage;
	HWND	fMessageWindow;
#endif

};


//========================================================================================
//	CLASS BR_CBedChoreList
//========================================================================================

class BR_CBedChoreList
{
public:
	BR_CBedChoreList();
	BR_CChore::ChoreId Add(BR_CChore* chore);
	void Remove(const BR_CChore& chore);
	void DoChore(BR_CChore::ChoreId id);
	void DoAll();

private:
	BC_TUnboundedCollection<BR_CChore *, BC_CUnmanaged> fList;
};


//========================================================================================
//	CLASS BR_CApplication
//========================================================================================

class BR_CApplication : public BR_CModule
{
	friend class BR_CEventLoopContext;

public:
	static BR_CApplication* GetCurrentApplication();
	virtual~ BR_CApplication();
	virtual BR_Boolean Quit();
	virtual BR_CClipboard* MakeClipboard();
	virtual BR_CHelp* MakeHelp();
	virtual BR_CDocument* CreateDocument() = 0;
	virtual BR_CDocument* OpenDocument(BR_CFileSpecification& fileSpec) = 0;
	virtual BR_Boolean ChooseFile(BR_CFileSpecification*& fileSpec,
								  BR_CSFPDialogInfo* fileFilters) const;
	virtual void SetTitle();
	virtual void GetTitle(BR_TString<BR_Char>& title) const;
	virtual BR_Boolean OutOfMemory(BR_CDocument::MemoryError severity);
	virtual void Activate();
	virtual void Deactivate();
	virtual BR_Boolean IsHidden() const;
	virtual void SetUpFileParameters();
	virtual void UncaughtBedrockException(BR_XBedException& bedrockException);
	virtual void UncaughtException();
	virtual BR_CHelp* GetHelp() const;
	virtual BR_Boolean DoCommand(CommandId commandId,
								 BR_CObject* notifier,
								 BR_Boolean callSupervisor = TRUE);
	virtual BR_Boolean DoMessage(BR_CMessanger &messanger);
	virtual void UpdateMenus(BR_CMenuBar& theMenuBar,
							 BR_Boolean callSupervisor = TRUE);
	virtual void AddDocument(BR_CDocument* document);
	virtual void RemoveDocument(const BR_CDocument& document);
	virtual BR_CApplication* GetApplication() const;
	virtual BR_CDirector* GetDirector() const;
	virtual BR_Boolean AddViewHelp(BR_CView* theView,
								   BR_CHelp::HelpTopic theId);
	virtual BR_Boolean RemoveViewHelp(const BR_CView& view);
	virtual BR_CHelp::HelpTopic GetViewHelpId(const BR_CView& view) const;
	virtual BR_CHelp::HelpTopic GetMenuHelpId(BR_CMenu::MenuId menuId) const;
	virtual BR_Boolean DoMenuHelp(BR_CMenu::MenuId theId,
								  BR_CDirector::TypeOfHelp theType);
	virtual BR_Boolean DoViewHelp(const BR_CView& theView,
								  BR_CDirector::TypeOfHelp theType);
	virtual BR_Boolean DoHelp(BR_CHelp::HelpTopic theId,
							  BR_CDirector::HelpItem theItem,
							  BR_CDirector::TypeOfHelp theType);
	virtual BR_CHelp::HelpTopic RemapHelpId(BR_CHelp::HelpTopic theId,
											BR_CDirector::HelpItem theItem,
											BR_CDirector::TypeOfHelp theType) const;
	virtual BR_Boolean ShowHelpStatusString(const BR_TString<BR_Char>& helpStatusString);
	virtual BR_Boolean GetStatusString(BR_CHelp::HelpTopic theId,
									   BR_TString<BR_Char>& helpStatusString) const;
	virtual BR_CSFPDialogInfo* GetSFPDialogInfo() const;
	virtual void SetSFPDialogInfo(BR_CSFPDialogInfo* dialogInfo);
	void SetAppDesktop(BR_CAppDesktop* newAppDesktop);
	BR_CAppDesktop* GetAppDesktop() const;
	BR_CClipboard* GetClipboard() const;
	BR_ResourceId GetResourceId() const;
	BR_CModule* GetResourceModule() const;
	const BR_CInitializationFile* GetInitializationFile() const;
	BC_Index GetDocumentCount() const;
	unsigned short GetNextDocumentNumber() const;
	BR_CDocument* GetActiveDocument() const;
	BR_Boolean IsActive() const;
	BR_CChore::ChoreId AssignChore(BR_CChore* chore);
	void RemoveChore(const BR_CChore& chore);
	const BC_TCollection<BR_CDocument *> *GetDocumentList() const;
	void SetAppModal();
	void ClearAppModal();
	BR_Boolean HaveAppModal() const;
	void RunDialog(BR_CDialogBox* theDialog);
	void Run();
	void ProcessEventsInQueue();
	void ProcessEventsInQueue(BR_CWindow& window);
	void DoChore(BR_CChore::ChoreId choreId);
	BR_Boolean SetTimer(BR_CChore::ChoreId choreId,
						BR_Milliseconds interval,
						HWND pane = NULL);
	void KillTimer(BR_CChore::ChoreId choreId,
				   HWND pane = NULL);

	// they used to be protected [HLX]
	void SetClipboard(BR_CClipboard* newClipboard);
	void SetHelp(BR_CHelp* newHelp);

protected:
	BR_CApplication(BR_CSystem* system,
					BR_CModule* module,
					BR_ResourceId resourceId);
	virtual BR_CAppDesktop* MakeAppDesktop();
	virtual BR_CSFPDialogInfo* MakeSFPDialogInfo();
	virtual void Initialize();
	virtual void ProcessEventsInQueueIntercept();
	virtual void ProcessEventsUntilContextChangesIntercept(BR_CEventLoopContext& currentContext);
	virtual void EventLoopHook();
	void SetHelpResModule(BR_CModule* helpResourceModule);
	void SetHelpStatusResId(BR_ResourceId resourceId);
	void SetHelpMenuResId(BR_ResourceId resourceId);

private:
	BC_TUnboundedCollection<BR_CDocument *, BC_CUnmanaged> fDocumentList;
	BR_CBedChoreList fTimerChoreList;			// application's timer chores
	BR_CBedChoreList fIdleChoreList;			// application's idle chores
	BR_CClipboard* fClipboard;					// pointer to the clipboard
	BR_CAppDesktop* fAppDesktop;				// pointer to the application's desktop
	BR_CHelp* fHelp;							// pointer to the help file
	BR_ResourceId fAppResourceId;				// application's resource ID
	BR_CModule* fResourceModule;				// application's resource module
	BR_CInitializationFile fIniFile;			// application's ini file
	BR_CSFPDialogInfo* fDialogInfo;				// Dialog information class used by app.
	unsigned short fNextDocument;				// Number of the fNext document window.
	BR_Boolean fIsActive;						// Are we in the foreground?
	unsigned short fAppModalCount;				// the application's modal count
	BR_CAppDirector* fAppDirector;				// application's director
	BR_CEventLoopContext* fCurrentEventLoopContext;

	void PerformChores();
	void InitIniFile();
	void OpenDocuments();
	void RunMain();
	void ProcessEvent();
	void ProcessEventsUntilContextChanges(BR_CEventLoopContext& currentContext);
	BR_Boolean IsEventAvailable() const;


#ifdef BR_BUILD_MAC
public:
	static EventRecord gMacLastMouseDown;		// last mouse down event
	static EventRecord gMacLastMouseUp;			// last mouse up event

	void DoMouseDown(EventRecord& macEvent);
	void DoMouseUp(EventRecord& macEvent);
	void DoKeyDownEvent(EventRecord& macEvent);
	void DoKeyUpEvent(EventRecord& macEvent);
	void DoDiskEvent(EventRecord& macEvent);
	void DoOtherEvent(EventRecord& macEvent);
	void DoHighLevelEvent(EventRecord& macEvent);
	void Idle(EventRecord& macEvent);

protected:
	void DoTheUpdateMenus();

private:
	static BR_CApplication* gMacCurrentApplicationPtr;// Pointer to current application.
	static short gMacAutoKeyRepeatCount;		// auto fKey repeat count
	static RgnHandle gMacMouseRegion;			// Notify if mouse not in this region
	BR_CBedChoreList fMacUrgentChoreList;		// the application's urgent chores
	BR_CTimerQueue fMacTimerQueue;				// the list of Timer elements
	BR_Boolean fMacIsApplicationRunning;		// is this application running?
#endif


#ifdef BR_BUILD_WIN
protected:
	BR_Char* GetCommandLine() const;

private:
	BR_PlatformHandle fWinPreviousInstanceHandle;						// handle to the previous instance
	BR_PlatformHandle fWinAcceleratorTableHandle;
	BR_PlatformHandle fWinHelpAcceleratorTableHandle;
	HWND fWinCurrentMessageWindow;
	WORD fWinCurrentQuitMessage;
	WORD fWinLastMessageReceived;
#endif

	BR_SETCLASSNAME(BR_CApplication);
};


//----------------------------------------------------------------------------------------
// BR_CApplication::PerformChores
//----------------------------------------------------------------------------------------

inline void BR_CApplication::PerformChores()
{
	fIdleChoreList.DoAll();
}

//----------------------------------------------------------------------------------------
// BR_CApplication::DoChore
//----------------------------------------------------------------------------------------

inline void BR_CApplication::DoChore(BR_CChore::ChoreId choreId)
{
	fTimerChoreList.DoChore(choreId);
}

//----------------------------------------------------------------------------------------
// BR_CApplication::SetAppModal
//----------------------------------------------------------------------------------------

inline void BR_CApplication::SetAppModal()
{
	++fAppModalCount;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::ClearAppModal
//----------------------------------------------------------------------------------------

inline void BR_CApplication::ClearAppModal()
{
	--fAppModalCount;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::HaveAppModal
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CApplication::HaveAppModal() const
{
	return (BR_Boolean)fAppModalCount;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::SetAppDesktop
//----------------------------------------------------------------------------------------

inline void BR_CApplication::SetAppDesktop(BR_CAppDesktop* newAppDesktop)
{
	fAppDesktop = newAppDesktop;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetAppDesktop
//----------------------------------------------------------------------------------------

inline BR_CAppDesktop* BR_CApplication::GetAppDesktop() const
{
	return fAppDesktop;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetClipboard
//----------------------------------------------------------------------------------------

inline BR_CClipboard* BR_CApplication::GetClipboard() const
{
	return fClipboard;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetResourceId
//----------------------------------------------------------------------------------------

inline BR_ResourceId BR_CApplication::GetResourceId() const
{
	return fAppResourceId;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetResourceModule
//----------------------------------------------------------------------------------------

inline BR_CModule* BR_CApplication::GetResourceModule() const
{
	return fResourceModule;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetInitializationFile
//----------------------------------------------------------------------------------------

inline const BR_CInitializationFile* BR_CApplication::GetInitializationFile() const
{
	return &fIniFile;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetDocumentCount
//----------------------------------------------------------------------------------------

inline BC_Index BR_CApplication::GetDocumentCount() const
{
	return fDocumentList.Length();
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetNextDocumentNumber
//----------------------------------------------------------------------------------------

inline unsigned short BR_CApplication::GetNextDocumentNumber() const
{
	return fNextDocument;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::IsActive
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CApplication::IsActive() const
{
	return fIsActive;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::GetDocumentList
//----------------------------------------------------------------------------------------

inline const BC_TCollection<BR_CDocument *> *BR_CApplication::GetDocumentList() const
{
	return &fDocumentList;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::SetClipboard
//----------------------------------------------------------------------------------------

inline void BR_CApplication::SetClipboard(BR_CClipboard* newClipboard)
{
	fClipboard = newClipboard;
}

//----------------------------------------------------------------------------------------
// BR_CApplication::SetHelp
//----------------------------------------------------------------------------------------

inline void BR_CApplication::SetHelp(BR_CHelp* newHelp)
{
	fHelp = newHelp;
}

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
// BR_CApplication::SetTimer
//----------------------------------------------------------------------------------------

inline BR_Boolean BR_CApplication::SetTimer(BR_CChore::ChoreId choreId,
											BR_Milliseconds interval,
											HWND pane)
{
	return (::SetTimer(pane, choreId, interval, NULL) != 0);
}
#endif

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
// BR_CApplication::KillTimer
//----------------------------------------------------------------------------------------

inline void BR_CApplication::KillTimer(BR_CChore::ChoreId choreId,
									   HWND pane)
{
	::KillTimer(pane, choreId);
}
#endif

#ifdef BR_BUILD_MAC
//----------------------------------------------------------------------------------------
// BR_CEventLoopContext::ContextHasChanged
//----------------------------------------------------------------------------------------

inline void BR_CEventLoopContext::ContextHasChanged()
{
	fMacContextHasChanged = TRUE;
}
#endif 

#endif


