#pragma once

#include "memstrm.h"

class CString;
class ObjectStream;
class NameList;

typedef unsigned long ObjectID;
const ObjectID NullObjectID = 0;

typedef unsigned long RegisteredClassMemoryAddress;

class RegisteredClass SIGNATURED
{
public:
	enum ClassID
	{
		//
		//--------------
		// Munga classes
		//--------------
		//
		NullClassID = -1,
		TrivialClassID = 0,
		TrivialPlugClassID,
		TrivialNodeClassID,
		TrivialComponentClassID,
		AttributeWatcherOfClassID,
		ReceiverAttributeWatcherOfClassID,
		MessageTapClassID,
		DerivationClassID,
		TrivialReceiverClassID,
		EventClassID,
		NetworkEventClassID,
		GeneralEventQueueClassID,
		EventQueueClassID,
		DeferredEventQueueClassID,
		TrivialModelClassID,
		TrivialSubsystemClassID,
		TrivialEntityClassID,
		NetworkManagerClassID,
		EntityManagerClassID,
		EntityAttributeHandlerReferenceClassID,
		PersistentReferenceClassID,
		InterestManagerClassID,
		HostManagerClassID,
		ControlsInstanceClassID,
		ControlsMappingGroupClassID,
		ControlsOwnerClassID,
		ControlsManagerClassID,
		TrivialMoverClassID,
		AudioStateTriggerClassID,
		AudioMotionScaleClassID,
		AudioRendererClassID,
		AudioLocationClassID,
		ApplicationClassID,
		EntityGroupClassID,
		GaugeConnectionClassID,
		GaugeClassID,
		GaugeRendererClassID,
		CollisionAssistantClassID,
		RendererManagerClassID,
		AudioMotionTriggerClassID,
		AudioMotionRandomTriggerClassID,
		TerrainClassID,
		UnscalableTerrainClassID,
		AudioControlMixerClassID,
		AudioHingeScaleClassID,
		AudioControlSmootherClassID,
		AudioControlMultiplierClassID,
		AudioResourceSelectorClassID,
		DropZoneClassID,
		ExplosionClassID,
		PlayerClassID,
		JointSubsystemClassID,
		AudioResourceIndexClassID,
		AudioScalarScaleClassID,
		AudioControlSendClassID,
		GaugeEntityListClassID,
		DirectControlsInstanceClassID,
		EventControlsInstanceClassID,
		AudioSampleAndHoldClassID,
		AudioScalarTriggerClassID,
		AudioEnumerationTriggerClassID,
		AudioIntegerTriggerClassID,
		AudioLogicalTriggerClassID,
		EyeCandyClassID,
		WarehouseObjectClassID,
		WarehouseBinClassID,
		AudioControlsButtonTriggerClassID,
		IcomClassID,
		IcomManagerClassID,
		CameraShipClassID,
		CameraDirectorClassID,
		ExplosionResourceTableClassID,
		ApplicationTaskClassID,
		AudioIdleWatcherClassID,
		AudioControlEventClassID,
		AudioControlSequenceClassID,
		AudioControlSplitterClassID,
		ApplicationManagerClassID,
		DamageZoneClassID,
		AudioLFOClassID,
		AudioEnumerationDeltaTriggerClassID,
		AudioScalarDeltaTriggerClassID,
		ControlsStringClassID,
		ControlsStringManagerClassID,
		AudioEntityClassID,
		AudioLevelOfDetailClassID,
		LandmarkClassID,
		ScenarioRoleClassID,
		TeamClassID,
		AudioMessageWatcherClassID,
		AudioControlsButtonMessageWatcherClassID,
		GaugeAlarmManagerClassID,
		GaugeAlarmClassID,
		LightClassID,
		CulturalIconClassID,
		DoorFrameClassID,
		DoorClassID,

		//
		//---------------------------------
		// Class ID's for Munga LBE classes
		//---------------------------------
		//
		L4AudioLocationClassID = 1000,
		DirectPatchSourceClassID,
		Dynamic3DPatchSourceClassID,
		L4ApplicationClassID,
		PatchResourceClassID,
		Static3DPatchSourceClassID,
		L4AudioCollisionTriggerClassID,
		L4GaugeImageManagerClassID,
		L4ControlsManagerClassID,
		L4IcomClassID,
		L4IcomManagerClassID,
		PatchLevelOfDetailClassID,

