/*
 	File:		QD3DGroup.h
 
 	Contains:	Q3Group methods		
 
 	Version:	Technology:	Quickdraw 3D 1.6
 				Release:	QuickTime 4.0
 
 	Copyright:	(c) 1995-1998 by Apple Computer, Inc., all rights reserved.
 
 	Bugs?:		For bug reports, consult the following page on
 				the World Wide Web:
 
 					http://developer.apple.com/bugreporter/
 
*/
#ifndef __QD3DGROUP__
#define __QD3DGROUP__

#ifndef __QD3D__
#include <QD3D.h>
#endif



#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if PRAGMA_IMPORT
#pragma import on
#endif

#if PRAGMA_STRUCT_ALIGN
	#pragma options align=power
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
	#pragma pack(2)
#endif

#if PRAGMA_ENUM_ALWAYSINT
	#pragma enumsalwaysint on
#elif PRAGMA_ENUM_OPTIONS
	#pragma option enum=int
#elif PRAGMA_ENUM_PACK
	#if __option(pack_enums)
		#define PRAGMA_ENUM_PACK__QD3DGROUP__
	#endif
	#pragma options(!pack_enums)
#endif

/******************************************************************************
 **																			 **
 **							Group Typedefs									 **
 **																			 **
 *****************************************************************************/
/*
 * These flags affect how a group is traversed
 * They apply to when a group is "drawn", "picked", "bounded", "written"
 */

enum TQ3DisplayGroupStateMasks {
	kQ3DisplayGroupStateNone	= 0,
	kQ3DisplayGroupStateMaskIsDrawn = 1 << 0,
	kQ3DisplayGroupStateMaskIsInline = 1 << 1,
	kQ3DisplayGroupStateMaskUseBoundingBox = 1 << 2,
	kQ3DisplayGroupStateMaskUseBoundingSphere = 1 << 3,
	kQ3DisplayGroupStateMaskIsPicked = 1 << 4,
	kQ3DisplayGroupStateMaskIsWritten = 1 << 5
};
typedef enum TQ3DisplayGroupStateMasks TQ3DisplayGroupStateMasks;

typedef unsigned long 					TQ3DisplayGroupState;
 

/******************************************************************************
 **																			 **
 **					Group Routines (apply to all groups)					 **
 **																			 **
 *****************************************************************************/
/* May contain any shared object */
EXTERN_API_C( TQ3GroupObject )
Q3Group_New						(void);

EXTERN_API_C( TQ3ObjectType )
Q3Group_GetType					(TQ3GroupObject 		group);

EXTERN_API_C( TQ3GroupPosition )
Q3Group_AddObject				(TQ3GroupObject 		group,
								 TQ3Object 				object);

EXTERN_API_C( TQ3GroupPosition )
Q3Group_AddObjectBefore			(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position,
								 TQ3Object 				object);

EXTERN_API_C( TQ3GroupPosition )
Q3Group_AddObjectAfter			(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position,
								 TQ3Object 				object);

EXTERN_API_C( TQ3Status )
Q3Group_GetPositionObject		(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position,
								 TQ3Object *			object);

EXTERN_API_C( TQ3Status )
Q3Group_SetPositionObject		(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position,
								 TQ3Object 				object);

