#ifndef __I3DSHANIMATION__
#define __I3DSHANIMATION__
/****************************************************************************************

		I3dShAnimation.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.

		I3DShTimeManager
		I3DShTimeBasedData
		ITimeBased
		I3DShParamInfo
		I3DShParamTimeLine


		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		12/08/99	Brice		Added ITimeBased::SetApproximateParamCount, to speed-up animation
								registration with tons of SetParam.
		4/27/99		Yann		Added ITimeBased::InvalidateCaches
		3/15/99		Greg		Added Reorder to API
		3/11/99		Greg		Added huge numbers of API calls to anim-related I3DSh*
		1/13/99		Greg		Changed MICROTICK3D to MicroTick (they're both int32s!)
		1/6/99		Greg		Added AllocatedTime to I3DShTimeManager
		1/4/99		Joshua		Added GetType to I3DShTimeBasedData

*****************************************************************************************/

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "IExtension.h"
#include "COMTypes.h"
#include "APITypes.h"
#include "I3DShTweener.h"


#define kCheckAllParams -1
#define kAutoParamID	'****'

//****** Globally Unique Ids **************************************************
MCDEFINE_GUID_SAFELIB(IID_I3DShTimeManager, 0x8c34ab4c, 0xd62a, 0x11d1, 0x84, 0x3, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);
MCDEFINE_GUID_SAFELIB(IID_ITimeBased, 0x39728dec, 0xc6d2, 0x11d2, 0xb3, 0xca, 0x30, 0x78, 0x30, 0x2c, 0x20, 0x30);
MCDEFINE_GUID_SAFELIB(IID_I3DShTimeBasedData, 0x8c34ab4d, 0xd62a, 0x11d1, 0x84, 0x3, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);
MCDEFINE_GUID_SAFELIB(IID_I3DParamInfo, 0x3c485821, 0xf655, 0x11d1, 0xab, 0x2c, 0x0, 0x60, 0x8, 0x15, 0xad, 0x45);
MCDEFINE_GUID_SAFELIB(IID_I3DParamTimeLine, 0x3c485822, 0xf655, 0x11d1, 0xab, 0x2c, 0x0, 0x60, 0x8, 0x15, 0xad, 0x45);


// Classes always available
MCDEFINE_GUID_SAFELIB(CLSID_StandardTimeBasedData, 0xff26f5cc, 0x4774, 0x11d2, 0x8f, 0x44, 0x0, 0x60, 0x97, 0x98, 0xe7, 0x7d);

struct I3DShParamInfo;
struct I3DShTweenerChainLink;
struct I3DShParamTimeLine;
struct ITimeBased;
struct I3DShTimeBasedData;
struct I3DShParamTimeLine;
struct IShTokenStream;
struct I3DShAttributesSet;
class  TMCPoint;
class  TParamHolder;
class  TTimeManager;


/// \addtogroup ShellInterface
/// \{

/// The time manager stores the current time and the allocated time.
///
struct I3DShTimeManager: public IMCUnknown
{
	// ****************************************************************************
	//								SetTime
	// 
	/// Set the current time.
	/// 
	/// \param time  The current time in MicroTicks. Use kTicksPerSecond to convert
	/// in seconds.
	/// 
	virtual MCCOMErr 	MCCOMAPI SetTime			(MicroTick time) = 0;
	
	// ****************************************************************************
	//								GetTime
	// 
	/// Returns the current time in MicroTicks. Use kTicksPerSecond to convert
	/// in seconds.
	/// 
	virtual MicroTick	MCCOMAPI GetTime			() = 0;
	
	// ****************************************************************************
	//								SetAllocatedTime
	// 
	/// Sets the allocated time.
	/// 
	/// \param time  The current time in MicroTicks. Use kTicksPerSecond to convert
	/// in seconds.
	/// 
	virtual MCCOMErr 	MCCOMAPI SetAllocatedTime	(MicroTick time) = 0;
	
	// ****************************************************************************
	//								GetAllocatedTime
	// 
	/// Returns the allocated time in MicroTicks.
	/// 
	virtual MicroTick	MCCOMAPI GetAllocatedTime	() = 0;
	
	// ****************************************************************************
	//								Read
	// 
	/// Reads a time manager.
	/// 
	/// \param stream  The stream from which we read.
	/// 
	virtual MCCOMErr 	MCCOMAPI Read				(IShTokenStream* stream) = 0;
	
	// ****************************************************************************
	//								Write
	// 
	/// Write a time manger.
	/// 
	/// \param stream  The stream to which we write.
	/// 
	virtual MCCOMErr 	MCCOMAPI Write				(IShTokenStream* stream) = 0;
	
	// ****************************************************************************
	//								EnableEventCreator
	// 
	/// Undocumented.
	/// 
	virtual boolean 	MCCOMAPI EnableEventCreator	(boolean enable) = 0;
};

/// \}


/// Callback object used with I3DShTimeBasedData.
///
struct IForEachTimeLineCallback //not derived from TMCObject as this is an interface
{
	/// Called for each parameter of a timebased object.
	///
	virtual void TimeLine(I3DShParamTimeLine* inTimeLine, I3DShTimeBasedData* inMerged) = 0;
};

/// \addtogroup ShellInterface
/// \{

