/*
	File:		SIHelper.h

	Contains:	Interface to an implementation of the ODCPlusSemanticInterface
				helper class.

	Owned by:	Nick Pilch

	Copyright:	© 1993-94 by Apple Computer, Inc., all rights reserved.

	Change History (most recent first):

		<14>	 1/16/95	eeh		1195186: remove GetUserToken etc.
		<13>	 1/13/95	NP		1191056-Change return signature for
									callback functions.
		<12>	  1/9/95	NP		1194880: SemtIntf name changes.
		<11>	11/15/94	NP		1200132-InitSIHelper should take pointer to
									base class, also new token utils added.
		<10>	10/28/94	SS		#1196346 - missing includes
		 <9>	10/13/94	NP		1189812: Changed UPP macros to specify
									pascal calling conventions.
		 <8>	 9/29/94	RA		1189812: Mods for 68K build.
		 <7>	  9/8/94	NP		API additions/changes.
		 <6>	 8/19/94	NP		1181622: Ownership fix.
		 <5>	 8/13/94	NP		1180819-Added param to InstallEventHandler
									and corresponding constants.
		 <4>	  7/5/94	NP		Tweaks to parameter lists and private
									fields.
		 <3>	  7/1/94	NP		Change to InitSIHelper and private fields.
		 <2>	 6/28/94	NP		Changed interface of InitSIHelper.
		 <1>	 6/24/94	NP		first checked in
		<24>	  5/5/94	eeh		bug #1153053, nativity (only now it runs)
		<23>	  4/4/94	T‚		#1154941: Get OpenDoc source to actually
									compile for PowerPC.  Fixed
									CallODTokenInquiryProc.
		<22>	  4/1/94	T‚		#1154941: Get OpenDoc source to actually
									compile for PowerPC.  Moved typedefs of
									UPPs to PlfmType.h where Platform Specific
									black box types belong.
		<21>	 3/26/94	NP		1153509. Messaging not PowerPC ready.
		<20>	 3/26/94	NP		1137665. Predispatch proc.
		<19>	 3/25/94	eeh		bug #1153053: goofed last time.
		<18>	 3/24/94	eeh		bug #1153053: Changes for PPC nativity (or
									is it nativeness...?)
		<17>	 3/15/94	MB		Changes to support SCpp/ASLM builds,
									#1150864.
		<16>	  2/9/94	NP		Tiger Team cleanup.
		<15>	  2/7/94	NP		Tiger Team doings.
		<14>	 1/14/94	NP		Init changes.
		<13>	11/30/93	NP		Added token inquiry proc.
		<12>	 11/5/93	NP		Removed CallObjectAccessor to
									ODNameResolver.
		<11>	10/22/93	NP		Added new private types for implementation.
		<10>	10/18/93	NP		InstallErrDescProc -> InstallGetErrDescProc
									and removed code name.
		 <9>	10/11/93	NP		Mods to keep in sync with SemtIntf.h. Added
									new private instance variables.
		 <8>	 9/20/93	NP		Moved some members around.
		 <7>	 8/19/93	NP		Added context field. Some moving of things.
		 <6>	 8/18/93	NP		Added OSLSupportFlags getters and setters.
		 <5>	  8/9/93	NP		Added class id string.
		 <4>	 7/28/93	NP		Added some temporary code.
		 <3>	 7/27/93	CG		Replaced the hash table
									fSpecialHandlerTable with fields in
									SemtIntf for each of the possible special
									handler proc ptrs.
		 <2>	 7/23/93	CG		Added Coercion handler dispatching.
		 <1>	  7/2/93	CG		first checked in

	To Do:
*/

#ifndef _SIHELPER_
#define _SIHELPER_


#ifndef _SIHLPABS_
#include "SIHlpAbs.h"
#endif

//ram#ifndef __MIXEDMODE__
//ram#include <MixedMode.h>
//ram#endif

#ifndef	__APPLEEVENTS__
#include "Applevnt.h"
#endif

#ifndef _ODOSATYP_
#include "odosatyp.h"
#endif

//==============================================================================
// Constants
//==============================================================================

#define kODStandardDispatch	0
#define kODAlwaysForward	1

//==============================================================================
// Functions
//==============================================================================
#if 0
ODDescType GetTokenDescType(ODOSLToken* token);
void SetTokenDescType(ODOSLToken* token, ODDescType type);
ODHandle GetTokenDataHandle(ODOSLToken* token);
void SetTokenDataHandle(ODOSLToken* token, ODHandle handle);
#endif /* 0 */

