/****************************************************************************************

		MCEvent.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		Author:	Pierre
		Date:	12/11/97

		Revision History

		when		who			what & why
		==========	==========	======================================================
		9/23/99		Ian			Moved all the static routines from TMCPlatformEvent into
								MCPlatformEventUtils.h in the TMCPlatformEventUtilities class.
		9/16/99		Ian			Added CheckForUserCancel().
		8/20/99		Ian			Added GetMouseScreenInfo().
		7/2/99		Ian			Added CheckKeyDown().
		6/16/99		Ian			Added an optional tolerance point to WaitMouseMoved.
		6/10/99		Ian			Array API changes.
		5/21/99		cph			moved TMCEventData out to internal header MCEventData.h 
		4/23/99		Pierre		added fUnique flag to events. If it is set to non unique, 
								only one event of this kind can be posted in the event queue.
								You can specify whever the oleder or the newr event of this calss is kept.
		4/20/99		Eml			Inlined ButtonDown, CommandKeyDown, ShiftKeyDown, 
										OptionKeyDown, ControlKeyDown, AutoKey, AlphaLocked
		3/30/99		Eml			Added TMCTimer
		2/22/99		Ian			TMCOpenFilesEventData(): Made the file list a
								TMCCountedPtrArray because files are counted.
		2/22/99		Pbk			Added HandleDoubleByte call 
		2/4/99		Ian			Added the TMCQuitEventData structure.
		1/18/99		Ian			Added YieldForKeysAndMouse().
		1/12/99		Ian			Added kOpenFilesEvt, TMCPlatformEvent::PostEvent(),
								and custom event data for the open files event.
		8/24/98		Ian			Added a new field fEventData to TMCPlatformEvent.
		8/23/98		tsh			Added kTabletEvt
		8/14/98		Eml			Added TMCThread support
		7/19/98		Ian			Added operator == and != to TMCModifiers. Renamed
								IsShiftKeyDown to ShiftKeyPressed, to be consistant with
								other key state checks. Added TMCPlatformEvent::WaitMouseMoved.
		6/5/98		Ian			Renamed fgCurrentModifiers to sCurrentModifiers.
		6/2/98		Ian			Added a new event type kMouseDownOutsideModalWindow.
		5/12/98		Ian			CoreLoop(): Added a TMCPlatformWindow* so we can tell when
								we are in a modal dialog.
		4/3/98		Pbk			Changed Event Handling to a Dispatch Function mechanism.
		4/2/98		Ian			Renamed GetMousePosition() to GetMouseScreenPostion(), to reflect
								a change in the functions behavior.
		3/13/98		Ian			Added file header, kchPeriod, and WaitTicks().

*****************************************************************************************/

#ifndef __MCEVENT__
#define __MCEVENT__

#include "MCBasicDefines.H"
#include "MCBasicTypes.H"
#include "MCPoint.h"

class TMCRect;

template <class T> class TMCPtrArray;


enum EMCEventPriority
 {
	kPriorityLowest		= 127,
	kPriorityLow		= kPriorityLowest-32,
	kPriorityNormal		= 64,
	kPriorityHigh		= kPriorityNormal-32,
	kPriorityHighest	= 0
};


//Note: if you change a value, keep MCKeyBindingsDefs.h in sync !
enum EAsciiControlCode
 {
	kchHome				= 1,
	kchEnter			= 3,	 
	kchEnd				= 4,		
	kchHelp				= 5,
	kchCommand			= 6,
	kchBackspace		= 8,	  
	kchTab				= 9,
	kchPageUp			= 11,
	kchPageDown			= 12,
	kchReturn			= 13,
	kchLeftMouse		= 14,
	kchRightMouse		= 15,
	kchFunction			= 16,
	kchContextMenu		= 17,
	kchEscape			= 27,  
	kchClear			= 27,
	kchLeft				= 28,
	kchRight			= 29,	  
	kchUp				= 30,
	kchDown				= 31,		 
	kchSpace			= 32,
	kchPeriod			= 46,
	kchFwdDelete		= 127  
};

