#pragma once

#include "..\munga\entity.h"
#include "..\munga\boxsolid.h"

enum ScoreZone__ScoreZoneType	{
		GlobalOneTime,
		LocalOneTime,
		GlobalSequential,
		LocalSequential
	} ;

//##########################################################################
//#####################    ScoreZone::ModelResource    #####################
//##########################################################################

struct ScoreZone__ModelResource
{
	ExtentBox
		extentBox;

	ScoreZone__ScoreZoneType
		scoreZoneType;

	Scalar
		pointValue;

};

//##########################################################################
//####################    ScoreZone::MakeMessage    ########################
//##########################################################################

class ScoreZone__MakeMessage:
	public Entity::MakeMessage
{
public:
	int
		sequenceNumber;

	ScoreZone__MakeMessage(
		Receiver::MessageID message_ID,
		size_t length,
		Entity::ClassID class_ID,
		const EntityID &owner_ID,
		ResourceDescription::ResourceID resource_ID,
		LWord instance_flags,
		const Origin &origin,
		int sequence
	):
		Entity::MakeMessage(
			message_ID,
			length,
			class_ID,
			owner_ID,
			resource_ID,
			instance_flags,
			origin
		),
		sequenceNumber(sequence)
			{}
	ScoreZone__MakeMessage(
		Receiver::MessageID message_ID,
		size_t length,
		const EntityID &entity_ID,
		Entity::ClassID class_ID,
		const EntityID &owner_ID,
		ResourceDescription::ResourceID resource_ID,
		LWord instance_flags,
		const Origin &origin,
		int sequence
	):
		Entity::MakeMessage(
			message_ID,
			length,
			entity_ID,
			class_ID,
			owner_ID,
			resource_ID,
			instance_flags,
			origin
		),
		sequenceNumber(sequence)
			{}
};

//##########################################################################
//############    ScoreZone::ProcessScoreRequestMessage    #################
//##########################################################################

class ScoreZone__ProcessScoreZoneRequestMessage :
	public Entity::Message
{
public:
	EntityID
		requestingEntity;

  Receiver::MessageID
		replyMessageID;

  Vector3D
		linearPosition;

  ScoreZone__ProcessScoreZoneRequestMessage(
		Receiver::MessageID message_ID,
		size_t length,
		const EntityID &reply_to,
		Receiver::MessageID reply_ID,
		Vector3D	vtv_pos
	):
		Entity::Message(message_ID, length),
		requestingEntity(reply_to),
		replyMessageID(reply_ID)
			{
				linearPosition = vtv_pos;
			}
};

//##########################################################################
//#################    ScoreZone::ReplyMessage    ##########################
//##########################################################################

class ScoreZone__ReplyMessage:
	public Entity::Message
{
public:
	Scalar
		pointValue;

	ScoreZone__ReplyMessage(
		Receiver::MessageID message_ID,
		size_t length,
		const  Scalar	point_value=0.0f
	):
		Entity::Message(message_ID, length)
			{
				pointValue = point_value;
			}
};

 //##########################################################################
 //##########################   ScoreZone    ################################
 //##########################################################################

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

	static SharedData DefaultData;


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Support
//
public:
	enum {
		ProcessScoreZoneRequestMessageID = Entity::NextMessageID,
		NextMessageID
	};

	typedef ScoreZone__MakeMessage MakeMessage;

private:
	static const HandlerEntry MessageHandlerEntries[];

protected:
	static MessageHandlerSet MessageHandlers;

public:

	void
		Dispatch(Receiver::Message *message);

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//

enum{
	ScoreZoneTypeAttributeID = Entity::NextAttributeID,
	PointValueAttributeID,
	NextAttributeID
};

private:

	static const IndexEntry AttributePointers[];

protected:

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

public:

	Scalar
		pointValue;

	typedef ScoreZone__ScoreZoneType ScoreZoneType;
	ScoreZoneType
		scoreZoneType;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//


enum ScoreZoneState{
		Active = Entity::StateCount,
		InActive,
		StateCount
};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	typedef ScoreZone__ModelResource ModelResource;

	static ScoreZone*
		Make(MakeMessage *creation_message);

	static Logical
		CreateMakeMessage(
			MakeMessage *creation_stream,
			NotationFile *model_file,
			const ResourceDirectories *directories
		);
	static ResourceDescription::ResourceID
		CreateModelResource(
			ResourceFile *resource_file,
			const char* model_name,
			NotationFile *model_file,
			const ResourceDirectories *directories,
			ModelResource *model=NULL
		);

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

	Logical
  	TestInstance() const;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Scorezone assignment
//

public:
	typedef ScoreZone__ProcessScoreZoneRequestMessage
		ProcessScoreZoneRequestMessage;
	typedef ScoreZone__ReplyMessage ReplyMessage;

	ExtentBox
		extentBox;
	int
		sequenceNumber;

protected:

	void
		ProcessScoreZoneRequestMessageHandler(
			ProcessScoreZoneRequestMessage *message
		);
};