//==============================================================================
// Classes defined in this interface
//==============================================================================

class	SIHelper;
class	AEHashTable;

//==============================================================================
// Classes used by this interface
//==============================================================================

class	ODPart;
class	ODSemanticInterface;
struct	OSLContext;

//==============================================================================
// Callback function mixed-mode glue.
//==============================================================================

#ifndef GetCurrentArchitecture
	// The pre-68k universal headers use GetCurrentISA; the newer headers that
	// support CFM68k use GetCurrentArchitecture. This lets us compile either way:
	#define GetCurrentArchitecture() GetCurrentISA()
#endif

#if USESROUTINEDESCRIPTORS
typedef UniversalProcPtr ODEventHandlerUPP ;
typedef UniversalProcPtr ODDescCoercionHandlerUPP ;
typedef UniversalProcPtr ODPtrCoercionHandlerUPP ;
typedef UniversalProcPtr ODCoercionHandlerUPP;
typedef UniversalProcPtr ODObjectAccessorUPP;
typedef UniversalProcPtr ODCompareUPP;
typedef UniversalProcPtr ODCountUPP ;
typedef UniversalProcPtr ODDisposeTokenUPP ;
typedef UniversalProcPtr ODGetMarkTokenUPP ;
typedef UniversalProcPtr ODMarkUPP ;
typedef UniversalProcPtr ODAdjustMarksUPP ;
typedef UniversalProcPtr ODGetErrDescUPP ;
typedef UniversalProcPtr ODPreDispatchUPP ;
typedef UniversalProcPtr ODTokenInquiryUPP ;
typedef UniversalProcPtr ODSpecialHandlerUPP;
#else	/* if not USESROUTINEDESCRIPTORS */

typedef ODError (*ODEventHandlerProcPtr)(ODPart*		thePart,
											ODAppleEvent*	theODAppleEvent,
											ODAppleEvent*	reply,
											ODSLong	handlerRefcon);

typedef ODError (*ODCoercionHandler)();

typedef ODError (*ODDescCoercionHandler)(ODPart*		thePart,
											ODDesc*		theODDesc,
											ODDescType	toType,
											ODSLong	handlerRefCon,
											ODDesc*		result);

typedef ODError (*ODPtrCoercionHandler)(ODPart*		thePart,
											ODDescType	typeCode,
											ODPtr		dataPtr,
											ODSize		dataSize,
											ODDescType	toType,
											ODSLong	handlerRefCon,
											ODDesc*		result);

typedef ODError (*ODAccessorProcPtr)(ODPart*				thePart,
										ODDescType			desiredClass,
										ODOSLToken*		container,
										ODDescType			containerClass,
										ODDescType			form,
										ODDesc*				selectionData,
										ODOSLToken*		value,
										ODSLong			handlerRefCon);

typedef ODError (*ODCompareProcPtr)(ODPart*				thePart,
										ODDescType			oper,
										ODOSLToken*		obj1,
										ODOSLToken*		obj2,
										ODBoolean*			result,
										ODSLong			refCon);

typedef ODError (*ODCountProcPtr)(ODPart*			thePart,
									ODDescType			desiredType,
									ODDescType			containerClass,
									ODOSLToken*		container,
									ODSLong*			result,
									ODSLong			refCon);

typedef ODError (*ODDisposeTokenProcPtr)(ODPart*			thePart,
											ODOSLToken*	unneededToken,
											ODSLong		refCon);

typedef ODError (*ODGetErrDescProcPtr)(ODPart*		thePart,
											ODDesc**	errDesc,
											ODSLong	refCon);

typedef ODError (*ODGetMarkTokenProcPtr)(ODPart*				thePart,
											ODOSLToken*		dContainerToken,
											ODDescType			containerClass,
											ODOSLToken*		result,
											ODSLong			refCon);

typedef ODError (*ODMarkProcPtr)(ODPart*				thePart,
									ODOSLToken*		dToken,
									ODOSLToken*		markToken,
									ODSLong			index,
									ODSLong			refCon);

typedef ODError (*ODAdjustMarksProcPtr)(ODPart*				thePart,
											ODSLong			newStart,
											ODSLong			newStop,
											ODOSLToken*		markToken,
											ODSLong			refCon);

