/*
	FILE:	Motoko_Manager.h
	
	AUTHOR:	Brent H. Pease
	
	CREATED: May 5, 1997
	
	PURPOSE: Interface to the Motoko 3D engine
	
	Copyright 1997

*/
#ifndef MOTOKO_MANAGER_H
#define MOTOKO_MANAGER_H

#include "BFW_Motoko.h"

#define	M3cManager_MaxCameras			(4)

typedef struct M3tManager_GeomCamera
{
	UUtBool			inUse;
	UUtBool			vfnDirty;					// viewFrustumNormals are dirty?
	UUtBool			wfpDirty;					// worldFrustumNormals are dirty?
	UUtBool			staticDirty;				// is static dirty?

	UUtBool			viewDirty;					// is view dirty?
	UUtBool			staticSet;					// has static been set?
	UUtBool			viewSet;					// has view data been set?
	UUtBool			pad;
	
	M3tPoint3D		cameraLocation;
	M3tVector3D		viewVector;
	M3tVector3D		upVector;
	M3tVector3D		crossVector;	// this is viewVector cross upVector
	float			fovy;
	float			aspect;
	float			zNear;
	float			zFar;
	
	M3tMatrix4x4	matrix_viewToFrustum;
	M3tMatrix4x4	matrix_frustumToView;
	
	M3tMatrix4x4	matrix_worldToView;
	M3tMatrix4x4	matrix_viewToWorld;

	M3tMatrix4x4	matrix_worldToFrustum;
	M3tMatrix4x4	matrix_frustumToWorld;
	

	M3tVector3D			viewFrustumNormals[6];
	M3tPlaneEquation	worldFrustumPlanes[6];
	M3tPoint3D			worldFrustumPoints[8];
	
} M3tManager_GeomCamera;

/*
 * typedefs for draw engine functions
 */
	/*
	 * Frame functions
	 */	
		typedef UUtError 
		(*M3tDrawContextMethod_Frame_Start)(
			UUtUns32			inGameTime);
			
		typedef UUtError 
		(*M3tDrawContextMethod_Frame_End)(
			UUtUns32	*outTextureBytesDownloaded);

		typedef UUtError 
		(*M3tDrawContextMethod_Frame_Sync)(
			void);
	
	/*
	 * 2 1/2 D triangles
	 */
	 
		typedef void
		(*M3tDrawContextMethod_Triangle)(
			void*			inTriangle);

	/*
	 * Quad routines
	 */
		typedef void
		(*M3tDrawContextMethod_Quad)(
			void*		inQuad);
	
	/*
	 * Pent functions, these are generated by the clipper
	 */
		typedef void
		(*M3tDrawContextMethod_Pent)(
			void*		inPent);

	/*
	 * 2 1/2 D Points and Lines
	 */
		typedef void
		(*M3tDrawContextMethod_Line)(
			UUtUns32		inVIndex0,
			UUtUns32		inVIndex1);

		typedef void
		(*M3tDrawContextMethod_Point)(
			M3tPointScreen*	inCoord);
	
	/*
	 * Bitmap drawing
	 */
		typedef void
		(*M3tDrawContextMethod_TriSprite)(
			const M3tPointScreen	*inPoints,			// points[3]
			const M3tTextureCoord	*inTextureCoords);	// UVs[3]
			
		typedef void
		(*M3tDrawContextMethod_Sprite)(
			const M3tPointScreen	*inPoints,			// topleft, botright
			const M3tTextureCoord	*inTextureCoords);	// topleft, topright, botleft, botright

		typedef void
		(*M3tDrawContextMethod_SpriteArray)(
			const M3tPointScreen	*inPoints,			// topleft, botright
			const M3tTextureCoord	*inTextureCoords,	// topleft, topright, botleft, botright
			const UUtUns32			*inColors,
			const UUtUns32			inCount );

		typedef UUtError 
		(*M3tDrawContextMethod_ScreenCapture)(
			const UUtRect*	inRect, 
			void*			outBuffer);

		typedef UUtBool
		(*M3tDrawContextMethod_PointVisible)(
			const M3tPointScreen	*inPoint,
			float					inTolerance);

	/*
	 * Query functions
	 */
		typedef UUtBool
		(*M3tDrawContextMethod_TextureFormatAvailable)(
			IMtPixelType	inTexelType);

	/* S.S. */
	typedef UUtError (*M3tDrawContextMethod_ChangeMode)(M3tDisplayMode mode);
	typedef void (*M3tDrawContextMethod_ResetFogParams)(void); // reset fog settings to defaults
	typedef UUtBool (*M3tDrawContextMethod_LoadTexture)(M3tTextureMap *texture_map); // load a texture
	typedef UUtBool (*M3tDrawContextMethod_UnloadTexture)(M3tTextureMap *texture_map); // unload it
	typedef UUtBool (*M3tDrawContextMethod_Support_Single_Pass_Multitexture)(void); // love these loooooooong names!
	typedef UUtBool (*M3tDrawContextMethod_SupportPointVisibility)(void);
