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

		I3DShTweener.h

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

		Author:	Ray Dream (from I3DSHUTI.H)
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		5/6/99		Greg		Added back pointer to chain link
		3/11/99		Greg		Added huge numbers of API calls to anim-related I3DSh*

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

#ifndef __I3DSHTWEENER__
#define __I3DSHTWEENER__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "COMTypes.h"
#include "MCCountedPtr.h"
#include "APITypes.h"

//****** Globally Unique Ids **************************************************

MCDEFINE_GUID_SAFELIB(IID_I3DShTweener, 0x385e1bf2, 0xcb8b, 0x11d2, 0x8b, 0x89, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);
MCDEFINE_GUID_SAFELIB(IID_I3DShTweenerChainLink, 0x385e1bf3, 0xcb8b, 0x11d2, 0x8b, 0x89, 0x0, 0x60, 0x97, 0xb, 0xc5, 0x21);

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

struct I3DShKeyFrame;
struct I3DShTweenerChainLink;
struct I3DShParamTimeLine;


/// \addtogroup ShellInterface
/// \{

// ****************************************************************************
//								I3DShTweener
// 
/// Defines Animation Tweeners. Tweeners are 3D Components that describe the
/// interpolation between key frames.
/// 
struct I3DShTweener : public IMCUnknown
{
	// ****************************************************************************
	//								Tween
	// 
	/// Interpolates between two keyframes.
	/// 
	/// \param res    The result of the interpolation.
	/// \param time   The time of the interpolation
	/// \param alink  The tweener chain link that owns this tweener.
	/// 
	virtual MCCOMErr MCCOMAPI Tween								(I3DShKeyFrame* res, int32 time, I3DShTweenerChainLink* alink) const = 0;
	
	// ****************************************************************************
	//								Edit
	// 
	/// \deprecated. Doesn't do anything now.
	/// 
	/// \param tweener    Not documented.
	/// \param chainLink  Not documented.
	/// 
	virtual void	 MCCOMAPI Edit								(I3DShTweener** tweener, I3DShTweenerChainLink* chainLink) const = 0;
	
	// ****************************************************************************
	//								SetLink
	// 
	/// Sets the link that owns this tweener.
	/// 
	/// \param inLink  A pointer to the tweener chain link
	/// 
	virtual void					MCCOMAPI	SetLink			(I3DShTweenerChainLink* inLink) = 0;
	
	// ****************************************************************************
	//								GetLinkNoAddRef
	// 
	/// Returns the link that owns this tweener.
	/// 
	virtual I3DShTweenerChainLink* 	MCCOMAPI	GetLinkNoAddRef	() = 0;

	// ****************************************************************************
	//								NeedKeyFrameTangents
	// 
	/// Returns true if the tweener need to have tangents on the keyframes.
	/// 
	virtual boolean					MCCOMAPI	NeedKeyFrameTangents() const = 0;
};

/// \}

/// Encapsulates the time and index of a keyframe
///
class TTimeInfo : public TMCObject
{
	public:
		void 		Set				(MicroTick inTime, int32 inIndex) 
												{ fTime = inTime; fIndex = inIndex; }
		void 		SetToBeforeAll	() 			{ fTime = -1; fIndex = 1; 			}
		void 		SetToZero		() 			{ fTime = 0; fIndex = 1; 			}

		boolean 	IsBeforeAll		() const 	{ return fTime < 0; }
		MicroTick 	GetTime			() const 	{ return fTime; 	}
		int32 		GetIndex		() const 	{ return fIndex; 	}

		boolean 	operator==		(const TTimeInfo &t1) const 
												{ 
													return ((fTime == t1.fTime) && (fIndex == t1.fIndex));
												} 
		boolean 	operator<		(const TTimeInfo &t2) const 
												{ 
													if (fTime < t2.fTime) return true;	
													else if (fTime > t2.fTime) return false;
													else return fIndex < t2.fIndex;
												}
	protected:

		MicroTick 	fTime;
		int32 		fIndex; ///< should be REMOVED (and forbid to have keys at the same time)
};


/// \addtogroup ShellInterface
/// \{

/// The tweener chain link is an element of a time line (see I3DShParamTimeLine). It owns
/// a tweener and a keyframe.
///
struct I3DShTweenerChainLink : public IMCUnknown
{
public:
	
	// ****************************************************************************
	//								Clone
	// 
	/// Creates a copy of the tweener chain link.
	/// 
	/// \param outLink           The copy.
	/// \param inFatherTimeLine  The time line.
	/// 
	virtual MCCOMErr 		MCCOMAPI Clone				(I3DShTweenerChainLink** outLink, I3DShParamTimeLine*	inFatherTimeLine) const = 0;
	
	// ****************************************************************************
	//								CopyData
	// 
	/// Copy the data of a tweener chain link into another tweener chain link.
	/// 
	/// \param inDest  The destination tweener chain link.
	/// 
	virtual MCCOMErr		MCCOMAPI CopyData			(I3DShTweenerChainLink* inDest) const = 0;

	// ****************************************************************************
	//								GetTweenerNoAddRef
	// 
	/// Returns a pointer to the tweener.
	/// 
	virtual I3DShTweener*	MCCOMAPI GetTweenerNoAddRef	(boolean inDefaultIfNone = false, boolean inCreateIfNone = false) = 0;
	
	// ****************************************************************************
	//								GetTweener
	// 
	/// Returns a pointer to the tweener.
	/// 
	virtual MCCOMErr		MCCOMAPI GetTweener			(I3DShTweener** outTweener, boolean inDefaultIfNone = false,	boolean	inCreateIfNone = false) = 0;
	