/// The TimeBased Data is the object that stores the animation parameters of a timebased object.
///
struct I3DShTimeBasedData : public IMCUnknown
{
	
	// ****************************************************************************
	//								SetTimeBased
	// 
	/// Sets the timebased that owns this timebased data.
	/// 
	/// \param inTimeBased  A pointer to the timebased.
	/// 
	virtual void	 	MCCOMAPI SetTimeBased(ITimeBased* inTimeBased) = 0;
	
	// ****************************************************************************
	//								GetTimeBasedNoAddRef
	// 
	/// Returns a pointer to the timebased that owns this timebased data.
	/// 
	virtual ITimeBased* MCCOMAPI GetTimeBasedNoAddRef() = 0;
	
	// ****************************************************************************
	//								GetTimeBased
	// 
	/// Returns a pointer to the timebased that owns this timebased data.
	/// 
	/// \param outTimeBased  
	/// 
	virtual MCCOMErr	MCCOMAPI GetTimeBased(ITimeBased** outTimeBased) = 0;

	// ****************************************************************************
	//								SetValidForCurrentTime
	// 
	/// Mark as valid for current time.
	/// 
	virtual void		MCCOMAPI SetValidForCurrentTime() = 0;

	// ****************************************************************************
	//								InvalidateParams
	// 
	/// Mark all parameters as invalid. Will cause CheckParamForRead to recompute
	/// all parameters.
	///
	/// \param recursive  Set to true if you want to invalidate the sub groups.
	/// 
	virtual MCCOMErr MCCOMAPI InvalidateParams(boolean recursive) = 0;

	// ****************************************************************************
	//								MarkParamAsModified
	// 
	/// Mark a parameter as invalid. Create a keyframe if needed. Cause CheckParamForRead
	/// to be called.
	/// 
	/// \param index			The index of the parameter.
	/// \param createKeyframe	Should create a keyframe.
	/// 
	virtual MCCOMErr MCCOMAPI MarkParamAsModified(int32 index, boolean createKeyframe=true) = 0;
	
	// ****************************************************************************
	//								CheckParamForRead
	// 
	/// Should be called before accessing the value of an animated parameter.
	/// 
	/// \param index  The index of the parameter.
	/// 
	virtual void	 MCCOMAPI CheckParamForRead(int32 index) = 0;
	
	// ****************************************************************************
	//								SetApproximateParamCount
	// 
	/// Allow faster allocation of the array of parameters.
	/// 
	/// \param Count  Estimated number of parameters.
	/// 
	virtual void	 MCCOMAPI SetApproximateParamCount( uint32 Count ) = 0;
	
	// ****************************************************************************
	//								SetParam
	// 
	/// Adds a new parameter.
	/// 
	/// \param aparam			A pointer to the value of the parameter. (the paramater keeps a reference to this address so it should be be deleted until the timebased is destroyed)
	/// \param itsName			The name of the parameter.
	/// \param itsID			The ID of the parameter (as displayed in the UI). If itsID is equal to kAutoParamID, an unique id for the parameter is generated.
	/// \param itsType			The type of the parameter.
	/// \param graphColorIndex	The index of the color to be used in the graph editor (-1 means default color).
	/// 
	virtual int32	 MCCOMAPI SetParam(void *aparam, const int8* itsName, IDType itsID, IDType itsType, int8 graphColorIndex = -1) = 0; 

	// ****************************************************************************
	//								InsertParam
	// 
	/// Adds a new parameter and puts it at the specified index in the parameter list.
	/// 
	/// \param inIndex			The index of the param (if < 0 or larger than the param count, the param is added at the end)
	/// \param aparam			A pointer to the value of the parameter. (the paramater keeps a reference to this address so it should be be deleted until the timebased is destroyed)
	/// \param itsName			The name of the parameter.
	/// \param itsID			The ID of the parameter (as displayed in the UI). If itsID is equal to kAutoParamID, an unique id for the parameter is generated.
	/// \param itsType			The type of the parameter.
	/// \param graphColorIndex	The index of the color to be used in the graph editor (-1 means default color).
	///
	virtual int32	 MCCOMAPI InsertParam	(int32 inIndex, void* aParam, const int8* itsName, IDType itsID, IDType itsType, int8 graphColorIndex= -1) = 0;
	
	// ****************************************************************************
	//								SetParamGroup
	// 
	/// Adds a new parameter group.
	/// 
	/// \param aGroup   A pointer to the timebased that contains the sub parameters.
	/// \param itsName  The name of the parameter (as displayed in the UI). If itsID is equal to kAutoParamID, an unique id for the parameter is generated.
	/// \param itsID    The ID of the parameter.
	/// 
	virtual int32	 MCCOMAPI SetParamGroup(ITimeBased *aGroup, const int8* itsName, IDType itsID) = 0;

	// ****************************************************************************
	//								InsertParamGroup
	// 
	/// Adds a new parameter group and puts it at the specified index in the groups and parameters list.
	/// 
	/// \param aGroup   A pointer to the timebased that contains the sub parameters.
	/// \param itsName  The name of the parameter (as displayed in the UI). If itsID is equal to kAutoParamID, an unique id for the parameter is generated.
	/// \param itsID    The ID of the parameter.
	/// 
	virtual int32	 MCCOMAPI InsertParamGroup(int32 inIndex, ITimeBased *aGroup, const int8* itsName, IDType itsID) = 0;

