//===========================================================================//
// File: EntityManager.hpp                                                   //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/29/94  JMA  Initial coding.                                            //
// 08/25/97  JMA  Infrastructure changes									 //
// 08/25/97  ECH	Infrastructure changes									 //
//---------------------------------------------------------------------------//
// Copyright (C) 1994, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "Entity.hpp"
#include "NameTable.hpp"

namespace Adept {

	class Entity;
	class DropZone;
	class Mover;

	//##########################################################################
	//########################    EntityStockpile    ###########################
	//##########################################################################

	class EntityStockpile:
		public Stuff::Plug
	{
		friend class EntityManager;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction and Destruction
	//
	protected:
		EntityStockpile();
		~EntityStockpile();

	public:
		void
			TestInstance();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Protected Data
	//
	protected:
		Stuff::ChainOf<Entity*>
			availableEntities;
	};

	//##########################################################################
	//########################    EntityManager    #############################
	//##########################################################################

	class EntityManager:
		public Stuff::Plug
	{
		friend class Entity;

	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction and destruction
	//
	public:
		EntityManager(ClassData *data = DefaultData);
		~EntityManager();

		void
			TestInstance();

		static EntityManager*
			GetInstance() 
		{
			return reinterpret_cast<EntityManager *>( GlobalPointers::GetGlobalPointer(EntityManagerGlobalPointerIndex));
		};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data support
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Entity Constrution & Destruction
	//
	public:
		void
			EntityCreated(Entity *entity);
		bool
			FryDeathRow();

		void
			SuspendExecution()
				{isExecutionSuspended = true;}
		void
			ResumeExecution()
				{isExecutionSuspended = false;}
		bool
			IsExecutionSuspended()
				{return isExecutionSuspended;}
		void
			PrefixParentToName(const Stuff::MString& parent_name, Entity *entity);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Drop Zone Support
	//
	public:
		DropZone*
			GetDropZone(ObjectID zone_id);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Mover (Vehicle) Support
	//
	public:
		virtual void
			AddMover(Mover *mover) {}
		virtual void
			RemoveMover(Mover *mover) {}
		virtual void
			AddPlayerVehicle(Mover *mover);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution
	//
	public:
		void
			PreCollisionExecute(Stuff::Time till);
		void
			PostCollisionExecute(Stuff::Time till);
		virtual void
			UpdateEntities();

		void
			RequestPostCollisionExecution(Entity *entity);
		void
			RemovePostCollisionExecution(Entity *entity);
		void
			RequestUpdate(Entity *entity);
		bool
			IsInPostCollisionExecution(Entity *entity);
		
		virtual void
			PreCollisionNetworkEvents(){STOP(("PURE VIRTUAL-NOT IMPLEMENTED"));};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//	
	
		bool 
			playerReady;

		virtual void SetPlayerReady(Entity *entity);

		bool PlayerReady()
		{
			return playerReady;
		}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Client Server Stuff
	//

	public:

		virtual void 
			ServeLocalEntities(Stuff::Time till);
		virtual void
			UpdateClientEntites(int connection, int message_type, Stuff::MemoryStream *message);


		virtual void RespawnClient(int id,Point3D trans){};
		virtual void StartClient(){};
		virtual void StopClient(){};

		virtual void StartServer(){};
		virtual void StopServer(){};

		virtual void
			StartUpdates(){};
		virtual void
			EndUpdates(){};

		virtual void
			Reset(){};

		virtual void
			BuildTileBoundDamageList();
		void
			ResetTileBoundDamageList();

		void
			SetNetworkDamageBit(bool bit_value, int bit_number);

		bool
			GetNetworkDamageBit(int bit_number);

	protected:
		Stuff::ChainOf<Entity*>
			postCollisionExecutors;
		Stuff::ChainOf<Entity*>
			updateEntities;

	public:
		Stuff::DynamicMemoryStream
			tileBoundDamage;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Armory
	//
	public:
		void
			StoreInArmory(Entity *entity);
		Entity*
			RequestFromArmory(const ResourceID &instance_resource_ID);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Accessor Functions
	//
	public:
		Stuff::TreeOf<Entity *, Stuff::MString>
			*GetNameSocket()
				{Check_Object(this); return &nameSocket;}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Protected Data
	//
	protected:
		Stuff::HashOf<EntityStockpile*, ResourceID>
			armory;
		Stuff::ChainOf<Entity*>
			deathRow;

		Stuff::TreeOf<Entity*, Stuff::MString>
			nameSocket;
		Stuff::HashOf<Entity*, ResourceID>
			resourceIDSocket;

		bool
			isExecutionSuspended;
	};

}


