/*

	FGL Extension Interface header file

*/

#if !defined ( __fglExtension_h__ )
#define __fglExtension_h__

#include "windows.h"
#include "fglTypes.h"

#define FGLE_VERSION_MINOR	0
#define FGLE_VERSION_MAJOR	1

#define FGLE_VERSION  MAKELONG( FGLE_VERSION_MINOR, FGLE_VERSION_MAJOR )

typedef struct FGL_EXTENSION_VERSION {
	unsigned long		version;
	char				name[MAX_PATH + 1];
} FGL_EXTENSION_VERSION;

typedef struct FGL_EXTENSION_FUNC_TABLE {
	//  object memory interface functions
	void *		(*omAlloc)				( unsigned int    size  );
	char *		(*omStrDup)				( const char	 *str	);
	GRIP		(*omGetGrip)			( VAR           **var   );
	GRIP *		(*omGetGripArray)		( unsigned int    count );
	int			(*omFreeGrip)			( GRIP            grip  );
	int			(*omFreeGripArray)		( GRIP           *array );
	int			(*omLockPage)			( void           *ptr   );
	int			(*omUnlockPage)			( void           *ptr   );
	void		(*omCollectionDisable)	( void );
	void		(*omCollectionEnable)	( void );

	//  array interface functions
	VAR	*		(*arrayGet)				( VAR  *array, int numIndicies, int *indicieArray );
	int			(*arrayIsElem)			( VAR  *array, int numIndicies, int *indicieArray );
	VAR	*		(*arrayNew)				( void               );

	//  fgl class registration functions
	int			(*classCreate )			( char *className, char *loadSource );
	int			(*classMethod)			( char *className, char *method, char access, long (_cdecl  *func)(void), char *params );
	int			(*classMethodDefParam)	( char *className, char *method, int nParam, char *expr );
	int			(*classAccessor)		( char *className, char *method, char access, long (_cdecl  *func)(void), char *params, char type );
	int			(*classAccessDefParam)  ( char *className, char *method, int nParam, int type, char *expr );
	int			(*classOperator)		( char *className, char *method, char access, long (_cdecl  *func)(void), char *params, char associative );
	int			(*classInstance)		( char *className, char *varName, char access );
	int			(*classInstanceX)		( char *className, char *varName, char access, char *expr );
	int			(*classConstant)		( char *className, char *constName, char *expr, char access );
	int			(*classInherit)			( char *className, char *class2,  char access,	 char isVirtual );
	int			(*classDirect)			( char *className, char *message, char *class2,  char *message2, char access );
	int			(*classStatic)			( char *className, char *varName, char access );
	int			(*classStaticX)			( char *className, char *varName, char access, char *expr );
	int			(*classRegisterGcCb)	( char *className, void (*cGarbageCollectionCB)(struct OBJ_MEM *om, VAR *var, void (*omMove)(struct OBJ_MEM *om, VAR *val) ) );
	int			(*classRegisterPackCB)	( char *className, void (*cPackCB)(VAR *val, BUFFER *buff, void *param, int (*pack)(VAR *val, void *param) ), int (*cUnPackCB) ( VAR *obj, char **buff, unsigned int *len, void *param, VAR *(*unPack)( char **buff, unsigned int *len, void *param ) ) );
	int			(*classFinalize)		( char *className );

	//  fgl class operational functions
	int         (*classNew)				( char *className, int nParams );
	int			(*classGetName)			( VAR *var );
	int			(*classGetElements)		( VAR *var );
	VAR *		(*classLocalAccess)		( VAR *obj, char *message );
	int			(*classLocalAssign)		( VAR *obj, char *message, GRIP val );
	void 		(*classAllocateCargo)	( VAR *var, unsigned int len );
	void *		(*classGetCargo)		( VAR *var );

	//  library unctions
	int			(*libraryLoad)			( char *id );
	int			(*libraryUnload)		( char *fName );
	int			(*isLibrayLoaded)		( char *fName );

	//  error routines
	int			(*throwError)			( int errorNum );
	int			(*throwErrorX)			( int errorNum, char *errorDesc );
	char *		(*errorAsText)			( int errorNum );
	int			(*getCurrentError)		( void );

	//	function interface
	int			(*funcRegister)			( long (__cdecl *funcPtr)( void ), char *name, char *params );
	int			(*funcDispatch)			( char *name, unsigned nParams );
	int			(*pCount)				( void );
	VAR	*		(*param)				( int num );
	VAR *		(*retVal)				( void );

	// resource routines
	int			(*resourceRegister)		( void *resource, int (*freeResource)(void *resource) );
	int			(*resourceFree)			( void *resource, int (*freeResource)(void *resource) );

	//  codeblock routines
	int         (*callCodeBlock)		( VAR *val, int doFixup );
	int			(*compileCodeblock)		( char *string );

	//  workarea support routines		
	int			(*allocateWorkarea)		( void *db, struct FGL_DATBASE_FUNC_TABLE *funcTable, char *alias );
} FGL_EXTENSION_FUNC_TABLE;