	// ****************************************************************************
	//								RemoveParams
	// 
	// -Description: 
	//
	//	!!!WARNING!!! : removing parameters will shift the index of all
	//			the following parameters. You need to take this into account when 
	//			using this method. If your code kept an index on it's animated 
	//			parameters, these indexes need to be modified.
	//
	// -Parameters: index: the index from which to remove parameters
	//				count: the number of parameters to be removed
	//
	// -Returns:	MC_S_OK if succeed
	//
	// ****************************************************************************
	//								RemoveParams
	// 
	/// Remove animation parameters from index to index+count.
	///
	/// <P><B>!!!WARNING!!!</B> : removing parameters will shift the index of all
	///  the following parameters. You need to take this into account when 
	///	using this method. If your code kept an index on it's animated 
	///	parameters, these indexes need to be modified.</P>

	/// \param index  The index of the first parameter to remove
	/// \param count  The number of parameter to remove.
	/// 
	virtual MCCOMErr MCCOMAPI RemoveParams( const int32 index, const int32 count ) = 0;

	// ****************************************************************************
	//								ClearParams
	// 
	/// Removes all the parameters.
	/// 
	virtual MCCOMErr MCCOMAPI ClearParams() = 0;
	
	// ****************************************************************************
	//								EnableParam
	// 
	/// Enable/Disable a parameter.
	/// 
	/// \param index   The index of the parameter.
	/// \param enable  the state of the parameter.
	/// 
	virtual MCCOMErr MCCOMAPI EnableParam(int32 index, boolean enable) = 0;
	
	// ****************************************************************************
	//								ChangeParamGroup
	// 
	/// Change a param group (see SetParamGroup()).
	/// 
	/// \param aGroup  The new timebased.
	/// \param index   The index of the parameter.
	/// 
	virtual MCCOMErr MCCOMAPI ChangeParamGroup(ITimeBased *aGroup, int32 index) = 0;

	// ****************************************************************************
	//								CopyData
	// 
	/// Copy the data of this time based data into another one.
	/// 
	/// \param dest  The destination time based data.
	/// 
	virtual MCCOMErr MCCOMAPI CopyData(I3DShTimeBasedData *dest) = 0;

	// ****************************************************************************
	//								IsAnimated
	// 
	/// Returns true if animation is enabled.
	/// 
	virtual boolean  MCCOMAPI IsAnimated() const = 0;
	
	// ****************************************************************************
	//								SetAnimated
	// 
	/// Sets the animation of the timebaseddata.
	/// 
	/// \param animated  the animation state.
	/// 
	virtual void	 MCCOMAPI SetAnimated(boolean animated) = 0;

	// ****************************************************************************
	//								SetTimeManager
	// 
	/// Sets the timemanager (usually it is the time manager of the scene).
	/// 
	/// \param timeManager  A pointer to the time manager.
	/// 
	virtual void	 MCCOMAPI SetTimeManager(I3DShTimeManager *timeManager) = 0;
	
	// ****************************************************************************
	//								GetTimeManager
	// 
	/// Returns the timemanager (usually it is the time manager of the scene).
	/// 
	virtual void	 MCCOMAPI GetTimeManager(I3DShTimeManager**) = 0;

	/// For internal use only
	virtual TTimeManager* MCCOMAPI GetTimeManager() const = 0;
	
	// ****************************************************************************
	//								IsTimeLineExpanded
	// 
	/// Internal use only.
	/// 
	virtual boolean	 MCCOMAPI IsTimeLineExpanded() const = 0;
	
	// ****************************************************************************
	//								SetTimeLineExpanded
	// 
	/// Internal use only.
	/// 
	virtual void	 MCCOMAPI SetTimeLineExpanded(boolean isExpanded) = 0;

	// ****************************************************************************
	//								GetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual	TMCPoint MCCOMAPI GetDrawOrigin() = 0;
	
	// ****************************************************************************
	//								GetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual void	 MCCOMAPI SetDrawOrigin(TMCPoint& origin) = 0;
	
	// ****************************************************************************
	//								GetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual	int32	 MCCOMAPI GetParamHeight() = 0;
	
	// ****************************************************************************
	//								SetParamHeight
	// 
	/// Internal use only.
	/// 
	/// \param inParamHeight  
	/// 
	virtual void	 MCCOMAPI SetParamHeight(int32 inParamHeight) = 0;

	// ****************************************************************************
	//								GetSonsCount
	// 
	/// Returns the number of timebased that are children of this timebased.
	/// 
	virtual int32 	 MCCOMAPI GetSonsCount() const = 0;
	
	// ****************************************************************************
	//								GetSonByIndex
	// 
	/// Returns a pointer to one of the children of this timebased.
	/// 
	/// \param result     A pointer to the child
	/// \param index      The index of the parameter.
	/// \param itsType    The type of the parameter
	/// \param itsID      The ID of the child
	/// \param isGroup    True if this is a group.
	/// \param isEnabled  True if it is enabled.
	/// \return the name of the parameter
	/// 
	virtual const int8* MCCOMAPI GetSonByIndex(
									ITimeBased**			result,
									int32 					index, 
									IDType &				itsType, 
									IDType &				itsID,
									boolean &				isGroup, 
									boolean &				isEnabled) const = 0;
	
