#include "Rewindable.h"
#include "Rewind_Manager.h"
#include "Utils.h"
#include "Global_Properties.h"

namespace Rewind
{
	// Last Pos Functions
	short LastPos::FloatToShort(float aFloat)
	{
		return (short)(aFloat*GlobalProperties::SAVE_FLOAT_PRECISION);
	}

	float LastPos::ShortToFloat(short aShort)
	{
		return ((float)aShort/GlobalProperties::SAVE_FLOAT_PRECISION);
	}

	void LastPos::SetPosition(glm::vec3 aPosition)
	{
		mX = FloatToShort(aPosition.x);
		mY = FloatToShort(aPosition.y);
		mZ = FloatToShort(aPosition.z);
	}

	glm::vec3 LastPos::GetPosition()
	{
		glm::vec3 position;

		position.x = ShortToFloat(mX);
		position.y = ShortToFloat(mY);
		position.z = ShortToFloat(mZ);

		return position;
	}

	// Rewindable Functions
	Rewindable::Rewindable()
	{
		RewindManager::I().AddRewinable(*this);
	}

	void Rewindable::InitRewindable(Geo::GeoObjTextured& aGeoObj)
	{
		mGeoObj = &aGeoObj;
	}

	void Rewindable::RewindMove(float aT)
	{
		mGeoObj->SetPosition(GLUtils::Lerp(mStartPos, mToPos, aT));
	}

	void Rewindable::AddPosition(bool aRemoveFront)
	{
		if (aRemoveFront)
			mLastPositions.pop_front();

		LastPos newPos;
		newPos.SetPosition(mGeoObj->GetPosition());
		mLastPositions.push_back(newPos);
	}

	void Rewindable::GoToNextPosition(bool aRemoveOldPosition)
	{
		if (mLastPositions.size() > 1)
		{
			if (aRemoveOldPosition)
				mLastPositions.pop_back();

			mStartPos = mGeoObj->GetPosition();
			mToPos = mLastPositions.back().GetPosition();
		}
	}

}