extern FGL_EXTENSION_FUNC_TABLE *fglFuncTable;

#define FGL_EXTENSION_REGISTER(fglExtensionName,func)\
extern "C" {\
FGL_EXTENSION_FUNC_TABLE *fglFuncTable;\
_declspec(dllexport) BOOL _cdecl fglExtensionInit ( FGL_EXTENSION_VERSION *ver )\
{\
	strncpy ( ver->name, (fglExtensionName), sizeof ( ver->name ) );\
	ver->version = MAKELONG ( FGLE_VERSION_MINOR, FGLE_VERSION_MAJOR );\
	return ( 1 );\
}\
__declspec(dllexport) BOOL _cdecl fglThreadInit ( FGL_EXTENSION_FUNC_TABLE *funcTable )\
{\
	fglFuncTable = funcTable;\
	(func)();\
	return ( 1 );\
}\
}

#if !defined (classMethod)
// API macro's

//
//	omAlloc
//
//	int	size		- amount of memory to allocate in object memory
//
//	returns:
//		void	*		- pointer to allocated memory
//
//
//	Description:
//
//		omAlloc is used to allocate a chunk of memory in the object memory pool.  This memory is volatile
//	and can become invlaid at any time unless it is reachable in some way by the object memory manager.
//
//	THIS FUNCTION CAN CAUSE GARBAGE COLLECTION TO OCCUR
//
#define omAlloc(size)												((fglFuncTable->omAlloc)(size))

//
//	omStrDup
//
//	char	*string		- string to duplicate into object memory
//
//	returns:
//		char	*		- new string
//
//
//	Description:
//
//		omStrDup will duplicate the parameter str into object memory.  The returned pointer is volatile
//	and can become invalid unless it is reachable in some way
//
//
//	THIS FUNCTION CAN CAUSE GARBAGE COLLECTION TO OCCUR
//
#define omStrDup(str)												((fglFuncTable->omStrDup)(str))

//
//	omGetGrip
//
//	VAR		**var		- variable to get a grip on
//
//	returns:
//		GRIP			- the newly returned grip
//
//
//	Description:
//
//		omGetGrip will allocate a grip.  This creates a reference to VAR so that it will be collected in the event 
//	a garbage collection occurs.
//
//		If <var> is NULL the grip returned can be utilized as a VAR structure.  If <var> is non null,
//	*<var> will be updated to point to the new location should any garbage collections occur in the future.
//
//		In general grips should be treated as transient's.  You should create them as needed during the processing
//	of a function call and release them when done.  If grips are going to be held longer then the life of a function
//  call then a resource should be registered to allow the grip to be reclaimed upon termination of the currently running
//  page.
//
//
#define omGetGrip(var)												((fglFuncTable->omGetGrip)(var))

//
//	omGetGripArray
//
//	int		count		- number of grips to allocate
//
//	returns:
//		GRIP			- the newly returned grip
//
//
//	Description:
//
//		omGetGripArray returns an array of GRIP's (VAR *) that are linked into the Object Memory system and will
//  subsequently be collected should any garbage collection occur.  Allocating an array of GRIPS is more efficient 
//  then allocating a large number of individual grips.
//
//
#define omGetGripArray(count)										((fglFuncTable->omGetGripArray)(count))

//
//	omFreeGrip
//
//	GRIP	grip		- grip to free
//
//	returns:
//
//
//	Description:
//	  omFreeGrip deallocates the grip previously allocated with the omGetGrip() function.
//
//
#define omFreeGrip(grip)											((fglFuncTable->omFreeGrip)(grip))

//
//	omFreeGripArray
//
//	GRIP	*gripArray	- array of grips to free
//
//	returns:
//
//
//	Description:
//	  omFreeGrip deallocates the grip array previously allocated with the omGetGripArray() function.
//
//
#define omFreeGripArray(array)										((fglFuncTable->omFreeGripArray)(array))

//
//	omLockPage
//
//	void	*ptr		- pointer
//
//	returns:
//
//
//	Description:
//		The omLockPage function ensures that a pointer remains valid irregardless of collection.  Should
//	a collection occur and <ptr> be a valid pointer with the object memory pool, the page contiaing <ptr>
//	WILL be garbage collected.  HOWEVER, the page will NOT be freed (returned to the free pool) until
//  all outstanding page locks are unlocked.
//
//		This function is used primarily on character arrays.  Should a function be passed a string pointer 
//	which and not a full VAR structure then either a VAR structure would have to be created to handle the 
//	string or a lock be placed on the page creating the <ptr>.
//		
//		omLockPage increases a reference count on the page.  The page will not be released until the 
//	reference count becomes zero.
//
#define omLockPage(ptr)												((fglFuncTable->omLockPage)(ptr))