	// ****************************************************************************
	//								GetFather
	// 
	/// Returns the parent of the timebased.
	/// 
	/// \param parent  A pointer to the parent.
	/// 
	virtual void  	 MCCOMAPI GetFather(I3DShTimeBasedData** parent) const = 0;
									
	// ****************************************************************************
	//								GetParamInfoCount
	// 
	/// Returns the number of paramaters.
	/// 
	virtual int32 	 MCCOMAPI GetParamInfoCount() const = 0;
	
	// ****************************************************************************
	//								GetParamInfoByIndex
	// 
	/// Returns a pointer to a parameter indentified by its index.
	/// 
	/// \param paramInfo  A pointer to the parameter information.
	/// \param index      The index of the parameter.
	/// 
	virtual void	 MCCOMAPI GetParamInfoByIndex(I3DShParamInfo**paramInfo,int32 index) const = 0;
	
	// ****************************************************************************
	//								GetParamInfoByID
	// 
	/// Returns a pointer to a parameter with a certain ID.
	/// 
	/// \param paramInfo  A pointer to the parameter information.
	/// \param id         The ID of the parameter.
	/// 
	virtual void	 MCCOMAPI GetParamInfoByID(I3DShParamInfo**paramInfo,IDType id) const = 0;

	// ****************************************************************************
	//								FindParamInfoIndex
	// 
	/// Returns the index of the parameter with a certain ID or -1 if not found.
	/// 
	/// \param id         The ID of the parameter.
	/// 
	virtual int32	 MCCOMAPI FindParamInfoIndex(IDType id) const = 0;

	// ****************************************************************************
	//								GetID
	// 
	/// Returns the ID of the timebased data.
	/// 
	virtual IDType 	 MCCOMAPI GetID() const = 0; 

	// ****************************************************************************
	//								GetType
	// 
	/// Returns the type of the timebased data.
	/// 
	virtual IDType 	 MCCOMAPI GetType() const = 0; 
	
	// ****************************************************************************
	//								SetType
	// 
	/// Sets the type of the timebased data.
	/// 
	/// \param type       The type.
	/// \param className  Name of the class.
	/// 
	virtual void	 MCCOMAPI SetType(IDType type, const int8* className) = 0;

	// ****************************************************************************
	//								GetTime
	// 
	/// Returns the time of the last update of the timebased data.
	/// 
	/// 
	virtual MicroTick	MCCOMAPI GetTime() const = 0;

	// ****************************************************************************
	//								GetCurrentTime
	// 
	/// Returns the current time of this timebased data (time from timemanager or
	/// the timebased data local time).
	/// 
	/// 
	virtual MicroTick	MCCOMAPI GetCurrentTime() const = 0;

	// ****************************************************************************
	//								SetLocalTime
	// 
	/// Set a local time to this param, when read it won't use the scene time but this local time
	/// Set local time to kInvalidTime to use the scene time back.
	/// 
	/// \param inTime  The new local time or kInvalidTime
	/// 
	virtual	void     MCCOMAPI SetLocalTime(MicroTick inTime) = 0;

	// ****************************************************************************
	//								GetClassName
	// 
	/// Returns the classname of the timebased data.
	/// 
	/// 
	virtual const int8*	MCCOMAPI GetClassName() = 0;


	// ****************************************************************************
	//								GetName
	// 
	/// Returns the name of the timebased data.
	///
	virtual	const int8*		 	MCCOMAPI GetName		() const = 0;

	// ****************************************************************************
	//								GetMergedTimeLine
	// 
	/// Returns the merged time line that corresponds to this timebased data. This is
	/// the time line that sums up all the timelines of all the parameters. It returns
	/// true if this time line is computed only from default time lines (see additional
	/// time lines on the I3DShParamInfo).
	/// 
	/// \param timeline  A pointer to the timeline that is returned.
	/// 
	virtual boolean	 MCCOMAPI GetMergedTimeLine(I3DShParamTimeLine**timeline) = 0;

	// ****************************************************************************
	//								ForEachActiveTimeLine
	// 
	/// Calls a callback for each of the active timeline of the parameters.
	/// 
	/// \param callback  The callback function.
	/// 
	virtual MCCOMErr MCCOMAPI ForEachActiveTimeLine(IForEachTimeLineCallback *callback) = 0;

	// ****************************************************************************
	//								InvalidateTimeLine
	// 
	/// Invalidates the time line.
	/// 
	virtual MCCOMErr MCCOMAPI InvalidateTimeLine	() = 0;
	
	// ****************************************************************************
	//								InvalidateMerged
	// 
	/// Invalidates the merge time line.
	/// 
	virtual MCCOMErr MCCOMAPI InvalidateMerged		() = 0;

	// ****************************************************************************
	//								GetControllingAttributesSet
	// 
	/// Returns the I3DShAttributesSet that control this time based data (if any).
	/// 
	virtual I3DShAttributesSet*		MCCOMAPI GetControllingAttributesSet() const  = 0;

	// ****************************************************************************
	//								GetIndexInFather
	// 
	/// Returns the index of the timebased in the father time based data.
	/// 
	virtual int32				MCCOMAPI GetIndexInFather			() const = 0;
};

