//===========================================================================//
// File:	registry.hh                                                         //
// Project: MUNGA           Brick: Registry Manager								  //
// Contents: Interface specification for Registry Manager						  //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 11/22/94  ECH  Initial coding.                                            //
// 11/29/94  JMA  Changed Identities to IDs                                  //
//---------------------------------------------------------------------------//
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc.                //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#if !defined(REGISTRY_HPP)
#	define REGISTRY_HPP

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

#	if !defined(OBJSTRM_HPP)
#		include <objstrm.hpp>
#	endif

#	if !defined(ENTITY_HPP) && 0
#		include <entity.hpp>
#	endif

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

#	if !defined(RESOURCE_HPP)
#		include <resource.hpp>
#	endif

	//##########################################################################
	//############################    Registry    ##############################
	//##########################################################################

	class Player;
	class Registry__MakeEntityMessage;
	class Entity;
	class Entity__MakeMessage;
	class Entity__SharedData;

	class Registry:
		public Receiver
	{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction, Destruction, and Testing
	//
	public:
		Registry(
			ClassID class_ID,
			SharedData &shared_data
		);
		Registry();
		~Registry();

		Logical
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Entity creation
	//
	public:
		//
		//-----------------------------------------------------------------------
		// MakeEntity
		//-----------------------------------------------------------------------
		//
		Entity*
			MakeEntity(Entity__MakeMessage *message);

		//
		//-----------------------------------------------------------------------
		// MakeTransferedEntity
		//
		// The registry creates an entity on this machine which
		// represents the transfer of ownership from the old host to this
		// host.
		//-----------------------------------------------------------------------
		//
		Entity*
			MakeTransferedEntity(
				HostID old_entity_host,
				EntityID old_entity_ID,
				void *old_entity_state_data
			);

		//
		//-----------------------------------------------------------------------
		// MakeEntityReplacement
		//
		// If a host abnormally terminates there may be replicants
		// hanging unattended by updates.  The host manager attempts
		// to create a replacement for the lost entity using the
		// replicant as a recipe for the replacement.
		//-----------------------------------------------------------------------
		//
		Entity*
			MakeEntityReplacement(
				HostID old_entity_host,
				EntityID replicant_entity_ID
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Entity data access
	//
	public:
		//
		//-----------------------------------------------------------------------
		// GetStaticData
		//
		// Provides an interface by which the static data for a class
		// may be accessed.
		//-----------------------------------------------------------------------
		//
		virtual Entity__SharedData*
			GetStaticData(ClassID entity_class);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Player creation
	//
	public:
		//
		//-----------------------------------------------------------------------
		// Create the player object
		//-----------------------------------------------------------------------
		//
		virtual Player*
			MakePlayer(Mission *mission);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Message Support
	//
	public:
		enum {
			MakeEntityMessageID = Receiver::NextMessageID,
			NextMessageID
		};

		typedef Registry__MakeEntityMessage
      	MakeEntityMessage;

		static const HandlerEntry
      	MessageHandlerEntries[];
		static MessageHandlerSet
      	MessageHandlers;

      void
      	MakeEntityMessageHandler(MakeEntityMessage *message);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Shared Data Support
	//
	public:
		static Derivation ClassDerivations;
		static SharedData DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Static object methods
	//
	public:
		static ResourceDescription::ResourceID
			CreateStaticObjectStreamResource(
				NotationFile *notation_file,
				ResourceFile *resource_file
			);

		void
			LoadStaticObjectStreamResource();
	};

	//~~~~~~~~~~~~~~~~~~~~~ Registry__MakeEntityMessage ~~~~~~~~~~~~~~~~~~~~~~~~

	class Registry__MakeEntityMessage:
		public Receiver::Message
	{
	public:
		Registry__MakeEntityMessage(size_t total_length);

      static Registry__MakeEntityMessage*
      	Make(Entity__MakeMessage *message);
	};

	//##########################################################################
	//#####################    RegistryObjectStream    #########################
	//##########################################################################

	class RegistryObjectStream:
   	public PlugStream
   {
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction, Destruction and testing
	//
   public:
		RegistryObjectStream();
		RegistryObjectStream(ResourceDescription *resource_description);
		~RegistryObjectStream();

      Logical
      	TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Implementations
	//
	private:
		RegisteredClass*
      	MakeObjectImplementation(Enumeration class_ID);

		void
         CreatedObjectImplementation(
         	RegisteredClass *object,
            ObjectID object_ID
         );

		void
      	BuildFromPageImplementation(
         	NameList *entry_list,
            Enumeration class_ID,
				ObjectID object_ID
         );

		void
      	BuiltFromPageImplementation(
         	Enumeration class_ID,
            ObjectID object_ID,
            const CString &object_name_string
         );
   };

#endif

