#ifndef ENTITY_H
#define ENTITY_H

#include "Mesh.h"
#include <d3dx9.h>
#include "messages.h"
#include "llist.h"

//prototype for the message class
class Msg;

class Entity
{
public:
    Entity() {m_scale = 1.0f;}

	//This class should actually return some sort of array of vertices
	virtual void GetMeshes(Mesh** MeshArray) = 0;
	virtual int GetMeshCount() = 0;

	//This function should return how many messages it wants to send, and place
	// those messages in the array pointed to by SentMessages.
	virtual unsigned int GetAction(float TimeStep, Msg** SentMsgs) = 0;

	//This is just like the GetAction function, except it also sends a message to the
	// entity in the RecievedMsg parameter
	virtual unsigned int SendMsg(Msg* RecievedMsg, Msg** SentMsgs) = 0;

	virtual ~Entity() {return;}

	D3DXVECTOR3 Position;
    float m_scale;
    D3DXMATRIX m_rotationMatrix;
};


struct Force
{
	D3DXVECTOR3 ForceVector;  //The direction AND magnitude of the force
    float Duration;			  //how much longer it is in effect; <0 means infinite (i.e. gravity)
};

class PhysicalEntity : public Entity
{
public:
	virtual ~PhysicalEntity() {}
	virtual D3DXVECTOR3 GetGroundContactPoint() = 0;
	virtual void AddConstantForce(Force NewForce);
	
	//Updates the position based on the velocity;
	//****NOTE****: This will call the updatevelocity function, so the client
	// should NOT call both; this would update the velocity twice.  That is why
	// I made updatevelocity protected.  Also, things may get off if you call both
	// updateposition and getupdatedposition on the same step
	virtual void UpdatePosition(float TimeStep);
	//This function does NOT update the position; it gets the point that
	// the position would have been updated to.
	virtual D3DXVECTOR3 GetUpdatedPosition(float TimeStep);
	D3DXVECTOR3 Velocity;
	float Mass;
protected:
	//Updates the velocity based on any forces acting on the object
	virtual void UpdateVelocity(float TimeStep);
	virtual D3DXVECTOR3 GetCurrentForces(float TimePeriod);

    LList<Force> ConstantForces;  //The list of all constant forces acting on the object
};

class AbstractEntity : public Entity
{
	void GetMeshes(Mesh** MeshArray) {return;}
	int GetMeshCount() {return 0;}

	//This function should return how many messages it wants to send, and place
	// those messages in the array pointed to by SentMessages.
	virtual unsigned int GetAction(float TimeStep, Msg** SentMsgs) = 0;

	//This is just like the GetAction function, except it also sends a message to the
	// entity in the RecievedMsg parameter
	virtual unsigned int SendMsg(Msg* RecievedMsg, Msg** SentMsgs) = 0;
public:
	virtual ~AbstractEntity() {return;}
};




#endif