EXTERN_API_C( TQ3Object )
Q3Group_RemovePosition			(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetFirstPosition		(TQ3GroupObject 		group,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetLastPosition			(TQ3GroupObject 		group,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetNextPosition			(TQ3GroupObject 		group,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetPreviousPosition		(TQ3GroupObject 		group,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_CountObjects			(TQ3GroupObject 		group,
								 unsigned long *		nObjects);

EXTERN_API_C( TQ3Status )
Q3Group_EmptyObjects			(TQ3GroupObject 		group);

/*
 * 	Typed Access
 */
EXTERN_API_C( TQ3Status )
Q3Group_GetFirstPositionOfType	(TQ3GroupObject 		group,
								 TQ3ObjectType 			isType,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetLastPositionOfType	(TQ3GroupObject 		group,
								 TQ3ObjectType 			isType,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetNextPositionOfType	(TQ3GroupObject 		group,
								 TQ3ObjectType 			isType,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetPreviousPositionOfType (TQ3GroupObject 		group,
								 TQ3ObjectType 			isType,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_CountObjectsOfType		(TQ3GroupObject 		group,
								 TQ3ObjectType 			isType,
								 unsigned long *		nObjects);

EXTERN_API_C( TQ3Status )
Q3Group_EmptyObjectsOfType		(TQ3GroupObject 		group,
								 TQ3ObjectType 			isType);

/*
 *	Determine position of objects in a group
 */
EXTERN_API_C( TQ3Status )
Q3Group_GetFirstObjectPosition	(TQ3GroupObject 		group,
								 TQ3Object 				object,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetLastObjectPosition	(TQ3GroupObject 		group,
								 TQ3Object 				object,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetNextObjectPosition	(TQ3GroupObject 		group,
								 TQ3Object 				object,
								 TQ3GroupPosition *		position);

EXTERN_API_C( TQ3Status )
Q3Group_GetPreviousObjectPosition (TQ3GroupObject 		group,
								 TQ3Object 				object,
								 TQ3GroupPosition *		position);


/******************************************************************************
 **																			 **
 **							Group Subclasses								 **
 **																			 **
 *****************************************************************************/
/* Must contain only lights */
EXTERN_API_C( TQ3GroupObject )
Q3LightGroup_New				(void);

/* Must contain only strings */
EXTERN_API_C( TQ3GroupObject )
Q3InfoGroup_New					(void);

/******************************************************************************
 **																			 **
 **						Display Group Routines								 **
 **																			 **
 *****************************************************************************/
/* May contain only drawables */
EXTERN_API_C( TQ3GroupObject )
Q3DisplayGroup_New				(void);

EXTERN_API_C( TQ3ObjectType )
Q3DisplayGroup_GetType			(TQ3GroupObject 		group);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_GetState			(TQ3GroupObject 		group,
								 TQ3DisplayGroupState *	state);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_SetState			(TQ3GroupObject 		group,
								 TQ3DisplayGroupState 	state);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_Submit			(TQ3GroupObject 		group,
								 TQ3ViewObject 			view);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_SetAndUseBoundingBox (TQ3GroupObject 	group,
								 TQ3BoundingBox *		bBox);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_GetBoundingBox	(TQ3GroupObject 		group,
								 TQ3BoundingBox *		bBox);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_RemoveBoundingBox (TQ3GroupObject 		group);

EXTERN_API_C( TQ3Status )
Q3DisplayGroup_CalcAndUseBoundingBox (TQ3GroupObject 	group,
								 TQ3ComputeBounds 		computeBounds,
								 TQ3ViewObject 			view);


/******************************************************************************
 **																			 **
 **		Ordered Display Group											 	 **
 **																			 **
 **		Ordered display groups keep objects in order by the type of object:	 **
 **																			 **
 **		1	kQ3ShapeTypeTransform											 **
 **		2	kQ3ShapeTypeStyle											 	 **
 **		3	kQ3SetTypeAttribute											 	 **
 **		4	kQ3ShapeTypeShader											 	 **
 **		5	kQ3ShapeTypeCamera											 	 **
 **		6	kQ3ShapeTypeLight											 	 **
 **		7	kQ3ShapeTypeGeometry											 **
 **		8	kQ3ShapeTypeGroup												 **			
 **		9	kQ3ShapeTypeUnknown												 **
 **																			 **
 **		Within a type, you are responsible for keeping things in order.		 **
 **																			 **
 **		You may access and/or manipulate the group using the above types 	 **
 **		(fast), or you may use any parent or leaf class types (slower).		 **
 **																			 **
 **		Additional types will be added as functionality grows.				 **
 **																			 **
 **		The group calls which access by type are much faster for ordered	 ** 
 **		display group for the types above.									 **
 **																			 **
 **		N.B. Lights and Cameras in groups are a no-op when drawn and will	 **
 **			 post an error with the debug libraries.						 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3GroupObject )
Q3OrderedDisplayGroup_New		(void);

/******************************************************************************
 **																			 **
 **		IO Proxy Display Group											 	 **
 **																			 **
 **		IO Proxy display groups are used to place more than one 			 **
 **		representation of an object in a metafile. For example, if you know	 **
 **		another program does not understand NURBPatches but does understand  **
 **		Meshes, you may place a mesh and a NURB Patch in an IO Proxy Group,  **
 **		and the reading program will select the desired representation.		 **
 **																			 **
 **		Objects in an IO Proxy Display Group are placed in their preferencial**
 **		order, with the FIRST object being the MOST preferred, the LAST 	 **
 **		object the least preferred.											 **
 **																			 **
 **		The behavior of an IO Proxy Display Group is that when drawn/picked/ **
 **		bounded, the first object in the group that is not "Unknown" is used,**
 **		and the other objects ignored.										 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3GroupObject )
Q3IOProxyDisplayGroup_New		(void);

/******************************************************************************
 **																			 **
 **						Group Extension Definitions							 **
 **																			 **
 *****************************************************************************/
/*
 *	Searching methods - OPTIONAL
 */

enum {
	kQ3XMethodType_GroupAcceptObject = FOUR_CHAR_CODE('gaco')
};

typedef CALLBACK_API_C( TQ3Boolean , TQ3XGroupAcceptObjectMethod )(TQ3GroupObject group, TQ3Object object);

enum {
	kQ3XMethodType_GroupAddObject = FOUR_CHAR_CODE('gado')
};

typedef CALLBACK_API_C( TQ3GroupPosition , TQ3XGroupAddObjectMethod )(TQ3GroupObject group, TQ3Object object);

enum {
	kQ3XMethodType_GroupAddObjectBefore = FOUR_CHAR_CODE('gaob')
};

typedef CALLBACK_API_C( TQ3GroupPosition , TQ3XGroupAddObjectBeforeMethod )(TQ3GroupObject group, TQ3GroupPosition position, TQ3Object object);

enum {
	kQ3XMethodType_GroupAddObjectAfter = FOUR_CHAR_CODE('gaoa')
};

typedef CALLBACK_API_C( TQ3GroupPosition , TQ3XGroupAddObjectAfterMethod )(TQ3GroupObject group, TQ3GroupPosition position, TQ3Object object);

enum {
	kQ3XMethodType_GroupSetPositionObject = FOUR_CHAR_CODE('gspo')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupSetPositionObjectMethod )(TQ3GroupObject group, TQ3GroupPosition gPos, TQ3Object obj);

enum {
	kQ3XMethodType_GroupRemovePosition = FOUR_CHAR_CODE('grmp')
};

typedef CALLBACK_API_C( TQ3Object , TQ3XGroupRemovePositionMethod )(TQ3GroupObject group, TQ3GroupPosition position);
 

/*
 *	Searching methods - OPTIONAL - default uses above methods
 */

enum {
	kQ3XMethodType_GroupGetFirstPositionOfType = FOUR_CHAR_CODE('gfrt')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetFirstPositionOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetLastPositionOfType = FOUR_CHAR_CODE('glst')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetLastPositionOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetNextPositionOfType = FOUR_CHAR_CODE('gnxt')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetNextPositionOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetPrevPositionOfType = FOUR_CHAR_CODE('gpvt')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetPrevPositionOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupCountObjectsOfType = FOUR_CHAR_CODE('gcnt')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupCountObjectsOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType, unsigned long *nObjects);

enum {
	kQ3XMethodType_GroupEmptyObjectsOfType = FOUR_CHAR_CODE('geot')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupEmptyObjectsOfTypeMethod )(TQ3GroupObject group, TQ3ObjectType isType);

enum {
	kQ3XMethodType_GroupGetFirstObjectPosition = FOUR_CHAR_CODE('gfop')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetFirstObjectPositionMethod )(TQ3GroupObject group, TQ3Object object, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetLastObjectPosition = FOUR_CHAR_CODE('glop')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetLastObjectPositionMethod )(TQ3GroupObject group, TQ3Object object, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetNextObjectPosition = FOUR_CHAR_CODE('gnop')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetNextObjectPositionMethod )(TQ3GroupObject group, TQ3Object object, TQ3GroupPosition *gPos);

enum {
	kQ3XMethodType_GroupGetPrevObjectPosition = FOUR_CHAR_CODE('gpop')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupGetPrevObjectPositionMethod )(TQ3GroupObject group, TQ3Object object, TQ3GroupPosition *gPos);
 

/*
 *	Group Position Methods
 */

enum {
	kQ3XMethodType_GroupPositionSize = FOUR_CHAR_CODE('ggpz')
};

typedef unsigned long 					TQ3XMethodTypeGroupPositionSize;

enum {
	kQ3XMethodType_GroupPositionNew = FOUR_CHAR_CODE('ggpn')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupPositionNewMethod )(void *gPos, TQ3Object object, const void *initData);

enum {
	kQ3XMethodType_GroupPositionCopy = FOUR_CHAR_CODE('ggpc')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupPositionCopyMethod )(void *srcGPos, void *dstGPos);

enum {
	kQ3XMethodType_GroupPositionDelete = FOUR_CHAR_CODE('ggpd')
};

typedef CALLBACK_API_C( void , TQ3XGroupPositionDeleteMethod )(void *gPos);
 

/*
 *	View Drawing Helpers
 *	
 *	TQ3XGroupStartIterateMethod
 *
 *		Pass back *object = NULL to NOT call EndIterate iterate
 *		Pass back *object != NULL to draw object
 *		 (other side will pass it to EndIterate for deletion!)
 *
 *		*iterator is uninitialized, use for iteration state. Caller should 
 *		 ignore it.
 *	
 *	TQ3XGroupEndIterateMethod
 *	
 *		*object is previous object, dispose it or play with it.
 *		Pass back NULL when last iteration has occurred
 *		*iterator is previous value, use for iteration state Caller should 
 *		ignore it.
 */

enum {
	kQ3XMethodType_GroupStartIterate = FOUR_CHAR_CODE('gstd')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupStartIterateMethod )(TQ3GroupObject group, TQ3GroupPosition *iterator, TQ3Object *object, TQ3ViewObject view);

enum {
	kQ3XMethodType_GroupEndIterate = FOUR_CHAR_CODE('gitd')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupEndIterateMethod )(TQ3GroupObject group, TQ3GroupPosition *iterator, TQ3Object *object, TQ3ViewObject view);
 

/*
 *	IO  Helpers
 *	
 *	TQ3XGroupEndReadMethod
 *		Called when a group has been completely read. Group should perform
 *		validation and clean up any reading caches.
 */

enum {
	kQ3XMethodType_GroupEndRead	= FOUR_CHAR_CODE('gerd')
};

typedef CALLBACK_API_C( TQ3Status , TQ3XGroupEndReadMethod )(TQ3GroupObject group);
EXTERN_API_C( void *)
Q3XGroup_GetPositionPrivate		(TQ3GroupObject 		group,
								 TQ3GroupPosition 		position);




#if PRAGMA_ENUM_ALWAYSINT
	#pragma enumsalwaysint reset
#elif PRAGMA_ENUM_OPTIONS
	#pragma option enum=reset
#elif defined(PRAGMA_ENUM_PACK__QD3DGROUP__)
	#pragma options(pack_enums)
#endif

#if PRAGMA_STRUCT_ALIGN
	#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
	#pragma pack()
#endif

#ifdef PRAGMA_IMPORT_OFF
#pragma import off
#elif PRAGMA_IMPORT
#pragma import reset
#endif

#ifdef __cplusplus
}
#endif

#endif /* __QD3DGROUP__ */