/*
 * Draw Engine methods
 */

	typedef enum {
		M3cDrawAPI_Empty			= 0,
		M3cDrawAPI_OpenGL			= 1,
		M3cDrawAPI_Glide			= 2,
		M3cDrawAPI_D3D				= 3,
		M3cDrawAPI_RAVE				= 4,
		M3cDrawAPI_Software			= 5
	} M3tDrawAPI;

/*
 * The draw context data structure
 */
	typedef struct M3tDrawContextMethods
	{
		M3tDrawContextMethod_Frame_Start			frameStart;
		M3tDrawContextMethod_Frame_End				frameEnd;
		M3tDrawContextMethod_Frame_Sync				frameSync;
		
		M3tDrawContextMethod_Triangle				triangle;
		M3tDrawContextMethod_Quad					quad;
		M3tDrawContextMethod_Pent					pent;
		
		M3tDrawContextMethod_Line					line;
		M3tDrawContextMethod_Point					point;
		
		M3tDrawContextMethod_TriSprite				triSprite;
		M3tDrawContextMethod_Sprite					sprite;
		M3tDrawContextMethod_SpriteArray			spriteArray;
		M3tDrawContextMethod_ScreenCapture			screenCapture;
		M3tDrawContextMethod_PointVisible			pointVisible;
		M3tDrawContextMethod_SupportPointVisibility	supportPointVisible;
		
		M3tDrawContextMethod_TextureFormatAvailable	textureFormatAvailable;

		M3tDrawContextMethod_ChangeMode				changeMode;
		M3tDrawContextMethod_ResetFogParams			resetFog;
		M3tDrawContextMethod_LoadTexture			loadTexture;
		M3tDrawContextMethod_UnloadTexture			unloadTexture;
		M3tDrawContextMethod_Support_Single_Pass_Multitexture	supportSinglePassMultitexture;

	} M3tDrawContextMethods;

	/*
	 * Engine draw context private new
	 */
	typedef UUtError (*M3tDrawEngineMethod_ContextPrivateNew)(
		M3tDrawContextDescriptor*	inDrawContextDescriptor,
		M3tDrawContextMethods*		*outDrawContextFuncs,
		UUtBool						inFullScreen,
		M3tDrawAPI					*outAPI);

	/* 
	 * Engine draw context private delete
	 */
	typedef void (*M3tDrawEngineMethod_ContextPrivateDelete)(
		void);
	
	/*
	 * Reset the entire texture state, including animated textures
	 */
	typedef void (*M3tDrawEngineMethod_Texture_ResetAll)(
		void);
	
	// This lets the engine allocate a new private state structure
	typedef UUtError
	(*M3tDrawEngineMethod_PrivateState_New)(
		void*	inState_Private);
	
	// This lets the engine delete a new private state structure
	typedef void 
	(*M3tDrawEngineMethod_PrivateState_Delete)(
		void*	inState_Private);
	
	// This lets the engine update the state according to the update flags
	typedef UUtError
	(*M3tDrawEngineMethod_State_Update)(
		void*			inState_Private,
		UUtUns32		inState_IntFlags,
		const UUtInt32*	inState_Int,
		UUtInt32		inState_PtrFlags,
		void**			inState_Ptr);
	
	// This lets the engine allocate a new private state structure
	typedef UUtError
	(*M3tGeomEngineMethod_PrivateState_New)(
		void*	inState_Private);
	
	// This lets the engine delete a new private state structure
	typedef void 
	(*M3tGeomEngineMethod_PrivateState_Delete)(
		void*	inState_Private);
	
	// This lets the engine update the state according to the update flags
	typedef UUtError
	(*M3tGeomEngineMethod_State_Update)(
		void*			inState_Private,
		UUtUns16		inState_IntFlags,
		const UUtInt32*	inState_Int);
	