//
//	omUnlockPage
//
//	void	*ptr		- pointer
//
//	returns:
//
//
//	Description:
//		omUnlckPage decreases the reference count on the page.  The page will be released when the 
//	reference count becomes zero.
//
#define omUnlockPage(ptr)											((fglFuncTable->omUnlockPage)(ptr))

//
//	omCollectionDisable
//
//	void	*ptr		- pointer
//
//	returns:
//
//
//	Description:
//		Disables the garbage collector from running.  USE SPARINGLY.
//
//
//
#define omCollectionDisable()										((fglFuncTable->omCollectionDisable)())

//
//	omCollectionEnable()
//
//	void	*ptr		- pointer
//
//	returns:
//
//
//	Description:
//		Enables the garbage collector.
//
//
#define omCollectionEnable()										((fglFuncTable->omCollectionEnable)())

//
//	arrayNew()
//
//	void	
//
//	returns:	
//		newly allocated array structure in retVal
//
//
//	Description:
//		Allocates a new 0-element variable length array
//
//
#define arrayNew()													((fglFuncTable->arrayNew)())

//
//	arrayGet()
//
//	VAR		*array			-	array to get the element of
//	int		 numIndicies	-	the number of indicies to traverse
//	int		*indicieArray	-	an array of ints holding the indicie 
//
//	returns:	
//		A pointer to the element
//
//	Description:
//		the arrayGet() routine allows for easy access to an element of an array.  If the element was never
//	before accesed, a NULL element will be created.  This routine allocates object memory and can cause
//	garbage collection to occur
//
//
#define arrayGet(array, numIndicies, indicieArray)					((fglFuncTable->arrayGet)((array),(numIndicies),(indicieArray)))

//
//	arrayIsElem()
//
//	VAR		*array			-	array to get the element of
//	int		 numIndicies	-	the number of indicies to traverse
//	int		*indicieArray	-	an array of ints holding the indicie 
//
//	returns:	
//		1 - if the element is present (even if NULL), 
//		0 - if the element is not present
//
//	Description:
//		The arrayIsElem() routine returns the presence of an elemnt in an array.  This is usefull for traversing
//	sporadic arrays.
//
//
#define arrayIsElem(arrray, numIndicies, indicieArray)				((fglFuncTable->arrayIsElem)((array),(numIndicies),(indicieArray)))

//
//	classCreate()
//
//	char	*className		-	name of class to create
//	char	*loadSource		-	name of entity declaring the class
//
//	returns:	
//		1	- if class is sucessfully created
//		0	- failure
//
//	Description:
//		The classCreate function creates a class with the name className.  You can then use the other class functions 
//	(classMethod, etc.) to add functionality to the class.  When you have added all class elements it is necessary to
//	call classFinalize() to make the class useable by the engine.
//
//
#define classCreate(className,loadSource)							((fglFuncTable->classCreate)((className), (loadSource)))

//
//	classMethod()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	long (_cdecl  *func)(void)	-	pointer to C function called upon method invocation
//	char	*params				-	string containing parameter information
//
//	returns:	
//		1	- if method is sucessfully created
//		0	- failure
//
//	Description:
//		The classMethod() function registers a C function as an invokable FGL class method.  The parameters to the C
//	function are processed according to the <*parameters> function.
//
//		NOTE: special functions function exactly as they would be if declared in FGL (e.g. default, new, release, etc.)
//
//
#define classMethod(className, method, access, func, params)		((fglFuncTable->classMethod)((className), (method), (access), (long (_cdecl  *)(void))(func), (params)))

//
//	classMethodDefParam()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 nParam				-	number of the parameter to set default
//	char	*expr				-	FGL expression
//
//	returns:	
//		1	- if default paramter is sucessfully created
//		0	- failure
//
//	Description:
//		The classMethodDefParam function assigns a default value to a specific parameter.  If this parameter is not
//	passed to the method, the <expr> will be evaluated and the result pass into the method.  The <expr> may NOT access
//	variables, however function calls are allowed.
//
//
#define classMethodDefParam(className, method, nParam, expr)		((fglFuncTable->classMethodDefParam)((className), (method), (nParam), (expr)))

//
//	classAccess()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	long (_cdecl  *func)(void)	-	pointer to C function called upon method invocation
//	char	*params				-	string containing parameter information
//
//	returns:	
//		1	- if access method is sucessfully created
//		0	- failure
//
//	Description:
//		The classAccess() function registers a C function as an invokable FGL class access method.  The parameters to the C
//	function are processed according to the <*parameters> function.
//
//
#define classAccess(className, method, access, func, params)		((fglFuncTable->classAccessor)((className), (method), (access), (long (_cdecl  *)(void))(func), (params), 0))