/// \}

/// \addtogroup ShellInterface
/// \{

/// Interface to an animated object.  Animated objects have animated parameters (I3DShTimeBasedData).  
/// The ITimeBased interface provides methods for toggling animation status for an object, and provides
/// access to the object's timebased data.
///
struct ITimeBased : public IMCUnknown
{
	virtual boolean					MCCOMAPI IsAnimated() const = 0;
	virtual void					MCCOMAPI SetAnimated(boolean animated) = 0;
	virtual I3DShTimeBasedData*		MCCOMAPI GetTimeBasedDataNoAddRef() = 0;
	virtual void					MCCOMAPI InvalidateCaches(int32 itsID, int32 itsIndex) = 0;
	virtual void					MCCOMAPI SetLocalTime(MicroTick inTime) = 0;
	virtual MicroTick				MCCOMAPI GetCurrentTime() const = 0;

	// ****************************************************************************
	//								CheckParameterRange
	// 
	/// This function can be used to enforce some range check for the parameters.
	//
	/// \param itsIndex		Index of the paramater in the time based data.
	/// \param value		Value of the parameter.
	/// \param type			Type of the parameter.
	//
	/// \return true if the parameter has been modified
	/// 
	virtual boolean					MCCOMAPI CheckParameterRange(int32 itsIndex, void* value, IDType type) const = 0;	

	// ****************************************************************************
	//								GetOverrideAttributesSet
	// 
	/// You can use this function to override the attributes set that will control
	/// a given sub param group of this time based. Usually, all sub groups are
	/// controlled by the attributes set that is controlling the current group.
	//
	/// \param subGroupParamID		ID of the sub group.
	/// 
	virtual I3DShAttributesSet*		MCCOMAPI GetOverrideAttributesSet(IDType subGroupParamID) = 0;
};
/// \}
  
/// \addtogroup ShellInterface
/// \{

/// I3DShParamInfo is implemented by Animated Parameters. Each animated object (see ITimeBased) has a list
/// of animated parameters (see I3DShTimeBasedData). This interface gives access to the attributes of the
/// parameter as well as its keyframes.
///
struct I3DShParamInfo : public IMCUnknown
{
	virtual void*	 			MCCOMAPI GetLeafParam	() const = 0;
	
	// ****************************************************************************
	//								GetType
	// 
	/// Returns the type of the parameter. (see PMapTypes.h for a list of types)
	///
	virtual	IDType	 			MCCOMAPI GetType		() const = 0;
	
	// ****************************************************************************
	//								GetID
	// 
	/// Returns the ID of the parameter (if the parameter is in the parameter map
	/// of a component, then it is the ID of the parameter in the Pmap).
	/// 
	virtual	IDType	 			MCCOMAPI GetID			() const = 0;
	
	// ****************************************************************************
	//								GetName
	// 
	/// Returns the name of the parameter.
	/// 
	virtual	const int8*		 	MCCOMAPI GetName		() const = 0;

	// ****************************************************************************
	//								GetParamValue
	// 
	/// Get the value of the parameter.
	/// 
	/// \param param        the result (must be of the correct type)
	/// 
	virtual void				MCCOMAPI GetParamValue	(TParamHolder& param) const = 0;

	// ****************************************************************************
	//								SetParamValue
	// 
	/// Set the value of the parameter.
	/// 
	/// \param param        the result (must be of the correct type)
	/// 
	virtual void				MCCOMAPI SetParamValue	(const TParamHolder& param) = 0;

	// ****************************************************************************
	//								GetGroupParam
	// 
	/// You can use this function to get a pointer to the sub parameter of this
	/// parameter. (use IsGroup() to see if it has sub parameters).
	/// 
	/// \param outGroupParam  A pointer to the group of sub parameters.
	/// 
	virtual MCCOMErr 			MCCOMAPI GetGroupParam				(ITimeBased** outGroupParam) const = 0;
	
	// ****************************************************************************
	//								GetGroupParamDataNoAddRef
	// 
	/// You can use this function to get a pointer to the sub parameter of this
	/// parameter. (use IsGroup() to see if it has sub parameters).
	/// 
	virtual I3DShTimeBasedData* MCCOMAPI GetGroupParamDataNoAddRef	() const = 0;
	
	// ****************************************************************************
	//								GetFather
	// 
	/// Returns a pointer to the parent of this parameter.
	/// 
	/// \param outFather  A pointer to the parent of this parameter.
	/// 
	virtual MCCOMErr			MCCOMAPI GetFather					(I3DShTimeBasedData** outFather) const = 0;

	// ****************************************************************************
	//								GetFatherNoAddRef
	// 
	/// Returns a pointer to the parent of this parameter.
	/// 
	virtual I3DShTimeBasedData*	MCCOMAPI GetFatherNoAddRef			() const = 0;

	// ****************************************************************************
	//								GetIndexInFather
	// 
	/// Returns the index of the parameter in the father time based data.
	/// 
	virtual int32				MCCOMAPI GetIndexInFather			() const = 0;

	// ****************************************************************************
	//								IsEnabled
	// 
	/// Returns true if the parameter is enabled.
	/// 
	virtual	boolean	 			MCCOMAPI IsEnabled		() const = 0;
	
