#pragma once

#include "entity.h"

class BoxedSolid;

//##########################################################################
//#####################    Terrain::MakeMessage    ##########################
//##########################################################################

class Terrain__MakeMessage:
	public Entity::MakeMessage
{
public:
	Scalar
		localScale;

	Terrain__MakeMessage(
		Receiver::MessageID message_ID,
		size_t length,
		const EntityID &entity_ID,
		Entity::ClassID class_ID,
		ResourceDescription::ResourceID resource_ID,
		LWord instance_flags,
		const Origin &origin,
		Scalar scale
	):
		Entity::MakeMessage(
			message_ID,
			length,
			entity_ID,
			class_ID,
        EntityID::Null,
			resource_ID,
			instance_flags,
			origin
		),
		localScale(scale)
			{}
};

//##########################################################################
//###########################    Terrain    ################################
//##########################################################################

class Terrain:
	public Entity
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
	static Derivation *GetClassDerivations();

	static SharedData DefaultData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Support
//
typedef Terrain__MakeMessage MakeMessage;

#if 0
private:
	static const HandlerEntry MessageHandlerEntries[];

protected:
	static MessageHandlerSet MessageHandlers;
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
	enum {
		LocalScaleAttributeID = Entity::NextAttributeID,
		NextAttributeID
	};

private:
	static const IndexEntry AttributePointers[];

protected:
	//static AttributeIndexSet	AttributeIndex
	static AttributeIndexSet& GetAttributeIndex();

//
// public attribute declarations go here
//
public:
	Scalar localScale;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	static Terrain*
		Make(MakeMessage *creation_message);
	//
	// Warning... This function requires a properly set up strtok!!!!
	//
	static Logical
		CreateMakeMessage(
			MakeMessage *creation_message,
			NotationFile *model_file,
        const ResourceDirectories *directories
		);

	Terrain(
		MakeMessage *creation_message,
		SharedData &virtual_data = DefaultData
	);
	~Terrain();

	Logical
  	TestInstance() const;

protected:
	BoxedSolid *collisionVolumes;
};

//##########################################################################
//######################    UnscalableTerrain    ###########################
//##########################################################################

class UnscalableTerrain:
	public Entity
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
	static Derivation *GetClassDerivations();

	static SharedData DefaultData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	static UnscalableTerrain*
		Make(MakeMessage *creation_message);

	//
	// Warning... This function requires a properly set up strtok!!!!
	//
	static Logical
		CreateMakeMessage(
			MakeMessage *creation_message,
			NotationFile *model_file,
        const ResourceDirectories *directories
		);

	UnscalableTerrain(
		MakeMessage *creation_message,
		SharedData &virtual_data = DefaultData
	);
	~UnscalableTerrain();

	Logical
  	TestInstance() const;

protected:
	BoxedSolid *collisionVolumes;
};