/*
 * Geom Engine methods
 */
	/*
	 * Engine draw context private new
	 */
	typedef UUtError (*M3tGeomEngineMethod_ContextPrivateNew)(
		M3tDrawContextDescriptor*	inDrawContextDescriptor,
		M3tGeomContextMethods*		*outGeomContextmethods);

	/*
	 * Engine draw context set environment
	 */
	typedef UUtError (*M3tGeomEngineMethod_ContextSetEnvironment)(
		struct AKtEnvironment*		inEnvironment);

	/* 
	 * Engine draw context private delete
	 */
	typedef void (*M3tGeomEngineMethod_ContextPrivateDelete)(
		void);

	/* 
	 * 
	 */
	typedef void (*M3tGeomEngineMethod_UpdateNotification)(
		void);

typedef struct M3tDrawEngineMethods
{
	M3tDrawEngineMethod_ContextPrivateNew		contextPrivateNew;
	M3tDrawEngineMethod_ContextPrivateDelete	contextPrivateDelete;
	M3tDrawEngineMethod_Texture_ResetAll		textureResetAll;
	
	UUtUns32									privateStateSize;
	M3tDrawEngineMethod_PrivateState_New		privateStateNew;
	M3tDrawEngineMethod_PrivateState_Delete		privateStateDelete;
	M3tDrawEngineMethod_State_Update			privateStateUpdate;
	
} M3tDrawEngineMethods;

typedef struct M3tGeomEngineMethods
{
	M3tGeomEngineMethod_ContextPrivateNew		contextPrivateNew;
	M3tGeomEngineMethod_ContextPrivateDelete	contextPrivateDelete;
	M3tGeomEngineMethod_ContextSetEnvironment	contextSetEnvironment;

	UUtUns32									privateStateSize;
	M3tGeomEngineMethod_PrivateState_New		privateStateNew;
	M3tGeomEngineMethod_PrivateState_Delete		privateStateDelete;
	M3tGeomEngineMethod_State_Update			privateStateUpdate;
	
	M3tGeomEngineMethod_UpdateNotification		cameraViewUpdate;
	M3tGeomEngineMethod_UpdateNotification		cameraStaticUpdate;
	
	
} M3tGeomEngineMethods;

extern TMtPrivateData*			M3gTemplate_Geometry_PrivateData;

/*
 * Draw functions that are allowed only within Motoko.
 */
	/*
	 * 2 1/2 D triangles
	 */

                typedef void (*M3rDraw_Triangle_Func)(void *inTriangle);
                
                M3rDraw_Triangle_Func M3rDraw_GetTriangleFunction();
                
		void
		M3rDraw_Triangle(
			void*		inTriangle);	// vertex type is specified via M3tDrawStateIntType_VertexFormat

	/*
	 * Quad routines
	 */
		void
		M3rDraw_Quad(
			void*		inQuad);	// vertex type is specified via M3tDrawStateIntType_VertexFormat
	
	/*
	 * Pent functions, these are generated by the clipper
	 */
		void
		M3rDraw_Pent(
			void*		inPent);	// vertex type is specified via M3tDrawStateIntType_VertexFormat

	/*
	 * 2 1/2 D Points and Lines
	 */
		void
		M3rDraw_Line(
			UUtUns32		inVIndex0,
			UUtUns32		inVIndex1);

		void
		M3rDraw_Point(
			M3tPointScreen*	inCoord);
	
/*
 *
 */
	
	void
	M3rManager_Camera_UpdateMatrices(
		M3tManager_GeomCamera*	inCamera);
	
	void
	M3rManager_Camera_Initialize(
		void);

/*
 *
 */
	UUtError
	M3rManager_Matrix_Initialize(
		void);
		
	void
	M3rManager_Matrix_Terminate(
		void);
	
/*
 * Functions to Register Motoko engines
 */
	UUtError
	M3rManager_Register_DrawEngine(
		M3tDrawEngineCaps*			inDrawEngineCaps,
		M3tDrawEngineMethods*		inDrawEngineMethods);

	UUtError
	M3rManager_Register_GeomEngine(
		M3tGeomEngineCaps*			inGeomEngineCaps,
		M3tGeomEngineMethods*		inGeomEngineMethods);
	
/*
 * 
 */
	void
	M3rManager_GetActiveDrawEngine(
		UUtUns16	*outActiveDrawEngie,
		UUtUns16	*outActiveDevice,
		UUtUns16	*outActiveMode);

M3tDrawAPI
M3rDrawContext_GetAPI(
	void);

#endif /* MOTOKO_MANAGER_H */