	// ****************************************************************************
	//								IsValid
	// 
	/// Returns true if the parameted is valid.
	/// 
	virtual boolean 			MCCOMAPI IsValid		() const = 0;
	
	// ****************************************************************************
	//								IsGroup
	// 
	/// Returns true if the parameter is a group of parameters (see GetGroupParamDataNoAddRef()).
	/// 
	virtual	boolean	 			MCCOMAPI IsGroup		() const = 0;
	
	// ****************************************************************************
	//								IsValidGroup
	// 
	/// 
	virtual boolean 			MCCOMAPI IsValidGroup	() const = 0;


	// ****************************************************************************
	//								SetGroupParam
	// 
	/// Sets the pointer to the group of sub parameters of this parameter.
	/// 
	/// \param inGroupParam  A pointer to the group of sub parameters of this parameter.
	/// 
	virtual MCCOMErr			MCCOMAPI SetGroupParam	(ITimeBased* inGroupParam) = 0;
	
	// ****************************************************************************
	//								SetEnable
	// 
	/// Enables this parameter.
	/// 
	virtual MCCOMErr			MCCOMAPI SetEnable		(boolean inEnabled) = 0;

	// ****************************************************************************
	//								GetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual	TMCPoint 			MCCOMAPI GetDrawOrigin() = 0;
	
	// ****************************************************************************
	//								SetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual void	 			MCCOMAPI SetDrawOrigin(TMCPoint& origin) = 0;

	// ****************************************************************************
	//								SetShowGraph
	// 
	/// Internal use only.
	/// 
	virtual void	 			MCCOMAPI SetShowGraph(boolean shown) = 0;

	// ****************************************************************************
	//								GetShowGraph
	// 
	/// Internal use only.
	/// 
	virtual boolean	 			MCCOMAPI GetShowGraph() = 0;

	// ****************************************************************************
	//								GetGraphColorIndex
	// 
	/// Returns the index of the color to be used in the graph editor (-1 means default
	/// color).
	/// 
	virtual int32				MCCOMAPI GetGraphColorIndex() const = 0;

	// ****************************************************************************
	//								GetParamTimeLineCount
	// 
	/// Returns the number of time lines this param has.
	/// 
	virtual int32				MCCOMAPI GetParamTimeLineCount() const = 0;

	// ****************************************************************************
	//								AddParamTimeLine
	// 
	/// You can add time lines to a param using this function. Every additional time
	/// line is identified by a id that should be unique.
	//
	/// \param id		The unique id for this time line.
	/// 
	virtual int32				MCCOMAPI AddParamTimeLine(uint32 id) = 0;

	// ****************************************************************************
	//								RemoveParamTimeLine
	// 
	/// Removes one of the time line. Note that this function can only remove
	/// additional time lines.
	//
	/// \param index	Index of the time line to be removed.
	/// 
	virtual void				MCCOMAPI RemoveParamTimeLine(int32 index) = 0;

	// ****************************************************************************
	//								FindParamTimeLine
	// 
	/// Finds the time line index given an id. This function goes thought all the
	/// additional time lines and search for the one that has the correct id. It
	/// returns -1 if the time line is not found.
	//
	/// \param id		The unique id for the time line.
	/// 
	virtual int32				MCCOMAPI FindParamTimeLine(uint32 id) const = 0;

	// ****************************************************************************
	//								GetParamTimeLine
	// 
	/// Returns a pointer to the time line. The time line is the list of all the
	/// keyframes and tweeners that defines that value of this parameter over
	/// time. Note that a param can have multiple time lines.
	//
	/// \param index		Index if the time line if the param have multiple
	///                     time lines. 0 means the default time line.
	/// 
	virtual I3DShParamTimeLine*	MCCOMAPI GetParamTimeLine(int32 index = 0) const = 0;

	// ****************************************************************************
	//								GetParamTimeLineID
	// 
	/// Returns the unique id of one of the additional time line.
	//
	/// \param index		Index if the time line.
	/// 
	virtual uint32				MCCOMAPI GetParamTimeLineID(int32 index) const = 0;

	// ****************************************************************************
	//								GetActiveParamTimeLine
	// 
	/// Returns a pointer to the active time line. The active time line is one of
	/// the param time lines depending on the current animation edit mode.
	/// 
	virtual I3DShParamTimeLine*	MCCOMAPI GetActiveParamTimeLine() const = 0;

	// ****************************************************************************
	//								Invalidate
	// 
	/// Invalidates the param that will be recomputed by the next CheckParamForRead().
	/// 
	virtual void				MCCOMAPI Invalidate() = 0;

	// ****************************************************************************
	//								MarkParamAsModified
	// 
	/// Mark a parameter as invalid. Create a keyframe if needed. 
	//
	/// \param createKeyframe	Should create a keyframe.
	///
	/// \see I3DShTimeBasedData::MarkParamAsModified()
	/// 
	virtual MCCOMErr			MCCOMAPI MarkParamAsModified(boolean createKeyframe=true) = 0;
	
	// ****************************************************************************
	//								CheckParamForRead
	// 
	/// Should be called before accessing the value of an animated parameter.
	/// 
	/// \see I3DShTimeBasedData::CheckParamForRead()
	/// 
	virtual void				MCCOMAPI CheckParamForRead() = 0;
};