typedef ODError (*ODPreDispatchProcPtr)(ODPart*		thePart,
												ODAppleEvent*	theODAppleEvent,
												ODAppleEvent*	reply,
												ODSLong	handlerRefcon);

typedef ODError (*ODSpecialHandlerPtr)();

typedef ODPart* (*ODTokenInquiryProcPtr)(ODOSLToken*	token,
											ODSLong		refCon);

typedef ODEventHandlerProcPtr ODEventHandlerUPP ;
typedef ODDescCoercionHandler ODDescCoercionHandlerUPP ;
typedef ODPtrCoercionHandler ODPtrCoercionHandlerUPP ;
typedef ODCoercionHandler ODCoercionHandlerUPP;
typedef ODAccessorProcPtr ODObjectAccessorUPP ;
typedef ODCompareProcPtr ODCompareUPP;
typedef ODCountProcPtr ODCountUPP ;
typedef ODGetMarkTokenProcPtr ODGetMarkTokenUPP ;
typedef ODMarkProcPtr ODMarkUPP ;
typedef ODAdjustMarksProcPtr ODAdjustMarksUPP ;
typedef ODDisposeTokenProcPtr ODDisposeTokenUPP ;
typedef ODGetErrDescProcPtr ODGetErrDescUPP ;
typedef ODPreDispatchProcPtr ODPreDispatchUPP ;
typedef ODTokenInquiryProcPtr ODTokenInquiryUPP ;
typedef ODSpecialHandlerPtr ODSpecialHandlerUPP ;
typedef ODCoercionHandler ODCoercionHandlerUPP ;
#endif		/* USESROUTINEDESCRIPTORS */

#if USESROUTINEDESCRIPTORS
enum {
	uppODEventHandlerProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODAppleEvent*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODAppleEvent*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODDescCoercionHandlerProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDesc*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODSLong)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODDesc*)))
};

enum {
	uppODPtrCoercionHandlerProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(long)))
		 | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(ODDesc*)))
};

enum {
	uppODObjectAccessorProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODDesc*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(ODDesc*)))
		 | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(8, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODCompareProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODBoolean*)))
		 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODCountProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODSLong*)))
		 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODDisposeTokenProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODGetMarkTokenProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODDescType)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODGetErrDescProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODDesc**)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODMarkProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODSLong)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODAdjustMarksProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODSLong)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODSLong)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODPreDispatchProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODError)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODAppleEvent*)))
		 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ODAppleEvent*)))
		 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ODSLong)))
};

enum {
	uppODTokenInquiryProcInfo = kPascalStackBased
		 | RESULT_SIZE(SIZE_CODE(sizeof(ODPart*)))
		 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ODOSLToken*)))
		 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ODSLong)))
};

#define CallODEventHandlerProc(userRoutine, thePart, theODAppleEvent, reply, handlerRefcon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODEventHandlerProcInfo, (thePart), (theODAppleEvent), (reply), (handlerRefcon))
#define NewODEventHandlerProc( theHandlerProc )								\
	(ODEventHandlerUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODEventHandlerProcInfo, GetCurrentArchitecture() )

#define CallODDescCoercionHandlerProc(userRoutine, thePart, theODDesc, toType, handlerRefCon, result)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODDescCoercionHandlerProcInfo, (thePart), (theODDesc), (toType), (handlerRefCon), (result))
#define NewODDescCoercionHandlerProc( theHandlerProc )							\
	(ODDescCoercionHandlerUPP) NewRoutineDescriptor(						\
			(ProcPtr)(theHandlerProc),										\
			uppODDescCoercionHandlerProcInfo, GetCurrentArchitecture() )

#define CallODPtrCoercionHandlerProc(userRoutine, thePart, typeCode, dataPtr, dataSize, toType, handlerRefCon, result)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODPtrCoercionHandlerProcInfo, (thePart), (typeCode), (dataPtr), (dataSize), (toType), (handlerRefCon), (result))
#define NewODPtrCoercionHandlerProc( theHandlerProc )							\
	(ODPtrCoercionHandlerUPP) NewRoutineDescriptor(						\
			(ProcPtr)(theHandlerProc),										\
			uppODPtrCoercionHandlerProcInfo, GetCurrentArchitecture() )


