//
// Asura_Chunk_Entity.h
//
// Created by Richard Rice - 30/04/2002
// 
// Copyright (C) 2002 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef _ASURA_CHUNK_ENTITY_H_
#define _ASURA_CHUNK_ENTITY_H_

#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "Core/Asura_Maths.h"
#include "Network/Asura_Guid.h"

class Asura_Entity_Server;
class Asura_SaveBlock_Base;
class Asura_Chunk_Stream;
struct Asura_StaticMessage;

///////////////////////////////////////////////////////////////////////////////////////////////
/*--------------------**
** Asura_Chunk_Entity **
**--------------------*/

class Asura_Chunk_Entity : public Asura_Chunk_Header
{
public:
	bool Process(Asura_Handle fileHandle) const;
	bool Process(const char* chunkBuffer) const;
	bool Process(Asura_Chunk_Stream& xStream) const;
	bool Project_Process(const char* chunkBuffer) const;
    bool Project_ProcessClientEntities( const char* pcChunkBuffer ) const;
	static void Create(Asura_Entity_Server* pxEntity, Asura_SaveBlock_Base& xSaveBlock);

	enum ChunkFlags
	{
		ChunkFlag_ClientOnly = 0x00000001,//Prevents server chunk parser from handling this chunk
		ChunkFlag_ServerOnly = 0x00000002,//Prevents client chunk parser from handling this chunk
	};

	Asura_Guid		Guid;
	unsigned short	Classification;
    unsigned short  m_usPadding;

private:
    enum { CURRENT_CHUNK_VERSION = 0 };
};

///////////////////////////////////////////////////////////////////////////////////////////////
/*------------------------------**
** Asura_Chunk_Entity_ToolsData **
**------------------------------*/

class Asura_Chunk_Entity_ToolsData : public Asura_Chunk_Header
{
	public :
		bool Process(Asura_Chunk_Stream& xStream) const;
		bool Process(Asura_Handle fileHandle) const;
		bool Process(const char* chunkBuffer,struct Tools_Entity_Data* pxToolsData = 0) const;
#ifdef ASURA_TOOLS
		static void Create(Asura_Entity_Server* entity,Asura_SaveBlock_Base& saveBlock,bool bSavingToTemplateFile = false);
#endif

		Asura_Guid Guid;
		Asura_Vector_3 Position;
};

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------**
** Asura_Chunk_StaticMessages **
**----------------------------*/

class Asura_Chunk_StaticMessages : public Asura_Chunk_Header
{
private :
#if defined(ASURA_USE_STREAMING) && !defined(ASURA_TOOLS)
		// This is necessary to ensure that unique GUIDs are available when streaming...
		static bool FixGuidsForStreaming(Asura_StaticMessage& xMessage);
		static bool Project_FixGuidsForStreaming(Asura_StaticMessage& xMessage);
#endif	// defined(ASURA_USE_STREAMING)

public :
		bool Process(Asura_Handle fileHandle);
		bool Process(Asura_Chunk_Stream& xStream);
#ifdef ASURA_TOOLS
		//extracts a single message block from a chunk , and assigns a new message block ID
		u_short ProcessSingleMessageBlock(const char* pcChunkBuffer,u_short usBlockID) const;

		static void Create(Asura_SaveBlock& saveBlock,int iMessageSet);
		static bool Project_FillInChunkBuffer(char*& pcChunkBuffer, Asura_StaticMessage* pxMessage);
		//static bool Project_WriteToChunkStream(Asura_Chunk_Stream& xStream, Asura_StaticMessage* pxMessage);
		// Nasty hack to get around ShowHUDMessage structure being changed
		// (static message data structures should *never* be changed)
		static void FixData(Asura_StaticMessage* pxMessage);
		//Project_FixData should return false if the message wasn't dealt with by project code
		static bool Project_FixData(Asura_StaticMessage* pxMessage);
#endif

		//read/write a single message to a chunk stream
		static void ReadSingleMessageFromChunkStream(int iVersion,Asura_Chunk_Stream& xStream, Asura_StaticMessage* pxMessage,bool bHasToolsData);
		#ifdef ASURA_TOOLS
		static void WriteSingleMessageToChunkStream(Asura_Chunk_Stream& xStream, Asura_StaticMessage* pxMessage,bool bIncludeToolsData);
		#endif
		#ifdef ASURA_TOOLS
		//skip past a message in chunk stream
		static void SkipSingleMessageInChunkStream(int iVersion,Asura_Chunk_Stream& xStream,bool bHasToolsData);
		#endif
	

		//Gets the most recent masked version number
		static int GetCurrentMaskedVersion();



		enum ChunkFlags
		{
			ChunkFlag_HasToolsData = 0x00000001,
		};


		int NumberOfMessageBlocks;
};

///////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------------**
** Asura_Chunk_StaticMessages_InGame **
**-----------------------------------*/

//For saving state of any delayed messages that have been sent
class Asura_Chunk_StaticMessages_InGame : public Asura_Chunk_Header
{
public :
	bool Process(Asura_Chunk_Stream& xStream) const;
	bool Process(const char* pcChunkBuffer) const;

	static void Create(Asura_Chunk_Stream& xStream);
	static void Create(Asura_SaveBlock_Base& xSaveBlock);

};

///////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------**
** Asura_Chunk_Entity_NextGuid **
**-----------------------------*/

//Saves the next tools guid (cutscene or entity file depending on the range it appears in)
#ifdef ASURA_TOOLS
class Asura_Chunk_Entity_NextGuid : public Asura_Chunk_Header
{
	public :
		bool Process(Asura_Chunk_Stream& xStream) const;
		bool Process(Asura_Handle iFileHandle) const;
		static void Create(int iRange,Asura_SaveBlock_Base& xSaveBlock);

		Asura_Guid m_uNextGuid;
	
};
#endif //ASURA_TOOLS

///////////////////////////////////////////////////////////////////////////////////////////////
/*----------------------------------**
** Asura_Chunk_Entity_SecondaryFile **
**----------------------------------*/

//Saves version information for secondary entity files
#ifdef ASURA_TOOLS
class Asura_Chunk_Entity_SecondaryFile : public Asura_Chunk_Header
{
	public :
		bool Process(Asura_Handle iFileHandle) const;

		static void Create(const class Tools_SecondaryEntityFile* pxFile,Asura_SaveBlock_Base& xSaveBlock);

		enum ChunkFlags
		{
			ChunkFlag_CommonFile = 0x00000001,//secondary entity file intended for sharing across several main files
			ChunkFlag_MissionDir = 0x00000002,//secondary entity file that should be saved to the mission directory
		};

		int m_iFileVersion;
		int m_iNextID;
};
#endif



#ifdef ASURA_TOOLS
void BuildEntityTextureTree(class Asura_NameTree* pxNameTree,Asura_Guid uMinGuid,Asura_Guid uMaxGuid);
#endif


#endif //_ASURA_CHUNK_ENTITY_H_
