//===========================================================================//
// File:	hostmgr.hpp                                                         //
// Project: MUNGA           Brick: Connection Library                        //
// Contents: Interface specification for base Host class                     //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 10/28/94  ECH  Initial coding.                                            //
// 11/03/94  ECH  Develop to munga spec												  //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(HOSTMGR_HPP)
#	define HOSTMGR_HPP

#	if !defined(NETWORK_HPP)
#		include <network.hpp>
#	endif

#	if !defined(HOST_HPP)
#		include <host.hpp>
#	endif

#	if !defined(TABLE_HPP)
#		include <table.hpp>
#	endif

#	if !defined(HASH_HPP)
#		include <hash.hpp>
#	endif

#	if !defined(ENTITYID_HPP)
#		include <entityid.hpp>
#	endif

	class Entity;
	class Entity__MakeMessage;

	//##########################################################################
	//#########################    HostManager    ##############################
	//##########################################################################

	class HostManager__EntityTransferOwnershipMessage;
	class HostManager__EntityNewOwnershipMessage;

	class HostManager:
		public NetworkClient
	{
		friend class HostManager__AllEntityIterator;
		friend class HostManager__DynamicMasterEntityIterator;
		friend class HostManager__DynamicReplicantEntityIterator;

		friend class HostManager__RemoteHostIterator;
		friend class HostManager__AllHostIterator;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Public types
	//
	public:
		typedef HostManager__AllEntityIterator
			AllEntityIterator;
		typedef HostManager__DynamicMasterEntityIterator
			DynamicMasterEntityIterator;
		typedef HostManager__DynamicReplicantEntityIterator
			DynamicReplicantEntityIterator;

		typedef HostManager__RemoteHostIterator
			RemoteHostIterator;
		typedef HostManager__AllHostIterator
			AllHostIterator;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction, Destruction, and testing
	//
	public:
		HostManager();
		~HostManager();

		Logical
			TestInstance() const;
		static void
			TestClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Execution control
	//
	public:
		void
			Shutdown();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Local and remote host methods
	//
	public:
		//
		//-----------------------------------------------------------------------
		// AdoptLocalHost, OrphanLocalHost
		//-----------------------------------------------------------------------
		//
		void
			AdoptLocalHost(Host *local_host);
		Host*
			OrphanLocalHost();

		//
		//-----------------------------------------------------------------------
		// GetLocalHostID, GetLocalHost
		//-----------------------------------------------------------------------
		//
		HostID
			GetLocalHostID();
		Host*
			GetLocalHost();

		//
		//-----------------------------------------------------------------------
		// AdoptRemoteHost, OrphanRemoteHost
		//-----------------------------------------------------------------------
		//
		void
			AdoptRemoteHost(Host *remote_host);
		void
			OrphanRemoteHost(Host *remote_host);

		//
		//-----------------------------------------------------------------------
		// GetRemoteHost, GetConsoleHost, FindHost
		//-----------------------------------------------------------------------
		//
		Host*
			GetRemoteHost(HostID host_ID);
		Host*
			GetConsoleHost();
		Host*
			FindHost(NetworkAddress net_address);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Entity methods
	//
	public:
		//
		//-----------------------------------------------------------------------
		// MakeUniqueEntityID
		//
		// Returns a unique entity indentity
		//-----------------------------------------------------------------------
		//
		EntityID
			MakeUniqueEntityID();

		//
		//-----------------------------------------------------------------------
		// NotifyOfEntityCreation
		//
		// This method is called to notify the host manager that a new entity
		// has been created on this host.
		//-----------------------------------------------------------------------
		//
		void
			NotifyOfEntityCreation(
				Entity *entity,
				Entity__MakeMessage *creation_message
			);

		//
		//-----------------------------------------------------------------------
		// NotifyOfEntityDestruction
		//
		// This method is called to notify the host manager that a entity is
		// being destroyed.
		//-----------------------------------------------------------------------
		//
		void
			NotifyOfEntityDestruction(Entity *entity);

		//
		//-----------------------------------------------------------------------
		// NotifyOfReplacementEntityCreation
		//
		// This method is called by the registry manager to notify the
		// host manager that a new replacement entity has been
		// created on this host.
		//-----------------------------------------------------------------------
		//
		void
			NotifyOfReplacementEntityCreation(
				Entity *entity,
				EntityID entity_ID,
				ClassID entity_class,
				LWord entity_type
			);

		//
		//-----------------------------------------------------------------------
		// GetEntityPointer
		//
		// Returns a pointer to the entity specified by entityID.
		//-----------------------------------------------------------------------
		//
		Entity*
			GetEntityPointer(const EntityID &entityID);

		//
		//-----------------------------------------------------------------------
		// IdentifyNewMapEntityHost
		//
		// For LAN specific solutions the host manager can return the
		// host id of a new map entity prior to its creation.  This
		// method uses an algorithm to determine this value and returns
		// it.
		//-----------------------------------------------------------------------
		//
		HostID
			IdentifyNewMapEntityHost(EntityID entity_ID);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Message Support
	//
	public:
		//
		// Message IDs
		//
		enum
		{
			NewHostMessageID = NetworkClient::NextMessageID,
			HostUpdateMessageID,
			EntityTransferOwnershipMessageID,
			EntityNewOwnershipMessageID,
			NextMessageID
		};

		//
		// Message types
		//
		typedef HostManager__EntityTransferOwnershipMessage
			EntityTransferOwnershipMessage;
		typedef HostManager__EntityNewOwnershipMessage
			EntityNewOwnershipMessage;

		//
		//-----------------------------------------------------------------------
		// EntityTransferOwnership
		//-----------------------------------------------------------------------
		//
		void
			EntityTransferOwnershipHandler(EntityTransferOwnershipMessage*);

		//
		//-----------------------------------------------------------------------
		// EntityNewOwnership
		//-----------------------------------------------------------------------
		//
		void
			EntityNewOwnershipHandler(EntityNewOwnershipMessage*);

		//
		//-----------------------------------------------------------------------
		// Message table, Shared data
		//-----------------------------------------------------------------------
		//
		static const HandlerEntry
			MessageHandlerEntries[];
		static MessageHandlerSet
			MessageHandlers;

		static Derivation
			ClassDerivations;
		static SharedData
			DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Private data
	//
	private:
		Host
			*localHost;
		TableOf<Host*, HostID>
			remoteHostSocket;
		TableOf<Host*, HostID>
			allHostSocket;
		TableIteratorOf<Host*, HostID>
			*allHostIterator;

		//
		// The last entity id to be allocated, used to allocate a new one
		//
		EntityID
			lastEntityID;

		//
		// The entity index socket holds all entities, static, dynamic,
		// replicant, etc...
		//
		HashOf<Entity*, EntityID>
			entityIndexSocket;
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~~~ HostManager inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~

	inline Entity*
		HostManager::GetEntityPointer(const EntityID &entity_ID)
	{
		Check(this);
		return entityIndexSocket.Find(entity_ID);
	}

	inline Host*
		HostManager::GetLocalHost()
	{
		Check(this);

		//
		// GAC removed this so we can use the call to see if a
		// local host exists or not, there doesn't seem to be
		// any call for this.  Host Manager initializes localHost
		// to NULL and all routines check it before use so this
		// shouldn't cause any problems.
		//
		// Check(localHost);

		return localHost;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~ HostManager messages ~~~~~~~~~~~~~~~~~~~~~~~~~~

	class HostManager__EntityTransferOwnershipMessage:
		public NetworkClient::Message
	{
	public:
		HostManager__EntityTransferOwnershipMessage():
			NetworkClient::Message(
				HostManager::EntityTransferOwnershipMessageID,
				sizeof(HostManager__EntityTransferOwnershipMessage)
			)
			{}
	};

	class HostManager__EntityNewOwnershipMessage:
		public NetworkClient::Message
	{
	public:
		HostManager__EntityNewOwnershipMessage():
			NetworkClient::Message(
				HostManager::EntityNewOwnershipMessageID,
				sizeof(HostManager__EntityNewOwnershipMessage)
			)
			{}
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllEntityIterator ~~~~~~~~~~~~~~~~~~

	class HostManager__AllEntityIterator:
		public Host__AllEntityIterator
	{
	public:
		HostManager__AllEntityIterator(HostManager *host_manager);
		~HostManager__AllEntityIterator();
	};

	//~~~~~~~~~~~~~~~~~ HostManager__DynamicMasterEntityIterator ~~~~~~~~~~~~~~~

	class HostManager__DynamicMasterEntityIterator:
		public Host__DynamicMasterEntityIterator
	{
	public:
		HostManager__DynamicMasterEntityIterator(HostManager *host_manager);
		~HostManager__DynamicMasterEntityIterator();
	};

	//~~~~~~~~~~~~~~~~~ HostManager__DynamicReplicantEntityIterator ~~~~~~~~~~~~

	class HostManager__DynamicReplicantEntityIterator:
		public Host__DynamicReplicantEntityIterator
	{
	public:
		HostManager__DynamicReplicantEntityIterator(HostManager *host_manager);
		~HostManager__DynamicReplicantEntityIterator();
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__RemoteHostIterator ~~~~~~~~~~~~~~~~~

	class HostManager__RemoteHostIterator:
		public TableIteratorOf<Host*, HostID>
	{
	public:
		HostManager__RemoteHostIterator(HostManager *host_manager);
		~HostManager__RemoteHostIterator();
	};

	//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllHostIterator ~~~~~~~~~~~~~~~~~~~~

	class HostManager__AllHostIterator:
		public TableIteratorOf<Host*, HostID>
	{
	public:
		HostManager__AllHostIterator(HostManager *host_manager);
		~HostManager__AllHostIterator();
	};

#endif