	// ****************************************************************************
	//								SetTweener
	// 
	/// Sets a new tweener
	/// 
	virtual MCCOMErr		MCCOMAPI SetTweener			(I3DShTweener* inTweener) = 0;
	
	// ****************************************************************************
	//								GetKeyFrameNoAddRef
	// 
	/// Returns a pointer to the keyframe.
	/// 
	virtual I3DShKeyFrame* 	MCCOMAPI GetKeyFrameNoAddRef() const = 0;
	
	// ****************************************************************************
	//								GetKeyFrame
	// 
	/// Returns a pointer to the keyframe.
	/// 
	virtual MCCOMErr	 	MCCOMAPI GetKeyFrame		(I3DShKeyFrame** outKeyFrame) const = 0;
	
	// ****************************************************************************
	//								SetKeyFrame
	// 
	/// Sets the key frame.
	/// 
	virtual MCCOMErr		MCCOMAPI SetKeyFrame		(I3DShKeyFrame* inKeyFrame) = 0;

	// ****************************************************************************
	//								KeyFrameCanHaveTangents
	// 
	/// Returns true if the keyframe of this link can have tangents (this depends on
	/// the keyframe as well as the previous and next tweener).
	/// 
	virtual boolean			MCCOMAPI KeyFrameCanHaveTangents() const = 0;
		
	// ****************************************************************************
	//								GetTime
	// 
	/// Returns the time of the key frame associated with this chain link.
	/// 
	virtual MicroTick		MCCOMAPI GetTime			() const = 0;

	// ****************************************************************************
	//								SetTime
	// 
	/// Sets the time of the key frame associated with this chain link.
	/// 
	virtual MCCOMErr		MCCOMAPI SetTime			(MicroTick inTime) = 0;
	
	// ****************************************************************************
	//								GetNextNoAddRef
	// 
	/// Returns the next tweener chain link in the time line.
	/// 
	virtual I3DShTweenerChainLink*	MCCOMAPI GetNextNoAddRef	() = 0;
	
	// ****************************************************************************
	//								GetNext
	// 
	/// Returns the next tweener chain link in the time line.
	/// 
	virtual MCCOMErr				MCCOMAPI GetNext	(I3DShTweenerChainLink** outNext) const = 0;
	
	// ****************************************************************************
	//								SetNext
	// 
	/// Sets the next chain link in the time line.
	/// 
	virtual MCCOMErr	 			MCCOMAPI SetNext	(I3DShTweenerChainLink* inNext) = 0;

	// ****************************************************************************
	//								GetPrevNoAddRef
	// 
	/// Returns the previous chain link in the time line.
	/// 
	virtual I3DShTweenerChainLink*	MCCOMAPI GetPrevNoAddRef	() = 0;
	
	// ****************************************************************************
	//								GetPrev
	// 
	/// Returns the previous chain link in the time line.
	/// 
	virtual MCCOMErr				MCCOMAPI GetPrev	(I3DShTweenerChainLink** outPrev) const = 0;
	
	// ****************************************************************************
	//								SetPrev
	// 
	/// Sets the previous chain link in the time line.
	/// 
	virtual MCCOMErr	 			MCCOMAPI SetPrev	(I3DShTweenerChainLink* inPrev) = 0;
	
	// ****************************************************************************
	//								GetFatherNoAddRef
	// 
	/// Returns the time line that contains this tweener chain link
	/// 
	virtual I3DShParamTimeLine*		MCCOMAPI GetFatherNoAddRef	() = 0;
	
	// ****************************************************************************
	//								RemoveFromChain
	// 
	/// Removes the chain link from the time line.
	/// 
	virtual MCCOMErr		MCCOMAPI RemoveFromChain	() = 0;
	
	// ****************************************************************************
	//								InsertAfter
	// 
	/// Inserts the chain link after a chain link.
	/// 
	virtual void			MCCOMAPI InsertAfter		(I3DShTweenerChainLink* inAfter) = 0;
	
	// ****************************************************************************
	//								InsertBefore
	// 
	/// Inserts the chain link before a chain link.
	/// 
	virtual void			MCCOMAPI InsertBefore		(I3DShTweenerChainLink* inBefore) = 0;
	
	// ****************************************************************************
	//								OffsetLink
	// 
	/// Undocumented.
	/// 
	virtual MCCOMErr		MCCOMAPI OffsetLink			(MicroTick inDeltaTime) = 0;

	// ****************************************************************************
	//								GetTimeInfo
	// 
	/// Returns the time.
	/// 
	virtual MCCOMErr		MCCOMAPI GetTimeInfo		(TTimeInfo& outTimeInfo) const = 0;	

	// ****************************************************************************
	//								IsTweenerSelected
	// 
	/// Returns true if the tweener is selected.
	/// 
	virtual boolean 		MCCOMAPI IsTweenerSelected	() const = 0;
	
	// ****************************************************************************
	//								IsKeyFrameSelected
	// 
	/// Returns true if the keyframe is selected.
	/// 
	virtual boolean 		MCCOMAPI IsKeyFrameSelected	() const = 0;  
	
	// ****************************************************************************
	//								SelectKeyFrame
	// 
	/// Selects/Deselect the key frame.
	/// 
	virtual MCCOMErr 		MCCOMAPI SelectKeyFrame		(boolean select) = 0;
	
	// ****************************************************************************
	//								SelectTweener
	// 
	/// Selects/Deselect the tweener.
	/// 
	virtual MCCOMErr 		MCCOMAPI SelectTweener		(boolean select) = 0;
};


/// \}


#endif