enum PlatformMessage
 {
    kNullEvent			= 0,
    kMouseDown,
	kContextMouseDown,
	kMiddleMouseDown,
	kDesktopMouseDown,
	kMenuEvent,    
 	kFirstWindowMessage,
	kWindowMoved,
	kWindowResized,
	kAttemptWindowClose,
	kWindowMacZoomIn,
	kWindowMacZoomOut,
	kWindowMaximize,
	kWindowMinimize,
	kWindowFloat,
	kWindowUnfloat,
	kWindowSelect,
	kLastWindowMessage, 
    kMouseUp,
    kKeyDown,
    kKeyUp,
    kAutoKey,
    kUpdateEvt,
    kUpdateMinimizedEvt,
    kActivateEvt,
    kDeactivateEvt,
    kMouseMove, 
	kValidateCursor,
	kActivateApp,
	kDeactivateApp, 
	kQuitApp, 
	kAppResized,
	kMouseDownOutsideModalWindow,
	kTabletEvt,
	kOpenFilesEvt,
	kMouseWheel,
//Mac Specific events
	kDiskEvt,
    kOsEvt,
//Win Specific message
	kSetupMenus,
	kAppMoved,
	kUnknownEvent
};


enum EEventClass
{
	eGenericEventClass,
	ePlatformEventClass,
	eApplicationEventClass
};



/*********************************************************************\
*                                                                     *
*           TMCModifiers                                              *
*                                                                     *
\*********************************************************************/

/// Stores the status of special keys or mouse buttons
///
class TMCModifiers	
{
public:
	TMCModifiers();
	boolean operator==		(const TMCModifiers& rhs) const;
	boolean operator!=		(const TMCModifiers& rhs) const;
	void	Set				(boolean lbutton,boolean rbutton,boolean command,boolean shift,boolean alphaLock,boolean option,
							 boolean control,boolean autoKey);
	boolean ButtonDown		() const 		{ return fLeftButton;}
	boolean RightButtonDown	() const 		{ return fRightButton;}
	boolean CommandKeyDown	() const 		{ return fCommandKey;}
	boolean ShiftKeyDown	() const 		{ return fShiftKey;}
	boolean AlphaLocked		() const 		{ return fAlphaLock;}
	boolean OptionKeyDown	() const 		{ return fOptionKey;}
	boolean ControlKeyDown	() const 		{ return fControlKey;}
	boolean AutoKey			() const 		{ return fAutoKey;}
	void SetAutoKey			(boolean flag)	{ fAutoKey=flag; }
protected:
	boolean fLeftButton;
	boolean fRightButton;
	boolean fCommandKey;
	boolean fShiftKey;
	boolean fAlphaLock;
	boolean fOptionKey;
	boolean fControlKey;
	boolean fAutoKey;
	};

enum EAction
{
	kCanUndo			= true,
	kCantUndo			= false,
	kCausesChange		= true,
	kDoesNotCauseChange = false
};                                         


class TMCPlatformWindow;

enum EventUniqueness
{
	kNonUniqueEvent			= 0,
	kUniqueEventKeepFirst	= 1,
	kUniqueEventKeepLast	= 4
};


/*********************************************************************\
*                                                                     *
*           TMCEvent                                                  *
*                                                                     *
\*********************************************************************/

/// \addtogroup MCCore
/// \{

/// Something the application has to deal with
///
class TMCEvent 
{
public:

	uint32					fMessage;                                                                
	TMCPlatformWindow*		fWindow;
	boolean					fNeedPrepareMenus;                                          
	EMCEventPriority		fPriority;           
	EEventClass				fEventClass;                     
	EventUniqueness			fUnique;                     

							TMCEvent(uint32 message);
	virtual					~TMCEvent();
	
	virtual boolean			DeleteWhenCompleted();
	virtual boolean			ReadyToPost();
	virtual boolean			Recurring();
	virtual void			Process();
};

/// \}

