//	InterpolatedValue.h - Template class which can be used to obtain an
//						  interpolated value.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef INTERPOLATEDVALUE_H_
#define INTERPOLATEDVALUE_H_

///	Template class which can be used to obtain an interpolated value.
/*!
	This is necessary for working with a fixed timestep and variable framerate.

	\sa GameState
 */
template<typename T>
class InterpolatedValue
{
  public:
	///	Constructor.
	InterpolatedValue(const T& val):
	value(val),
	lastValue(val),
	returnValue(val)
	{
		
	};
	///	Copy constructor.
	InterpolatedValue(const InterpolatedValue<T>& other):
	value(other.value),
	lastValue(other.lastValue),
	returnValue(other.returnValue)
	{

	};
	///	Destructor.
	~InterpolatedValue() {};

	///	Returns the interpolated value.
	/*!
		\param dt The interpolation amount 0->1.

		\return A value interpolated between this value's previous value
		and its current value, determined by dt.

		This is just a bog-standard linear interpolation.
	 */
	const T& getValue(float dt)
	{
		returnValue = lastValue + ((value-lastValue)*dt);
		//lastValue = returnValue;

		return returnValue;
	};
	///	Returns the current value.
	/*!
		Note: This is not the interpolated value. It is simply the most
		recent value that has been set.
	 */
	operator const T&() {return value;};

	///	Assigns a new value.
	/*!
		As with all the assignment operators, this assigns value to lastValue,
		and value now becomes newVal.
	 */
	InterpolatedValue<T>& operator=(const T& newVal)
	{
		lastValue = value;
		value = newVal;

		return *this;
	};
	///	Addition assignment operator.
	InterpolatedValue<T>& operator+=(const T& newVal)
	{
		lastValue = value;
		value += newVal;

		return *this;
	};
	///	Subtraction assignment operator.
	InterpolatedValue<T>& operator-=(const T& newVal)
	{
		lastValue = value;
		value -= newVal;

		return *this;
	};
	///	Multiplication assignment operator.
	InterpolatedValue<T>& operator*=(const T& newVal)
	{
		lastValue = value;
		value *= newVal;

		return *this;
	};
	///	Division assignment operator.
	InterpolatedValue<T>& operator/=(const T& newVal)
	{
		lastValue = value;
		value /= newVal;

		return *this;
	};
  private:
	///	The current value.
	T value;
	///	The previous value.
	T lastValue;
	///	The value returned from getValue().
	/*!
		So we can return a reference rather than a copy.
	 */
	T returnValue;
};

#endif
