/****************************************************************************************/
/*  JEPTRMGR.H                                                                          */
/*                                                                                      */
/*  Author:  John Pollard                                                               */
/*  Description:                                                                        */
/*                                                                                      */
/*  The contents of this file are subject to the Jet3D Public License                   */
/*  Version 1.02 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.jet3d.com                                                                */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Jet3D, released December 12, 1999.                             */
/*  Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved           */
/*                                                                                      */
/****************************************************************************************/

#ifndef JE_PTRMGR_H
#define JE_PTRMGR_H

#include "BaseType.h"
#include "VFile.h"

#ifdef __cplusplus
extern "C" {
#endif

//=======================================================================================
//=======================================================================================
typedef struct jePtrMgr		jePtrMgr;

//=======================================================================================
//	Function prototypes
//=======================================================================================
JETAPI jePtrMgr		*jePtrMgr_Create(void);
JETAPI jeBoolean	jePtrMgr_IsValid(const jePtrMgr *PtrMgr);
JETAPI jeBoolean	jePtrMgr_CreateRef(jePtrMgr *PtrMgr);
JETAPI void			jePtrMgr_Destroy(jePtrMgr **PtrMgr);

JETAPI jeBoolean	jePtrMgr_ReadPtr(jePtrMgr *PtrMgr, jeVFile *VFile, void **Ptr);
	// ReadPtr - Reads the ptr header, and determines if the ptr is in the ptr stack.  If in stack, it refs it by 1
JETAPI jeBoolean	jePtrMgr_PushPtr(jePtrMgr *PtrMgr, void *Ptr);
	// PushPtr - Pushes a ptr on the ptr stack
JETAPI jeBoolean	jePtrMgr_WritePtr(jePtrMgr *PtrMgr, jeVFile *VFile, void *Ptr, uint32 *Count);
	// WritePtr - Writes the ptr header, and returns the current ref count of the ptr in the stack (0 == not in stack yet)
JETAPI void			jePtrMgr_PopPtr(jePtrMgr *PtrMgr, void *Ptr);
	// PopPtr - Pops the last pushed ptr off the stack (Must specify the pointer for internal error checking)

JETAPI jeBoolean	jePtrMgr_GetPtrCount(const jePtrMgr *PtrMgr, int32 *PtrCount);
JETAPI jeBoolean	jePtrMgr_GetPtrRefs(const jePtrMgr *PtrMgr, int32 *PtrRefs);

#if 0
//	Example read code
jeActor *jeActor_CreateFromFile(jeVFile *VFile, jePtrMgr *PtrMgr)
{
	if (PtrMgr)
	{
		if (!jePtrMgr_ReadPtr(PtrMgr, VFile, &Actor))
			return NULL;

		if (Actor)
		{
			if (!jeActor_CreateRef(Actor))
				return NULL:

			return Actor;		// Ptr found in stack, return it
		}
	}

	// Create a new actor
	Actor = JE_RAM_ALLOCATE_STRUCT(jeActor);

	if (!Actor)
		return NULL;
	
	if (!jeVFile_Read(VFile, &Actor->Number, sizeof(Actor->Number))
		goto ExitWithError;

	if (PtrMgr)
	{
		// Push the ptr on the stack
		if (!jePtrMgr_PushPtr(PtrMgr, Actor))
			goto ExitWithError;
	}
	
	return Actor;

	ExitWithError:
	{
		if (Actor)
			jeRam_Free(Actor);

		return NULL;
	}
}

//	Example write code
jeBoolean jeActor_WriteToFile(const jeActor *Actor, jeVFile *VFile, jePtrMgr *PtrMgr)
{
	uint32		Count;

	if (PtrMgr)
	{
		if (!jePtrMgr_WritePtr(PtrMgr, VFile, Actor, &Count))
			return JE_FALSE;

		if (Count)		// Already loaded
			return JE_TRUE;
	}

	if (!jeVFile_Write(VFile, &Actor->Number, sizeof(Actor->Number))
		return JE_FALSE:
	
	if (PtrMgr)
	{
		// Push the ptr on the stack
		if (!jePtrMgr_PushPtr(PtrMgr, Actor))
			return JE_FALSE;
	}

	return JE_TRUE;
}

#endif
#ifdef __cplusplus
}
#endif

#endif