//
//	classAccessDefParam()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 nParam				-	number of the parameter to set default
//	char	*expr				-	FGL expression
//
//	returns:	
//		1	- if default paramter is sucessfully created
//		0	- failure
//
//	Description:
//		The classAccessDefParam function assigns a default value to a specific parameter.  If this parameter is not
//	passed to the access method, the <expr> will be evaluated and the result pass into the method.  The <expr> may NOT access
//	variables, however function calls are allowed.
//
//
#define classAccessDefParam(className, method, nParam, expr)		((fglFuncTable->classAccessDefParam)((className), (method), (nParam), 0, (expr)))

//
//	classAssign()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	long (_cdecl  *func)(void)	-	pointer to C function called upon method invocation
//	char	*params				-	string containing parameter information
//
//	returns:	
//		1	- if assign method is sucessfully created
//		0	- failure
//
//	Description:
//		The classAssign() function registers a C function as an invokable FGL class assign method.  The parameters to the C
//	function are processed according to the <*parameters> function.
//
//
#define classAssign(className, method, access, func, params)		((fglFuncTable->classAccessor)((className), (method), (access), (long (_cdecl  *)(void))(func), (params), 1))

//
//	classAssignDefParam()
//
//	char	*className			-	name of class
//	char	*method				-	name of the method
//	int		 nParam				-	number of the parameter to set default
//	char	*expr				-	FGL expression
//
//	returns:	
//		1	- if default paramter is sucessfully created
//		0	- failure
//
//	Description:
//		The classAssignDefParam function assigns a default value to a specific parameter.  If this parameter is not
//	passed to the assign method, the <expr> will be evaluated and the result pass into the method.  The <expr> may NOT access
//	variables, however function calls are allowed.
//
//
#define classAssignDefParam(className, method, nParam, expr)		((fglFuncTable->classAccessDefParam)((className), (method), (nParam), 1, (expr)))

//
//	classOperator()
//
//	char	*className			-	name of class
//	char	*method				-	operator
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	long (_cdecl  *func)(void)	-	pointer to C function called upon operator invocation
//	char	*parameters			-	string containing parameter information
//
//	returns:	
//		1	- if operator is sucessfully overloaded
//		0	- failure
//
//	Description:
//		The classAssign() function registers a C function as an invokable FGL class operator overloaded method.  The parameters 
//	to the C function are processed according to the <*parameters> function.  The parameter string must contain only the return 
//  type, the object to be operated on and either one parameter for binary operators or no parameters for unary operators.
//
//
#define classOperator(className, method, access, func, params, asc)	((fglFuncTable->classOperator)((className), (method), (access), (long (_cdecl  *)(void))(func), (params), (asc)))

//
//	classInstance()
//
//	char	*className			-	name of class
//	char	*varName			-	name of the instance variable
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//
//	returns:	
//		1	- if the instance variable is sucessfully created
//		0	- failure
//
//	Description:
//		The classInstance() function creates an instance variable <varName> within the class.
//
//
#define classInstance(className, varName, access)					((fglFuncTable->classInstance)((className), (varName), (access)))

//
//	classInstanceX()
//
//	char	*className			-	name of class
//	char	*varName			-	name of the instance variable
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	char	*expr				-	initalizer
//
//	returns:	
//		1	- if the instance variable is sucessfully created
//		0	- failure
//
//	Description:
//		The classInstance() function creates an instance variable <varName> within the class and assigns the result of <expr> to
//	the instance variable upon object instantiation
//
//
#define classInstanceX(className, varName, access, expr)			((fglFuncTable->classInstance)((className), (varName), (access), (expr)))

//
//	classInstanceX()
//
//	char	*className			-	name of class
//	char	*constName			-	name of the constant
//	int		 access				-	access level of the method (oPUBLIC, oPRIVATE, or oPROTECTED)
//	char	*expr				-	initalizer
//
//	returns:	
//		1	- if the instance variable is sucessfully created
//		0	- failure
//
//	Description:
//		The classConstant() function creates a constant <constName> within the class having the value <expr>
//
//
#define classConstant(className, constName, expr, access)			((fglFuncTable->classConstant)((className), (constName), (expr), (access)))

//
//	classInherit()
//
//	char	*className			-	name of class
//	char	*class2				-	class to inherit from
//	char	*expr				-	initalizer
//	int		 isVirtual			-	is the class inherited virtually?
//
//	returns:	
//		1	- if the class is succesfully inherited from
//		0	- failure
//
//	Description:
//		The classInherit() function directs that the class <className> should inherit the attributes and methods of the
//  class <class2>.
//
//	NOTE: Order of definition is NOT critical.  The only requirement is that both classes be defined at the time the object
//			is instantiated, NOT when the class is defined.
//
//
#define classInherit(className, class2, access, isVirtual)			((fglFuncTable->classInherit)((className), (class2), (access), (isVirtual)))

