#pragma once

#include "..\munga\mover.h"

#define RIVET_MAXIMUM_LIFETIME 5.0f

//######################     Rivet ModelResource      ####################

struct Rivet__ModelResource :
	public Mover::ModelResource
{
	Damage
		damageData;
	ResourceDescription::ResourceID
		explosionResourceID;
};

//##########################################################################
//#####################    Mover::MakeMessage    ##########################
//##########################################################################

class Rivet__MakeMessage:
	public Mover::MakeMessage
{
public:
	EntityID
		shootingEntity;

	Rivet__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,
		const Motion &velocity,
		const Motion &acceleration,
		const EntityID &shooter
	):
		Mover::MakeMessage(
			message_ID,
			length,
			class_ID,
			owner_ID,
			resource_ID,
			instance_flags,
			origin,
			velocity,
			acceleration
		),
		shootingEntity(shooter)
			{}
	Rivet__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,
		const Motion &velocity,
		const Motion &acceleration,
		const EntityID &shooter
	):
		Mover::MakeMessage(
			message_ID,
			length,
			entity_ID,
			class_ID,
			owner_ID,
			resource_ID,
			instance_flags,
			origin,
			velocity,
			acceleration
		),
		shootingEntity(shooter)
			{}
};

//##########################################################################
//#############################    Rivet    ################################
//##########################################################################

class Rivet :
	public Mover
{
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data support
//
public:
	static Derivation *GetClassDerivations();
	static SharedData DefaultData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support
//
public:
	enum {
		DamageDataAttributeID = Mover::NextAttributeID,
		NextAttributeID
	};

private:
	static const IndexEntry AttributePointers[];

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

//
// public attribute declarations go here
//
public:
	Damage
		damageData;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model support
//
public:
	enum {
		DefaultFlags =
			Mover::DefaultFlags|NoCollisionVolumeFlag|NoCollisionTestFlag
	};

	typedef void (Rivet::*Performance)(Scalar time_slice);

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

	void
		MoveToTarget(Scalar time_slice);

public:

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
	typedef Rivet__ModelResource ModelResource;
	typedef Rivet__MakeMessage MakeMessage;

	static Rivet*
		Make(MakeMessage *creation_message);

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

	Logical
  	TestInstance() const;

	static ResourceDescription::ResourceID
		CreateModelResource(
			ResourceFile	*resource_file,
			const char		*model_name,
			NotationFile	*notation_file,
			const	ResourceDirectories  *directories,
			ModelResource *model = NULL
		);

protected:
	ResourceDescription::ResourceID
		explosionResourceID;
	Entity
		*shootingEntity;
};

