#include "entity.h"


void PhysicalEntity::AddConstantForce(Force NewForce)
{
	ConstantForces.MoveToHead();
	ConstantForces.InsertAfter(NewForce);
}

D3DXVECTOR3 PhysicalEntity::GetCurrentForces(float TimePeriod)
{
	//return all of the forces active over this time period
	//we need to sum all of the forces in the list
	D3DXVECTOR3 Total = D3DXVECTOR3(0,0,0);
	ConstantForces.MoveToHead();
	ConstantForces.Next();
	while(!ConstantForces.AtEnd())
	{
		//if it is a permanent force...
		if(ConstantForces.GetCurrent()->Data.Duration < 0)
		{
			Total+=ConstantForces.GetCurrent()->Data.ForceVector;
			ConstantForces.Next();
		}
		//if it is going to finish during this time period...
		else if(ConstantForces.GetCurrent()->Data.Duration <= TimePeriod)
		{
            //HACK: if the force finishes midway through the time period
			// that was requested, all I am doing is returning a force that is
			// that fraction of the original.  This would only be true if
			// force F for time t/2 = force F/2 for time t... which I'm not sure if it
			// is true.  I did a vague check which seemed to verify this
			Total+=ConstantForces.GetCurrent()->Data.ForceVector * (ConstantForces.GetCurrent()->Data.Duration / TimePeriod);
			//Now this force is over.
			ConstantForces.DeleteCurrent();
		}
		//the force is not finished in this time period
		else
		{
			Total+=ConstantForces.GetCurrent()->Data.ForceVector;
			//TODO: check this... we are returning a pointer to the node,
			// and looking at a stack allocated member of that pointer...
			// if we modify it, will it modify the one within the original
			// force object?  It should, but this is something to check
			// in case I'm way wrong.
			ConstantForces.GetCurrent()->Data.Duration-=TimePeriod;
			ConstantForces.Next();
		}
	}
	return Total;
}

void PhysicalEntity::UpdateVelocity(float TimeStep)
{
	D3DXVECTOR3 CurrentForces = GetCurrentForces(TimeStep);
	
	//using good old f=ma,
	D3DXVECTOR3 Acceleration = CurrentForces/Mass;

	//v1 = v0 + a*t
	Velocity += Acceleration*TimeStep;
}

void PhysicalEntity::UpdatePosition(float TimeStep)
{
    //s1 = s0 + v*t
	UpdateVelocity(TimeStep);
	Position += Velocity*TimeStep;
}

D3DXVECTOR3 PhysicalEntity::GetUpdatedPosition(float TimeStep)
{
	D3DXVECTOR3 NewPosition;
    UpdateVelocity(TimeStep);
	NewPosition = Position + Velocity*TimeStep;
	return NewPosition;
}