//===========================================================================//
// File: Connection.hpp                                             
// Project: MUNGA           Brick: Replicator                                //
// Contents:															
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
//	08/24/97  JMA  Infrastructure changes.								
// 08/25/97  ECH  Infrastructure changes.                                    //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1997, Virtual World Entertainment, Inc.                //
//                      PROPRIETARY AND CONFIDENTIAL                         //
//===========================================================================//

#pragma once

#include "Adept.hpp"
#include "ReplicatorID.hpp"
#include "Network.hpp"

namespace Adept {

	//##########################################################################
	//#######################    Connection    ##########################
	//##########################################################################

	class Replicator;
	class Replicator__CreateMessage;
	class Replicator__Message;

	typedef InBox__Message Connection__Message;

	class Connection:
		public InBox
	{
		friend class Network;

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

		static ClassData
			*DefaultData;

		typedef Connection__Message Message;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction, Destruction, and Testing
	//
	public:
		Connection(
			BYTE id,
			DWORD network_address,
			const char *name
		);

		//Connection(
		//	BYTE id,
		//	DWORD network_address,
		//	const char *name
		//);

		~Connection();

		static Connection
			*Local;
		static Connection
			*Server;
		static Connection
			*Hermit;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data & Message Support
	//
	public:
		enum
		{
			ReplicateMessageID = InBox::NextMessageID,
			ReplicatorMessageID,
			NextMessageID
		};

		void
			ReplicateMessageHandler(const Replicator__CreateMessage *message);
		void
			ReplicatorMessageHandler(const Message *message);

	protected:
		static const MessageEntry
			MessageEntries[];

	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Public Interface
	//
	public:
		const ReplicatorID&
			GetNextReplicatorID();

		int 
			GetLastReplicatorIDUsed()
		{
			return nextReplicatorID.localID;
		}

		void
			RegisterReplicatorID(const ReplicatorID &id);

		void
			AddReplicator(Replicator *replicator);
		void
			RemoveReplicator(Replicator *replicator);
		void
			ReplicatorCreated(
				Replicator *replicator
			);

		void
			ReplicatorDestroyed(Replicator *replicator);

		void
			SendToMaster(
				Replicator *replicator,
				const Replicator__Message *message
			);

		void
			BroadcastToReplicants(
				Replicator *replicator,
				const Replicator__Message *message
			);

		Replicator*
			FindReplicator(const ReplicatorID &id);

		void
			DeleteChildren(void);

	protected:
		Stuff::SafeChainOf<Replicator*>
			allReplicators;

		int replicatorCount;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Accessors
	//
	public:
		BYTE
			GetID()
				{Check_Object(this); return connectionID;}
		const char*
			GetConnectionName()
				{Check_Object(this); return connectionName;}

		DWORD
			GetNetworkAddress()
				{Check_Object(this); return networkAddress;}
		void
			SetNetworkAddress(DWORD network_address)
				{Check_Object(this); networkAddress = network_address;}

		void
			SetConnectionUsed(int connection);
		void
			ClearConnectionUsed(int connection);
		bool
			ISConnectionUsed(int connection);

	protected:
		BYTE
			connectionID;
		DWORD
			networkAddress;
		Stuff::MString
			connectionName;
		ReplicatorID
			nextReplicatorID;
		BYTE
			dataTransferBox,
			*dataBuffer,
			*dataPointer;
		size_t
			bytesToTransfer;

		BYTE
			usedConnections[8192];

		
    public:
        static void DeleteReplicator(Replicator* p);
	};
}