/// \}

/// \addtogroup ShellInterface
/// \{

/// A Time line is the list of tweeners and key frames that defines the animation of a
/// parameter.
///
struct I3DShParamTimeLine : public IMCUnknown
{
	// ****************************************************************************
	//								Clone
	// 
	/// Creates a copy of the time line.
	/// 
	/// \param outClone  A pointer to the copy that is returned.
	/// 
	virtual MCCOMErr	MCCOMAPI Clone			(I3DShParamTimeLine** outClone) const = 0;
	
	// ****************************************************************************
	//								CopyData
	// 
	/// Copy the current time into another.
	/// 
	/// \param inDest  The destination time line.
	/// 
	virtual MCCOMErr	MCCOMAPI CopyData		(I3DShParamTimeLine* inDest) const = 0;
	
	// ****************************************************************************
	//								IsValid
	// 
	/// returns True if the timeline is valid.
	/// 
	virtual boolean		MCCOMAPI IsValid		(MicroTick& outBadDelta) const = 0;
	
	// ****************************************************************************
	//								IsAnimated
	// 
	/// Returns true if the time line contains more than one key frame.
	/// 
	virtual boolean		MCCOMAPI IsAnimated		() const = 0;
	
	// ****************************************************************************
	//								AddLink
	// 
	/// Adds a new link to the timeline.
	/// 
	/// \param inNewLink          The link to add to the timeline
	/// \param inRemoveDuplicate  If true and the new link has the same time than another link, the "old" link is removed from the timeline
	/// 
	virtual MCCOMErr	MCCOMAPI AddLink		(I3DShTweenerChainLink* inNewLink, boolean inRemoveDuplicate) = 0;

	// ****************************************************************************
	//								InsertLinkAfter
	// 
	/// Adds a new link to the timeline.
	/// If inRemoveDuplicate is true, and the new link has the same time than another link, the "old" link is removed from the timeline
	/// 
	/// \param inPrevLink         The link before the link that should be added.
	/// \param inNewLink          The link to add.
	/// \param inRemoveDuplicate  
	/// 
	virtual MCCOMErr	MCCOMAPI InsertLinkAfter(const I3DShTweenerChainLink*	inPrevLink, 
												 I3DShTweenerChainLink*			inNewLink,
												 boolean						inRemoveDuplicate) = 0;

	// ****************************************************************************
	//								InsertLinkAfter
	// 
	/// Adds a new link to the timeline.
	/// If inRemoveDuplicate is true, and the new link has the same time than another link, the "old" link is removed from the timeline
	/// 
	/// \param inIndex            The index of the link before the link that should be added.
	/// \param inNewLink          The link to add.
	/// \param inRemoveDuplicate  
	/// 
	virtual MCCOMErr	MCCOMAPI InsertLinkAfter(int32 							inIndex, 
												 I3DShTweenerChainLink*			inNewLink,
												 boolean						inRemoveDuplicate) = 0;
	
	// ****************************************************************************
	//								RemoveLink
	// 
	/// Removes a link from the timeline
	/// 
	/// \param inLink  The link to remove.
	/// 
	virtual MCCOMErr	MCCOMAPI RemoveLink(
									I3DShTweenerChainLink* 			inLink) = 0;
	
	// ****************************************************************************
	//								AddKeyFrame
	// 
	/// Adds a keyframe to the timeline.
	/// 
	/// \param inTime   The time of the keyframe.
	/// \param inParam  The value of the keyframe
	/// \param inType   The type of the keyframe (see I3DShKeyFrame).
	/// 
	virtual MCCOMErr	MCCOMAPI AddKeyFrame	(MicroTick inTime, const void* inParam, int32 inType) = 0;

		// ****************************************************************************
	//								AddKeyFrame
	// 
	/// Adds a keyframe to the timeline.
	/// 
	/// \param inTime   The time of the keyframe.
	/// \param inParam  The value of the keyframe.
	/// 
	virtual MCCOMErr	MCCOMAPI AddKeyFrame	(MicroTick inTime, const TParamHolder& inParam) = 0;

	// ****************************************************************************
	//								RemoveKeyFrame
	// 
	/// Removes a keyframe from the time line.
	/// 
	/// \param inTime  The time of the keyframe.
	/// 
	virtual boolean		MCCOMAPI RemoveKeyFrame	(MicroTick inTime) = 0;
	
	// ****************************************************************************
	//								GetTweener
	// 
	/// Returns the tweener that interpolate between this keyframe and the next
	/// Returns a NULL pointer if inTime is after the last keyFrame.
	/// 
	/// \param inTime      The time for which we want the tweener.
	/// \param outTweener  A pointer to the tweener that is returned.
	/// 
	virtual MCCOMErr	MCCOMAPI GetTweener		(MicroTick inTime, I3DShTweener** outTweener) = 0;
	
	// ****************************************************************************
	//								SetTweener
	// 
	/// Sets the tweener that is used for the interpolation at a given time.
	/// 
	/// \param inTime     The time that is considered.
	/// \param inTweener  A pointer to the tweener.
	/// 
	virtual MCCOMErr	MCCOMAPI SetTweener		(MicroTick inTime, I3DShTweener* inTweener) = 0;
	