#define CallODObjectAccessorProc(userRoutine, thePart, desiredClass, container, containerClass, form, selectionData, value, handlerRefCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODObjectAccessorProcInfo, (thePart), (desiredClass), (container), (containerClass), (form), (selectionData), (value), (handlerRefCon))
#define NewODObjectAccessorProc( theAccessorProc )								\
	(ODObjectAccessorUPP) NewRoutineDescriptor( (ProcPtr)(theAccessorProc),\
			uppODObjectAccessorProcInfo, GetCurrentArchitecture() )

#define CallODCompareProc(userRoutine, thePart, oper, obj1, obj2, result, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODCompareProcInfo, (thePart), (oper), (obj1), (obj2), (result), (refCon))
#define NewODCompareProc( theHandlerProc )										\
	(ODCompareUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),		\
			uppODCompareProcInfo, GetCurrentArchitecture() )

#define CallODCountProc(userRoutine, thePart, desiredType, containerClass, container, result, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODCountProcInfo, (thePart), (desiredType), (containerClass), (container), (result), (refCon))
#define NewODCountProc( theHandlerProc )										\
	(ODCountUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),			\
			uppODCountProcInfo, GetCurrentArchitecture() )

#define CallODDisposeTokenProc(userRoutine, thePart, unneededToken, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODDisposeTokenProcInfo, (thePart), (unneededToken), (refCon))
#define NewODDisposeTokenProc( theHandlerProc )								\
	(ODDisposeTokenUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODDisposeTokenProcInfo, GetCurrentArchitecture() )

#define CallODGetMarkTokenProc(userRoutine, thePart, dContainerToken, containerClass, result, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODGetMarkTokenProcInfo, (thePart), (dContainerToken), (containerClass), (result), (refCon))
#define NewODGetMarkTokenProc( theHandlerProc )								\
	(ODGetMarkTokenUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODGetMarkTokenProcInfo, GetCurrentArchitecture() )

#define CallODMarkProc(userRoutine, thePart, dToken, markToken, index, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODMarkProcInfo, (thePart), (dToken), (markToken), (index), (refCon))
#define NewODMarkProc( theHandlerProc )										\
	(ODMarkUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),			\
			uppODMarkProcInfo, GetCurrentArchitecture() )

#define CallODAdjustMarksProc(userRoutine, thePart, newStart, newStop, markToken, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODAdjustMarksProcInfo, (thePart), (newStart), (newStop), (markToken), (refCon))
#define NewODAdjustMarksProc( theHandlerProc )									\
	(ODAdjustMarksUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODAdjustMarksProcInfo, GetCurrentArchitecture() )

#define CallODGetErrDescProc(userRoutine, thePart, errDesc, refCon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODGetErrDescProcInfo, (thePart), (errDesc), (refCon))
#define NewODGetErrDescProc( theHandlerProc )									\
	(ODGetErrDescUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODGetErrDescProcInfo, GetCurrentArchitecture() )

#define CallODPreDispatchProc(userRoutine, thePart, theODAppleEvent, reply, handlerRefcon)		\
		CallUniversalProc((UniversalProcPtr)(userRoutine), uppODPreDispatchProcInfo, (thePart), (theODAppleEvent), (reply), (handlerRefcon))
#define NewODPreDispatchProc( theHandlerProc )								\
	(ODPreDispatchUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODPreDispatchProcInfo, GetCurrentArchitecture() )

#define CallODTokenInquiryProc(userRoutine, token, refCon)		\
		(ODPart*)CallUniversalProc((UniversalProcPtr)(userRoutine), uppODTokenInquiryProcInfo, (token), (refCon))
#define NewODTokenInquiryProc( theHandlerProc )								\
	(ODTokenInquiryUPP) NewRoutineDescriptor( (ProcPtr)(theHandlerProc),	\
			uppODTokenInquiryProcInfo, GetCurrentArchitecture() )

#else	/* if not USESROUTINEDESCRIPTORS */

#define CallODEventHandlerProc(userRoutine, thePart, theODAppleEvent, reply, handlerRefcon)		\
		(*(userRoutine))((thePart), (theODAppleEvent), (reply), (handlerRefcon))
#define NewODEventHandlerProc(theHandlerProc)									\
		(ODEventHandlerUPP)(theHandlerProc)

