#pragma once

#include "simulate.h"
#include "resource.h"
#include "damage.h"

class Entity;
class NotationFile;

//##########################################################################
//####################    Subsystem::ModelResource    ######################
//##########################################################################

struct Subsystem__SubsystemResource
{
	char
		subsystemName[32];
	RegisteredClass::ClassID
		classID;
	size_t
		subsystemModelSize;
	int
		segmentIndex;
	LWord
		subsystemFlags;
};

//##########################################################################
//########################    Subsystem    #################################
//##########################################################################

class Subsystem:
	public Simulation
{
//##########################################################################
// Shared Data Support
//
public:
	static Derivation *GetClassDerivations();
	static SharedData DefaultData;

//##########################################################################
// Construction and Destruction Support
//
public:
	typedef Subsystem__SubsystemResource SubsystemResource;

	~Subsystem();

	static ResourceDescription::ResourceID
		CreateStreamedSubsystem(
			NotationFile	*model_file,
        const char* model_name,
			const char* subsystem_name,
        SubsystemResource *subsystem_resource,
			NotationFile *subsystem_file,
			const ResourceDirectories *directories
		);

protected:
	Subsystem(
		Entity *entity,
		int subsystem_id,
		SubsystemResource *model,
		SharedData &shared_data
	);

  Subsystem(
		Entity 							*entity,
		int 								subsystem_id,
		const char 						*subsystem_name,
		RegisteredClass::ClassID 	class_id,
		SharedData 						&shared_data
	);

//##########################################################################
// Flag Support
//
public:
	enum {
		DontReplicateBit = Simulation::NextBit,
		NextBit
	};
	enum {
		DontReplicateFlag		= 1<<DontReplicateBit
	};

//##########################################################################
// Model support
//
public:
	typedef void
		(Subsystem::*Performance)(Scalar time_slice);

	void
		SetPerformance(Performance performance)
			{
				Check(this);
				activePerformance = (Simulation::Performance)performance;
			}

	Entity*
		GetEntity()
			{Check(this); return owningEntity;}


	int
		GetSegmentIndex()
		{Check(this); return segmentIndex;}

	const char*
		GetName()
			{Check(this); return subsystemName;}

	void
		WriteUpdateRecord(
			UpdateRecord *message,
			int update_model
		);

protected:
	Entity*
		owningEntity;

	char*
		subsystemName;

	int
		subsystemID;

	int
		segmentIndex;

//##########################################################################
// Test support
//
public:
	Logical
		TestInstance() const;

	enum
	{
		nextFaultIndex = 0
	};

	virtual Logical
		GenerateFault(int fault_index);

//##########################################################################
// Damage support
//
virtual void
	TakeDamage(Damage &damage)
	{
		Check(this); Check_Pointer(&damage); Check(damageZone);
		damageZone->TakeDamage(damage);
	}

DamageZone		*damageZone;

virtual void
	DeathReset(int /*reset_command*/)
		{}

virtual void
	DeathShutdown(int /*shutdown_command*/)
		{}
};

//##########################################################################
// Tool support
//
int
Get_Segment_Index(
	NotationFile *model_file,
	const char* model_name,
	const ResourceDirectories *directories,
	const char *desired_page
);
