/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NAUTOMATIONPLAYER__
#define	__NAUTOMATIONPLAYER__


		#include "automation/automation_source.h"
		#include "automation/automated_property_provider.h"
		#include "motion/motion.h"	// FIXME move to motion_group
		#include "math/vector.h"
		#include "memory/bit_field.h"
		#include "memory/nauto_ptr.h"
		#include "memory/nshared_ptr.h"


namespace GS {
	namespace Automation {
		struct SourceGroup;

		using Core::Motion;
		using Core::MotionChannel;

/*!
	@short	Automation player.
	@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class	Player
{
public:

enum	AddSourceMode
{
		SourceSet			=	0,	///< Stop all current animation sources.
		SourceAdd					///< Add a new animation source.
};

enum
{
		FlagRelativeMotion	=	1	///< Motion sources should be evaluated in relative mode (not absolute)
};

protected:

		bool		active;

		SharedList <Motion *> motions;
		SharedList <Source *> sources;

		/// Only valid during evaluation.
		float		*weight_table;

public:

		AutoPtr <IPropertyProvider> property_provider;

/*!
	@name	Automation player.
	@{
*/
		BitField flags;

		/// Start an automation source.
		Source		*StartAutomation(Source *, float blend = Units::Sec(0.1), AddSourceMode = SourceSet, float weight = 1);

		/// Dispose of all sources.
		void		DisposeAutomationSources();

		bool		IsAutomated() const;
		bool		IsAutomationDone() const;
		bool		GetAutomationActive() const;
		void		SetAutomationActive(bool active);

		void		Evaluate(const Time &dt_time);

		void		BlendAutomatedProperty(MotionChannel::Type, float, float);

		/// Get animation sources.
		const SharedList <Source *> &GetSourceList() const { return sources; }
/// @}

/*!
	@name	Motion container.
	@{
*/

	// FIXME move to motion_group

		const SharedList <Motion *> &GetMotionList() const { return motions; }

		Motion		*GetMotion(const char *id) const;
		Motion		*GetMotionFromIndex(uint index) const;

		bool		AddMotion(Motion *motion);
		void		RemoveMotion(Motion *motion);
/// @}

		bool		FromMetaTag(NML::Tag &);
		NML::Tag	*AsMetaTag();

		Player();
		~Player();
};

	} // Automation
} // GS


#endif // __NAUTOMATIONPLAYER__