//
//	classDirect()
//
//	char	*className			-	name of class
//	char	*message			-	message to be directed
//	char	*class2				-	class to direct the message to
//	char	*message2			-	message to dispatch in class2
//	int		 access				-	access level of message (oPUBLIC, oPRIVATE, or oPROTECTED)
//
//	returns:	
//		1	- if the directed message is created
//		0	- failure
//
//	Description:
//		The classDirect() function is used to support directed inheritance.  Should two base classes contain the same method 
//	name, the classDirect() function can be used to implicitly direct <message> to the base class <class2> using the 
//	message <message2>.
//
//
#define classDirect(className, message, class2, message2, access)	((fglFuncTable->classDirect)((className), (message), (class2), (message2), (access)))

//
//	classStatic()
//
//	char	*className			-	name of class
//	char	*varName			-	name of the class static
//	int		 access				-	access level of message (oPUBLIC, oPRIVATE, or oPROTECTED)
//
//	returns:	
//		1	- if the static variable is sucessfully created
//		0	- failure
//
//	Description:
//		The classStatic() method is used to create class-wide static instance variables.  Static instance variables are global
//	to all instances of the class.
//
//
#define classStatic(className, varName, access)						((fglFuncTable->classStatic)((className), (varName), (access)))

//
//	classStaticX()
//
//	char	*className			-	name of class
//	char	*varName			-	name of the class static
//	int		 access				-	access level of message (oPUBLIC, oPRIVATE, or oPROTECTED)
//	char	*expr				-	initializer
//
//	returns:	
//		1	- if the static variable is sucessfully created
//		0	- failure
//
//	Description:
//		The classStaticX() method is used to create class-wide static instance variables.  Static instance variables are global
//	to all instances of the class.	The <expr> is used to initialize the class-wide static.  This is evaluated only once when
//	the very first instance of the class is created.
//
//
#define classStaticX(className, varName, access, expr)				((fglFuncTable->classStatic)((className), (varName), (access), (expr)))

//
//	classRegisterGcCb()
//
//	char	 *className																		-	name of class
//	void	(*cGarbageCollectionCB)	(	struct OBJ_MEM	 *om, 
//										VAR				 *object, 
//										void			(*omMove)(struct OBJ_MEM *om, VAR *val) 
//									)														-	callback
//
//	returns:	
//		1	- if the callback is sucessfully registered
//		0	- failure
//
//	Description:
//		The classRegisterGcCb() function informs the object memory manager that the class wishes to be notified upon garbage
//	collection events.  This allows the class to collect any object memory that may be used by the class but which may not
//	normally be reachable from the garbage collector.  The omMove() function which is passed to the callback function is
//	used to inform the garbage collector of a VAR that must be collected.  The OBJ_MEM parameter MUST be the parameter passed
//	to the callback routine.
//
//
#define classRegisterGcCb(className, cGarbageCollectionCB)			((fglFuncTable->classRegisterGcCb)((className), (cGarbageCollectionCB)))

//
//	classRegisterPackCb()
//
//	char	 *className																		- name of class
//	void	(*cPackCB)	(	VAR *val, 
//							BUFFER *buff, 
//							void *param, 
//							int (*pack)(VAR *val, void *param) 
//						)																	- pack callback
//	int		(*cUnPackCB) (	VAR *obj, 
//							char **buff, 
//							unsigned int *len, 
//							void *param, 
//							VAR *(*unPack)( char **buff, unsigned int *len, void *param ) 
//						)																	- unpack callback
//
//	returns:	
//		1	- if the callback is sucessfully registered
//		0	- failure
//
//	Description:
//		The classRegisterPackCb() function informs the engine that the class wishes to be altered when a pack/unpack operation
//	is occuring on an object in it's class.
//
//
#define classRegisterPackCB(className, cPackCB, cUnpackCB)			((fglFuncTable->classRegisterPackCB)((className), (cPackCB), (cUnpackCB)))

//
//	classRegisterPackCb()
//
//	char	 *className		- name of class
//
//	returns:	
//		1	- if the class is successfully finalized
//		0	- failure
//
//	Description:
//		The classFinalize() function builds the necessary tables to make the class accessable by the FGL runtime.
//
//
#define classFinalize(className)									((fglFuncTable->classFinalize)((className)))

//
//	classNew()
//
//	char	 *className		- name of class
//	int		  nParams		- number of parameters passed on the eval stack
//
//	returns:	
//		1	- if the class is successfully finalized
//		0	- failure
//
//	Description:
//		The classNew() function creates a new instance of <className>.  The resulting object is stored in retVal.
//
//
#define classNew(className, nParams)								((fglFuncTable->classNew)((className), (nParams)))

//
//	classGetName()
//
//	VAR		*object			- object
//
//	returns:	
//		char	*name		- class name
//
//	Description:
//		The classGetName() function returns the objects class name.
//
//
#define classGetName(var)											((fglFuncTable->classGetName)(var))