#define CallODObjectAccessorProc(userRoutine, thePart, desiredClass, container, containerClass, form, selectionData, value, handlerRefCon)		\
		(*(userRoutine))((thePart), (desiredClass), (container), (containerClass), (form), (selectionData), (value), (handlerRefCon))
#define NewODObjectAccessorProc(theAccessorProc)								\
		(ODObjectAccessorUPP)(theAccessorProc)

#define CallODCompareProc(userRoutine, thePart, oper, obj1, obj2, result, refCon)		\
		(*(userRoutine))((thePart), (oper), (obj1), (obj2), (result), (refCon))
#define NewODCompareProc(theAccessorProc)										\
		(ODCompareUPP)(theAccessorProc)

#define CallODCountProc(userRoutine, thePart, desiredType, containerClass, container, result, refCon)		\
		(*(userRoutine))((thePart), (desiredType), (containerClass), (container), (result), (refCon))
#define NewODCountProc(theAccessorProc)										\
		(ODCountUPP)(theAccessorProc)

#define CallODGetMarkTokenProc(userRoutine, thePart, dContainerToken, containerClass, result, refCon)		\
		(*(userRoutine))((thePart), (dContainerToken), (containerClass), (result), (refCon))
#define NewODGetMarkTokenProc(theAccessorProc)									\
		(ODGetMarkTokenUPP)(theAccessorProc)

#define CallODMarkProc(userRoutine, thePart, dToken, markToken, index, refCon)		\
		(*(userRoutine))((thePart), (dToken), (markToken), (index), (refCon))
#define NewODMarkProc(theAccessorProc)											\
		(ODMarkUPP)(theAccessorProc)

#define CallODAdjustMarksProc(userRoutine, thePart, newStart, newStop, markToken, refCon)		\
		(*(userRoutine))((thePart), (newStart), (newStop), (markToken), (refCon))
#define NewODAdjustMarksProc(theAccessorProc)									\
		(ODAdjustMarksUPP)(theAccessorProc)

#define CallODDisposeTokenProc(userRoutine, thePart, unneededToken, refCon)		\
		(*(userRoutine))((thePart), (unneededToken), (refCon))
#define NewODDisposeTokenProc(theAccessorProc)									\
		(ODDisposeTokenUPP)(theAccessorProc)

#define CallODGetErrDescProc(userRoutine, thePart, errDesc, refCon)		\
		(*(userRoutine))((thePart), (errDesc), (refCon))
#define NewODGetErrDescProc(theAccessorProc)									\
		(ODGetErrDescUPP)(theAccessorProc)

#define CallODPreDispatchProc(userRoutine, thePart, theODAppleEvent, reply, handlerRefcon)		\
		(*(userRoutine))((thePart), (theODAppleEvent), (reply), (handlerRefcon))
#define NewODPreDispatchProc(theHandlerProc)									\
		(ODEventHandlerUPP)(theHandlerProc)

#define CallODTokenInquiryProc(userRoutine, token, refCon)		\
		(*(userRoutine))((token), (refCon))
#define NewODTokenInquiryProc(theAccessorProc)									\
		(ODTokenInquiryUPP)(theAccessorProc)


#define CallODDescCoercionHandlerProc(userRoutine, thePart, theODDesc, toType, handlerRefCon, result)		\
		(*(userRoutine))((thePart), (theODDesc), (toType), (handlerRefCon), (result))
#define NewODDescCoercionHandlerProc( theHandlerProc )							\
		(ODCoercionHandlerUPP)(theHandlerProc)
#define CallODPtrCoercionHandlerProc(userRoutine, thePart, typeCode, dataPtr, dataSize, toType, handlerRefCon, result)		\
		(*(userRoutine))((thePart), (typeCode), (dataPtr), (dataSize), (toType), (handlerRefCon), (result))
#define NewODPtrCoercionHandlerProc( theHandlerProc )							\
		(ODCoercionHandlerUPP)(theHandlerProc)


#endif		/* USESROUTINEDESCRIPTORS */


//==============================================================================
// SIHelper
//==============================================================================

#define ODNVMethod 

class ODExport SIHelper : public SIHelperAbs
{
  public:

	SIHelper();
	ODVMethod ~SIHelper();
	ODNVMethod void InitSIHelper(ODSemanticInterface* helpee);

	// SIHelpAbs overrides
		