	// ****************************************************************************
	//								GetUniqueID
	// 
	/// Returns a uniqueID for the timeline.
	/// 
	virtual int32		MCCOMAPI GetUniqueID	() const = 0;

	// ****************************************************************************
	//								GetType
	// 
	/// Returns the type of the data.
	/// 
	virtual IDType 		MCCOMAPI GetType() const = 0;
		
	// ****************************************************************************
	//								GetTweenerChainLinkCount
	// 
	/// Returns the number of tweener chain link in the timeline.
	/// 
	virtual int32 	 	MCCOMAPI GetTweenerChainLinkCount() const = 0;
	
	// ****************************************************************************
	//								GetTweenerChainLinkByIndex
	// 
	/// Returns a tweener chain link.
	/// 
	/// \param inIndex  The index of the tweener chain link.
	/// \param outLink  A pointer to the chain link that is returned.
	/// 
	virtual MCCOMErr	MCCOMAPI GetTweenerChainLinkByIndex(
									int32 					inIndex,
									I3DShTweenerChainLink** outLink) const = 0;

	///return the tweener chain link at teh given index
	virtual I3DShTweenerChainLink* MCCOMAPI GetTweenerChainLinkByIndex(const int32 inIndex) const = 0;

	
	// ****************************************************************************
	//								GetPreviousLink
	// 
	/// Returns true previous link in the tweener chain.
	/// 
	virtual MCCOMErr 	MCCOMAPI GetPreviousLink(
									int32 					inTime, 
									I3DShTweenerChainLink** outLink, 
									int32* 					outIndex = NULL) const = 0;

	// ****************************************************************************
	//								Evaluate
	// 
	/// Calculates the parameter at the given time
	/// 
	/// \param time         the time when the timeline should be evaluated
	/// \param param        the result of the evaluation (must be of the correct size...)
	/// \param paramType    the type of the param (must match the one of the keyframes in the timeline
	/// \param ioLinkIndex  on imput, from where the seach should be started (optimization), on output the index of the link used to interpolate
	/// 
	virtual boolean		MCCOMAPI Evaluate	(const MicroTick time, void* param, const int32 paramType, int32* ioLinkIndex= NULL) const = 0;

	// ****************************************************************************
	//								Evaluate
	// 
	/// Calculates the parameter at the given time
	/// 
	/// \param time         the time when the timeline should be evaluated
	/// \param param        the result of the evaluation (must be of the correct type)
	/// \param ioLinkIndex  on imput, from where the seach should be started (optimization), on output the index of the link used to interpolate
	/// 
	virtual boolean		MCCOMAPI Evaluate	(const MicroTick time, TParamHolder& param, int32* ioLinkIndex= NULL) const = 0;

	// ****************************************************************************
	//								ResetTweenerChainLinks
	// 
	/// Removes all the chain links.
	/// 
	virtual MCCOMErr	MCCOMAPI ResetTweenerChainLinks() = 0;

	// ****************************************************************************
	//								GetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual	TMCPoint 	MCCOMAPI GetDrawOrigin() = 0;
	
	// ****************************************************************************
	//								SetDrawOrigin
	// 
	/// Internal use only.
	/// 
	virtual MCCOMErr	MCCOMAPI SetDrawOrigin(TMCPoint& origin) = 0;

	// ****************************************************************************
	//								WhenIsNextKeyFrame
	// 
	/// 
	virtual MCCOMErr 	MCCOMAPI WhenIsNextKeyFrame(
									const TTimeInfo& 		inPrevious, 
									TTimeInfo& 				outNext, 
									I3DShTweenerChainLink** outLink) const = 0;
	// ****************************************************************************
	//								WhenIsLastKeyFrame
	// 
	/// \return The time of the last KeyFrame of the time line (and -1 if there is no keyframe).
	/// 
	/// 
	virtual MicroTick 	MCCOMAPI WhenIsLastKeyFrame() const = 0;

	// ****************************************************************************
	//								Reorder
	// 
	/// Reorder the tweener chain links.
	/// 
	virtual MCCOMErr	MCCOMAPI Reorder() = 0;

	// ****************************************************************************
	//								GetFatherParamInfoNoAddRef
	// 
	/// Returns the father I3DShParamInfo.
	/// 
	virtual I3DShParamInfo*	MCCOMAPI GetFatherParamInfoNoAddRef() const = 0;

	// ****************************************************************************
	//								GetInitialValue
	// 
	/// Returns the value stored in the initial keyframe if there is one
	/// 
	/// \param buffer   A pointer to a buffer that can store the value.
	/// \param type     The type of the buffer (should be the same as the type of the keyframe usually
	///					although some limited conversions are possible).
	/// \param changed  Returns true if the value that is returned is different from the value that
	///					was originally pointed to by buffer.
	/// 
	virtual void		MCCOMAPI GetInitialValue(void* buffer,int32 type,boolean &changed) const = 0;

	// ****************************************************************************
	//								ApplyOffset
	// 
	/// Apply an offset to all the keyframes
	/// 
	/// \param param    A pointer to the value.
	/// \param type     The type of the value (should be the same as the type of the keyframe usually
	///					although some limited conversions are possible).
	/// 
	virtual MCCOMErr	MCCOMAPI ApplyOffset(const void* param,int32 type)=0;
};

/// \}

#endif