//
//	classGetElements()
//
//	VAR		*object			- object
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The classGetElements() function returns a multi-dimensional FGL array containing describing the contents
//	of the class.  This array is identical to the FGL classElements() function
//
//
#define classGetElements(var)										((fglFuncTable->classGetElements)(var))

//
//	classLocalAccess()
//
//	VAR			*obj			- object
//	char		*varName		- name of instance variable
//
//	returns:	
//		VAR	*	- if instance <varName> is found
//		NULL	- if <varName> is not found
//
//	Description:
//		The classLocalAccess() function returns a VAR * to the instance variable contained in the object <obj>
//	
//	NOTE: This function will NOT cause garbage collection to occur
//
//
#define classLocalAccess(obj, varName)								((fglFuncTable->classLocalAccess)((obj), (varName)))

//
//	classLocalAssign()
//
//	VAR			*obj			- object
//	char		*varName		- name of instance variable
//	VAR			*val			- value to assign
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The classLocalAssign() function assigns the instance variable <varName> contained in the object <val> the value <val>
//	
//	NOTE: This function MAY cause garbage collection to occur
//
//
#define classLocalAssign(obj, varName, val)							((fglFuncTable->classLocalAssign)((obj), (varName), (val)))

//
//	classAllocateCargo()
//
//	VAR			*obj		- object
//	int			 len		- amount of memory to allocate
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The classAllocateCargo() function allocates object memory for the exclusive use of the caller.  This function should
//	be called in a new routine as it is allowed to be called only once for any object and is not universal to the class.  A
//	pointer to the allocatd memory may be retrieved by calling the classGetCargo(<obj>) function.  This block of memory is
//	recognized by the garbage collector and will be moved should gargabe collection occur.  It is imperitive that you treat
//	this memory as volatile and call classGetCargo() again after any routine that may cause garbage collection to occur.
//	
//	NOTE: This function MAY cause garbage collection to occur
//
//
#define classAllocateCargo(obj, len)								((fglFuncTable->classAllocateCargo)((obj), (len)))

//
//	classGetCargo()
//
//	VAR			*obj		- object
//
//	returns:	
//		void	*			- pointer to allocated memory
//		NULL				- if not allocated
//
//	Description:
//		The classGetCargo() function retrieves a pointer to the object memory allocated by classAllocateCargo()
//
//
#define classGetCargo(obj)											((fglFuncTable->classGetCargo)(obj))

//
//	libraryLoad()
//
//	char		*fName		- file name
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The libraryLoad() function loads the FLB library <fName> into the the current execution instance
//
//
#define libraryLoad(fName)											((fglFuncTable->libraryLoad)(fName))

//
//	libraryUnload()
//
//	char		*fName		- file name
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The libraryLoad() function unloads the FLB library <fName> from the the current execution instance.
//
//	NOTE: Any loaded librarys are automaticallly unloaded upon completion of execution of any page/application in any
//			execution instance.
//
//
#define libraryUnload(fName)										((fglFuncTable->libraryUnload)(fName))

//
//	isLibrayLoaded()
//
//	char		*fName		- file name
//
//	returns:	
//		1	- if library has been loaded
//		0	- if library has not been loaded
//
//	Description:
//		The isLibraryLoaded() function allows the caller to determine if a specific library has already been loaded into
//	the current execution instance.
//
//
#define isLibrayLoaded(fName)										((fglFuncTable->isLibrayLoaded)(fName))

//
//	throwError()
//
//	int			errorNum	- error number
//
//	returns:	
//
//	Description:
//		The throwError() function causes an exception to be thrown in the current execution instance. Error number <errorNum>
//	reported in the systemError object.
//
//
#define throwError(errorNum)										((fglFuncTable->throwError)(errorNum))

//
//	throwErrorX()
//
//	int			 errorNum	- error number
//	char		*errorDesc	- error description
//
//	returns:	
//
//	Description:
//		The throwErrorX() function causes an exception to be thrown in the current execution instance. Error number <errorNum>
//	and errorDescription <errorDesc> are reported in the systemError object.
//
//
#define throwErrorX(errorNum,errorDesc)								((fglFuncTable->throwErrorX)((errorNum),(errorDesc)))

//
//	errorAsText()
//
//	int			 errorNum	- error number
//
//	returns:	
//		char	*			- textual description of <errorNum>
//
//	Description:
//		The errorAsText() function returns the textual description of the FGL error <errorNum>
//
//
#define errorAsText(errorNum)										((fglFuncTable->errorAsText)(errorNum))

//
//	getCurrentError()
//
//	returns:	
//		int					- the current errro number
//
//	Description:
//		The getCurrentError() function returns the current error number set within the execution instance or 0 if no error.
//
//
#define getCurrentError()											((fglFuncTable->getCurrentError)())