	ODVMethod ODError   CallEventHandler(
			ODPart* thePart,
			ODAppleEvent* theODAppleEvent,
			ODAppleEvent* reply);
	ODVMethod ODError   CallPredispatchProc(
			ODPart* thePart,
			ODAppleEvent* theODAppleEvent,
			ODAppleEvent* reply);
	ODVMethod ODError   CallCoercionHandler(
			ODPart* thePart,
			ODDesc* theODDesc,
			ODDescType toType,
			ODDesc* result);
	ODVMethod ODError   CallObjectAccessor(
			ODPart* thePart,
			ODDescType desiredClass,
			ODOSLToken* container,
			ODDescType containerClass,
			ODDescType form,
			ODDesc* selectionData,
			ODOSLToken* value);
	ODVMethod ODError   CallCompareProc(
		ODPart* thePart,
		ODDescType oper,
		ODOSLToken* obj1,
		ODOSLToken* obj2,
		ODBoolean* result);
	ODVMethod ODError   CallCountProc(
		ODPart* thePart,
		ODDescType desiredType,
		ODDescType containerClass,
		ODOSLToken* container,
		ODSLong* result);
	ODVMethod ODError   CallDisposeTokenProc(
		ODPart* thePart,
		ODOSLToken* unneededToken);
	ODVMethod ODError   CallGetErrDescProc(
		ODPart* thePart,
		ODDesc** errDesc);
	ODVMethod ODError   CallGetMarkTokenProc(
		ODPart* thePart,
		ODOSLToken* dContainerToken,
		ODDescType containerClass,
		ODOSLToken* result);
	ODVMethod ODError   CallMarkProc(
		ODPart* thePart,
		ODOSLToken* dToken,
		ODOSLToken* markToken,
		ODSLong index);
	ODVMethod ODError   CallAdjustMarksProc(
		ODPart* thePart,
		ODSLong newStart,
		ODSLong newStop,
		ODOSLToken* markToken);
	ODVMethod ODPart*	CallTokenInquiryProc(ODOSLToken*	token);

	// Object accessor management
		
	ODVMethod void		InstallObjectAccessor(ODDescType				desiredClass,
												ODDescType			containerType,
												ODObjectAccessorUPP	theAccessor,
												ODSLong			accessorRefcon);

	ODVMethod void		GetObjectAccessor(ODDescType				desiredClass,
										   ODDescType				containerType,
										   ODObjectAccessorUPP*	theAccessor,		// return parameter
										   ODSLong*			accessorRefcon);	// return parameter

	ODVMethod void			RemoveObjectAccessor(ODDescType			desiredClass,
											  ODDescType				containerType,
											  ODObjectAccessorUPP		theAccessor);

	// Special proc management

	ODVMethod void InstallCompareProc(ODCompareUPP	compareProc,
											ODSLong		refCon);

	ODVMethod void InstallCountProc(ODCountUPP	countProc,
											ODSLong	refCon);

	ODVMethod void InstallDisposeTokenProc(ODDisposeTokenUPP	disposeTokenProc,
											ODSLong					refCon);

	ODVMethod void InstallGetMarkTokenProc(ODGetMarkTokenUPP	getMarkTokenProc,
												ODSLong				refCon);

	ODVMethod void InstallMarkProc(ODMarkUPP	markProc,
											ODSLong	refCon);

	ODVMethod void InstallAdjustMarksProc(ODAdjustMarksUPP	adjustMarksProc,
											ODSLong				refCon);

	ODVMethod void InstallGetErrDescProc(ODGetErrDescUPP	errorDescProc,
											ODSLong			refCon);

	ODVMethod void InstallTokenInquiryProc(ODTokenInquiryUPP	tokenInquiryProc,
											ODSLong			refCon);

	// Event handler management

	ODVMethod void	InstallEventHandler(	ODEventClass			theAEEventClass,
											ODEventID				theAEEventID,
											ODEventHandlerUPP		handler,
											ODSLong					handlerRefcon);
	
	ODVMethod void	RemoveEventHandler(ODEventClass					theAEEventClass,
										  ODEventID					theAEEventID,
										  ODEventHandlerUPP	handler);
	
	ODVMethod void	GetEventHandler(ODEventClass				theAEEventClass,
									   ODEventID				theAEEventID,
									   ODEventHandlerUPP*		handler,
									   ODSLong*				handlerRefcon);
	