class TMCPlatformEvent;
class TMCEventData;

typedef void (*EventDispatchProc)(TMCPlatformEvent& event,void* data);


/*********************************************************************\
*                                                                     *
*           TMCPlatformEvent                                          *
*                                                                     *
\*********************************************************************/

/// \addtogroup MCCore
/// \{

/// Reprents a mouse or keyboard event comming from the operating system
///
class TMCPlatformEvent : public TMCEvent
{
public:
							TMCPlatformEvent	();
							~TMCPlatformEvent	();
  

			boolean			ButtonDown			() const {return fModifiers.ButtonDown();}
			boolean			CommandKeyDown		() const {return fModifiers.CommandKeyDown();}
			boolean			ShiftKeyDown		() const {return fModifiers.ShiftKeyDown();}
			boolean			OptionKeyDown		() const {return fModifiers.OptionKeyDown();}
			boolean			ControlKeyDown		() const {return fModifiers.ControlKeyDown();}

			boolean			AutoKey				() const {return fModifiers.AutoKey();}
			boolean			AlphaLocked			() const {return fModifiers.AlphaLocked();}

	virtual void			Process				();         
	virtual boolean			RemoveDependenciesOnFree();
	
	//for the osx japanese version
	static void				SetUseTextInput		(boolean inUse);
	static boolean			GetUseTextInput		();

	int32					fWhen;
	TMCPoint				fLocalWhere;
	TMCPoint				fGlobalWhere;
	TMCModifiers			fModifiers;
	short					fChar;          
	short					fKey;                             
	short					fClickCount;                                      
	int32					fActionNumber;                                      
	TMCEventData*			fEventData;
	short					fMouseWheelDelta;

protected:
	uint16					HandleDoubleByte(void);

};

/// \}

//-------------------------------------------------------------
// inline functions
//-------------------------------------------------------------

inline TMCModifiers::TMCModifiers()	
{
	fLeftButton = false;
	fRightButton = false;
	fCommandKey = false;
	fShiftKey = false;
	fAlphaLock = false;
	fOptionKey = false;
	fControlKey = false;
	fAutoKey = false;
}
	
inline void TMCModifiers::Set(boolean lbutton,boolean rbutton,boolean command,boolean shift,boolean alphaLock,boolean option,
					boolean control,boolean autoKey)
{
	fLeftButton = lbutton;
	fRightButton = rbutton;
	fCommandKey = command;
	fShiftKey = shift;
	fAlphaLock = alphaLock;
	fOptionKey = option;
	fControlKey = control;
	fAutoKey = autoKey;
}

inline boolean TMCModifiers::operator==(const TMCModifiers& rhs) const
{
	return	fLeftButton		== rhs.fLeftButton &&
			fRightButton	== rhs.fRightButton &&
			fCommandKey		== rhs.fCommandKey &&
			fShiftKey		== rhs.fShiftKey &&
			fAlphaLock		== rhs.fAlphaLock &&
			fOptionKey		== rhs.fOptionKey &&
			fControlKey		== rhs.fControlKey &&
			fAutoKey		== rhs.fAutoKey;
}

inline boolean TMCModifiers::operator!=(const TMCModifiers& rhs) const
{
	return !(*this == rhs);
}


/*********************************************************************\
*                                                                     *
*           TMCTimer                                                  *
*                                                                     *
\*********************************************************************/

class TMCTimer;
typedef boolean (*TMCTimerProc)(TMCTimer* timer, void* priv);

/// Not available for extensions
///
class TMCTimer
{
public:
	TMCTimer					(uint32 ticks, TMCTimerProc proc, void* priv);
	~TMCTimer					();
	boolean Service				(uint32 time);
	uint32 GetTicks				() {return fTicks;}
	uint32 GetNextTick			() {return fNextTick;}

	static boolean HasTimers	();
	static void ServiceTimers	();

protected:
	uint32 fTicks;
	uint32 fNextTick;
	TMCTimerProc fProc;
	void* fPriv;
};

#endif