//
//	funcRegister()
//
//	long (_cdecl	*pfunc)( void )	- pointer to function to register into FGL system
//	char			*name			- name of function in FGL
//	char			*params			- description of parameters
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The funcRegister() function allows the caller to register C callable functions into the FGL execution environment.
//	The Engine will automatically convert the FGL variables into the type of parameter needed by the called function.  This
//	translation is accomplished by indicating the type of parameters necessary by encoding the information in the <params>
//	structure.
//
//	The first encoded type in <params> is the return value of the function.  This can be any of the following:
//			*			- the return value has been set by the called function in retVal
//			I			- the returned value is an integer
//			U			- the returned value is an unsigned long
//			L			- the returned value is a long
//			D			- the returned value is a double
//			A			- the returned value i an int but it should be treated as an IP address
//			C			- the returned value is an asciiz string (strlen() will be called on this pointer) and free() called
//						  one this pointer after it has been copied into object memory.  The pointer must NOT be null
//			c			- this is the same as C except that the returned pointer will NOT be freed.  The pointer must NOT be null
//			P			- this is the same as C except that the returned pointer may be NULL.  If it is NULL then the FGL value
//						  will be NULL
//			p			- this is the same as c except that the returned pointer may be NULL.  If it is NULL then the FGL value
//						  will be NULL
//			O			- the returned pointer is an asciiz string located in object memory.  This value will have strlen() called
//						  on it to determine the length of the returned string
//			%B*<num>	- the returned value is an engine allocated buffer in parameter position number <num>.  The length is 
//						  length of the allocated buffer
//			%BS<num>	- the returned value is an engine allocated buffer in parameter position number <num>.  The length is
//						  calculated by doing a strlen() on the buffer
//			%L*<num>	- the returned value is an integer of the length referred in the parameter position number <num>,
//						  this is equivalent to doing *((int *)buffer)
//			%LP*<num>	- the returned value is an integer of the length of the buffer in the parameter position number <num> 
//			%L<num>		- the returned value is the integer <num>
//
//  For parameters the following types are valid:
//			I			- the parameter is an integer
//			U			- the parameter is an unsigned long
//			L			- the parameter is a long
//			*			- the parameter is the number of parameters pushed on the FGL eval stack (the number of passed FGL parameters)
//			C			- the parameter is an asciiz string or the string "" if the FGL parameter is null
//			P			- the parameter is an asciiz string or NULL if the FGL parameter is NULL
//			v			- the parameter is an FGL VAR
//			V			- (special) the function requires that the FGL program pass a parameter, but it is not passed directly to the
//						  C function.  The function must use param() to access this value
//			D			- the parameter is a double
//			%BC<num>	- the parameter is a copy in object memory of the string parameter in position <num>.  It is required by the
//						  engine that a parameter be passed in FGL in this position, but it is ignored
//			%bC<num>	- the parameter is a copy in object memory of the string parameter in position <num>.  This parameter is hidden
//						  and is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//			%BS<num>	- the parameter is a strdup in object memory of the string parameter in position <num>.  It is required by the
//						  engine that a parameter be passed in FGL in this position, but it is ignored
//			%bS<num>	- the parameter is a strdup in object memory of the string parameter in position <num>.  This parameter is hidden
//						  and is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//			%B*<num>	- the parameter is a newly allocated buffer in object memory of length <num>.  It is required by the
//						  engine that a parameter be passed in FGL in this position, but it is ignored.
//			%b*<num>	- the parameter is a newly allocated buffer in object memory of length <num>.  This parameter is hidden
//						  and is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//			%bP*<num>	- the parameter is a newly allocated buffer in object memory of length <num>.  This parameter is hidden
//						  and is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//						  NOTE: FGL parameters passed by reference will reflect any value changed in this buffer during execution
//						  of the function
//			%B<num>		- the parameter is a newly allocated buffer in object memory with the length taken from the parameter in 
//						  position<num>.  It is required by the engine that a parameter be passed in FGL in this position, but it 
//						  is ignored.
//			%b<num>		- the parameter is a newly allocated buffer in object memory with the length taken from the parameter in 
//						  position<num>.  This parameter is hidden and is generated by the engine for calling the C function, 
//						  there is no corresponding FGL parameter.
//			%L<num>		- the parameter is length of the buffer or the numeric value passed in positon <num>.  It is required by the
//						  engine that a parameter be passed in FGL in this position, but it is ignored
//			%l<num>		- the parameter is length of the buffer or the numeric value passed in positon <num>.  This parameter is 
//						  hidden and is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//			%L*<num>	- the parameter is a long passed in positon <num>.  It is required by the engine that a parameter be passed 
//						  in FGL in this position, but it is ignored
//			%l*<num>	- the parameter is long passed in passed in positon <num>.  This parameter is hidden and is generated by 
//						  the engine for calling the C function, there is no corresponding FGL parameter.
//			%l*<num>	- the parameter is long passed in passed in positon <num>.  This parameter is hidden and is generated by 
//						  the engine for calling the C function, there is no corresponding FGL parameter.
//			%lP*<num>	- the parameter is the address of a long passed in passed in positon <num>.  This parameter is hidden and 
//						  is generated by the engine for calling the C function, there is no corresponding FGL parameter.
//						  NOTE: FGL parameters passed by reference will reflect any value changed in this buffer during execution
//						  of the function
//
//
#define funcRegister(pfunc, name, params)							((fglFuncTable->funcRegister)(((long (__cdecl *)( void ))(pfunc)), (name), (params)))