	ODVMethod void	InstallCoercionHandler(ODDescType					fromType,
											  ODDescType				toType,
											  ODCoercionHandlerUPP	handler,
											  ODSLong				handlerRefcon,
											  ODBoolean			fromTypeIsDesc);
	
	ODVMethod void	RemoveCoercionHandler(ODDescType				fromType,
											 ODDescType			toType,
											 ODCoercionHandlerUPP	handler);
	
	ODVMethod void	GetCoercionHandler(ODDescType					fromType,
										  ODDescType				toType,
										  ODCoercionHandlerUPP*	handler,
										  ODSLong*				handlerRefcon,
										  ODBoolean*			fromTypeIsDesc);
	
	ODVMethod void	InstallSpecialHandler(AEKeyword					functionClass,
												ODSpecialHandlerUPP	handler,
												ODSLong				refCon);
	
	ODVMethod void	RemoveSpecialHandler(AEKeyword					functionClass,
												ODSpecialHandlerUPP	handler);
	
	ODVMethod void	GetSpecialHandler(AEKeyword					functionClass,
											ODSpecialHandlerUPP*	handler,
											ODSLong*				refCon);

//	ODVMethod void		SetOSLSupportFlags(short flags);

//	ODVMethod short	GetOSLSupportFlags();

  private: // Private by convention

	ODBoolean	LookupEventHandler(ODEventClass				eventClass,
								   ODEventID				eventID,
								   ODEventHandlerUPP*		handler,
								   ODSLong*				handlerRefcon);

	ODBoolean	LookupCoercionHandler(ODDescType				fromType,
									   ODDescType				toType,
									   ODCoercionHandlerUPP*	handler,
									   ODSLong*			handlerRefcon,
									   ODBoolean*			fromTypeIsDesc);

	ODBoolean	LookupObjectAccessor(ODDescType				desiredClass,
									   ODDescType				containerType,
									   ODObjectAccessorUPP*	theAccessor,
									   ODSLong*			accessorRefcon);

//	OSLContext*	GetOSLContext();

  private:

	void		ThrowProcNotFound(AEHashTable* table);
	void		AddToTable(ODDescType key1, ODDescType key2, UniversalProcPtr handler,
								ODSLong handlerRefCon,
								ODBoolean fromTypeIsDesc,
								AEHashTable* table);
	void		RetrieveFromTable(ODDescType key1, ODDescType key2,
											UniversalProcPtr* handler,
											ODSLong* handlerRefCon,
											ODBoolean* fromTypeIsDesc,
											AEHashTable* table);
	void		RemoveFromTable(ODDescType key1, ODDescType key2, UniversalProcPtr handler,
									AEHashTable* table);
	ODBoolean	HandlerLookup(
								ODDescType		key1,
								ODDescType		key2,
								AEHashTable*	theAEHashTable,
							  	void*			theValue);

	ODSemanticInterface*	fSemanticInterface;

	AEHashTable*	fEventHandlerTable;
	AEHashTable*	fObjectAccessorTable;
	AEHashTable*	fCoercionHandlerTable;

		// Special Handler procs	
	ODCountUPP 			fCountProcPtr;
	ODSLong		 		fCountProcPtrRefCon;
	ODCompareUPP		fCompareProcPtr;
	ODSLong		 		fCompareProcPtrRefCon;
	ODDisposeTokenUPP 	fDisposeTokenProcPtr;
	ODSLong		 		fDisposeTokenProcPtrRefCon;
	ODGetErrDescUPP		fErrDescProcPtr;
	ODSLong		 		fErrDescProcPtrRefCon;
	ODGetMarkTokenUPP 	fGetMarkTokenProcPtr;
	ODSLong		 		fGetMarkTokenProcPtrRefCon;
	ODMarkUPP 			fMarkProcPtr;
	ODSLong		 		fMarkProcPtrRefCon;
	ODAdjustMarksUPP 	fAdjustMarksProcPtr;
	ODSLong		 		fAdjustMarksProcPtrRefCon;
	ODPreDispatchUPP 	fPreDispatchProcPtr;
	ODSLong		 		fPreDispatchProcPtrRefCon;

	ODTokenInquiryUPP 	fTokenInquiryProc;
	ODSLong		 		fTokenInquiryProcRefCon;

	short				fOSLSupportFlags;
};


#endif /* _SIHELPER_ */