		//
		//----------------------
		// Class ID's for RP
		//----------------------
		//
		RPL4ApplicationClassID = 2000,
		VTVClassID,
		RivetClassID,
		DemolitionPackClassID,
		BoosterClassID,
		RivetGunClassID,
		LaserDrillClassID,
		DemolitionPackDropperClassID,
		ChuteClassID,
		ScoreZoneClassID,
		VTVPowerClassID,
		ThrusterClassID,
		ControlsMapperClassID,
		CrusherClassID,
		BlockerClassID,
		RunnerClassID,
		RPDirectorClassID,
		RPTeamClassID,
		RPPlayerClassID,

		//
		//------------------
		// Class ID's for BT
		//------------------
		//
		BTL4ApplicationClassID = 3000,
		MechClassID,
		MissileClassID,
		MechSubsystemClassID,
		HeatableSubsystemClassID,
		CondenserClassID,
		HeatSinkClassID,
		HeatWatcherClassID,
		ReservoirClassID,
		GeneratorClassID,
		PoweredSubsystemClassID,
		SensorClassID,
		GyroscopeClassID,
		TorsoClassID,
		MyomersClassID,
		CapacitorClassID,
		EmitterClassID,
		LaserClassID,
		ParticleCannonClassID,
		AmmoBinClassID,
		AmmoFeederClassID,
		ProjectileWeaponClassID,
		GaussRifleClassID,
		BallisticWeaponClassID,
		MissileLauncherClassID,
		ProjectileClassID,
		SeekerClassID,
		SubsystemMessageManagerClassID,
		PPCClassID,
		PowerWatcherClassID,
		HUDClassID,
		RadarClassID,
		SearchlightClassID,
		ThermalSightClassID,
		BTTeamClassID,
		BTPlayerClassID,
		BTDirectorClassID,
		MechTechClassID,
		TurretClassID,

		//
		//------------------
		// Class ID's for ND
		//------------------
		//
		NDL4ApplicationClassID = 4000,
		AirplaneClassID,
		BulletClassID,
		MachineGunClassID,
		NDDirectorClassID,
		NDTeamClassID,
		NDPlayerClassID,

		//
		//----------------------
		// Class ID's for Tools
		//----------------------
		//
		ShapeClassID = 60000,
		ShapeGroupListClassID,
		ShapeGroupClassID,
		ShapePlaneClassID,
		ShapePolygonClassID,
		ShapeLineClassID,
		ShapePointClassID,
		VertexReferenceClassID,
		VertexClassID,
		MaterialLibraryClassID,
		MaterialReferenceClassID,
		MaterialClassID,
		TargaImageClassID,
		ShapeListClassID,
		SkeletonClassID,
		SkeletonJointClassID,
		SkeletonSiteClassID,
		SkeletonSegmentClassID,
		ModelClassID,

		//
		//---------------------------------
		// Class ID's for Munga W4 classes
		//---------------------------------
		//				    

		W4ApplicationClassID = 70000,
		W4ControlsManagerClassID,
		
		//
		//-------------
		// end of list
		//-------------
		//
		MaxClassID
	};

public:
	RegisteredClass(ClassID class_id = TrivialClassID);
	RegisteredClass(ObjectStream *stream);
	virtual ~RegisteredClass();

	Logical TestInstance() const;

public:
	ClassID GetClassID();

	static ClassID GetClassID(const CString &class_name_string);

	RegisteredClassMemoryAddress GetMemoryAddress();

public:
	static void BuildFromPage(ObjectStream *stream, NameList *name_list, ClassID class_ID, ObjectID object_ID);

private:
	ClassID classID;
};

inline RegisteredClass::ClassID RegisteredClass::GetClassID()
{
	Check(this);
	return classID;
}

inline RegisteredClassMemoryAddress RegisteredClass::GetMemoryAddress()
{
	Check(this);
	return (RegisteredClassMemoryAddress)this;
}

inline MemoryStream& MemoryStream_Read(MemoryStream* stream, RegisteredClass::ClassID *output)
{	return stream->ReadBytes(output, sizeof(*output)); }

inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const RegisteredClass::ClassID *input)
{	return stream->WriteBytes(input, sizeof(*input)); }