//
//	funcDispatch()
//
//	char		*name		- name of function to call
//	int			 nParams	- number of parameters on FGL eval stack
//
//	returns:	
//		1	- success
//		0	- failure
//
//		function result is in retVal
//
//	Description:
//		The funcDispatch() function dispatches an FGL function (any FGL callable function, even C functions are dispatchable).
//
//
#define funcDispatch(name, nParams)									((fglFuncTable->funcDispatch)((name), (nParams)))

//
//	pCount()
//
//
//	returns:	
//		int		- the number of parameters in the current stack frame
//
//	Description:
//		The pCount() function returns the number of parameters in the current stack frame (the number passed to the 
//	function on the FGL stack)
//
//
#define pCount()													((fglFuncTable->pCount)()	)

//
//	param()
//
//	int			 nParam		- number of the parameter to retrieve
//
//	returns:	
//		VAR	*				- the returned parameter or NULL if it doesn't exist
//		0	- failure
//
//	Description:
//		The param() function retrieves the <nParam> parameter passed to the function.  Parameters are numbered such that 1 is the
//	leftmost parameter passed.
//
//
#define param(num)													((fglFuncTable->param)(num))

//
//	retVal()
//
//	returns:	
//		VAR	*		- the function return pointer
//
//	Description:
//		The retVal() function returns a pointer to a VAR structure that is used to return VAR's to the engine.  This is a static
//	location local to each execution instance.  This location is linked to the garbage collector so any values stored here will
//	automatically be collected.
//
//
#define retVal()													((fglFuncTable->retVal)())

//
//	callCodeBlock()
//
//	VAR		*val		- VAR with type codeblock
//	int		 doFixup	- fixup flag
//
//	returns:	
//		1	- success
//		0	- failure
//
//		function result is in retVal
//
//	Description:
//		The callCodeBlock() function executes a codeblock in <val>.  If doFixup is 1, then any variables in the current stack frame
//	that match those in <val> are moved from the stack into object memory and the variable in <val> is assigned a reference to the
//	moved variable.
//
//
#define callCodeBlock(val, doFixup)									((fglFuncTable->callCodeBlock)((val), (doFixup)))

//
//	compileCodeblock()
//
//	char	*string		- expression to compile into a codeblock
//
//	returns:	
//		1	- success
//		0	- failure
//
//		function result is in retVal
//
//	Description:
//
//		TBD
//
//
#define compileCodeblock(string)									((fglFuncTable->compileCodeblock)(string))

//
//	resourceRegister()
//
//	void		*resource			- pointer to resource to register
//	int (_cdecl *freeFunc)(void *)	- pointer to function to free resource 
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The resourceRegster() function attaches a resource <resource> to a list of resources that are necessary to close upon 
//	completion of the currently executing FGL instance.  Such resources may include file handles, sockets, windows resources, etc.
//	Upon completion, the engine will call the function <freeFunc> with the parameter <resource> to allow for cleanup.
//
//
#define resourceRegister(resource,freeFunc)							((fglFuncTable->resourceRegister)((resource), (int (_cdecl *)(void *resource))(freeFunc) ))

//
//	resourceFree()
//
//	void		*resource			- pointer to resource to register
//	int (_cdecl *freeFunc)(void *)	- pointer to function to free resource 
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The resourceFree() function removes a resource previously registered with resourceRegister() from the resource list
//
//
#define resourceFree(resource,freeFunc)								((fglFuncTable->resourceFree)((resource), (int (_cdecl *)(void *resource))(freeFunc) ))

//
//	allocateWorkarea()
//
//	void					*db			- pointer to some database object
//	FGL_DATBASE_FUNC_TABLE	*funcTable	- pointer to function table
//	char					*alias		- pointer to alias to assign workarea
//
//	returns:	
//		1	- success
//		0	- failure
//
//	Description:
//		The alloateWorkarea() function allocates a new database workarea and attaches the database <db> to that workarea.  Any
//	database calls directed to this workarea are routed throught the <funcTable> function table.
//
//
#define allocateWorkarea(db, funcTable, alias)						((fglFuncTable->allocateWorkarea)((db), (funcTable), (alias) ))

#define EXCEPT(errNum)				{throwError(errNum);return (0);}
#define EXCEPTX(errNum,desc)		{throwErrorX((int)(errNum),(char*)(desc));return(0);}

#endif /* defined ( classNew ) */
#endif /* defined ( __fglExtension_h__ ) */