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

		Basic3DCOMImplementations.h

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

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who					what & why
		==========	=================	======================================================
		10/01/99	Mathieu				TBasicForce implementation
		09/30/99	Mathieu				TBasicAnimationMethod::GetInitialTransform()
		09/09/99	Guillaume			Changed the name of I3DExMotionLink to I3DExConstraint
		08/11/99	Guillaume&Christy	Added inheritance to all the Basic* classes
		11/18/98	Joshua				Added TransformIsLocal call to TBasicAnimationMethod
		9/29/98		Joshua				Removed Basic Behaviors and Deformers
		9/18/98		Greg				Changed TBasicModule to reflect new Module API
		9/1/98		Eml					I3dExRenderer API change
		6/18/98		Greg				Added SelfPrepareMenus to TBasicModule
		6/18/98		Joshua				Removed evil virtual destructor on TBasicTweener
		6/17/98		Eml					Split Basic3DCOMImplementations and BasicCOMImplementations
		6/17/98		Greg				Added SelfMenuAction to TBasicPart, TBasicModule
		5/8/98		Eml					Added Basic objects for Render Features
		5/4/98		Greg				Updated to new COM macros and added TBasicModule
										and TBasicPart

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

#ifndef __Basic3DCOMImplementations__
#define __Basic3DCOMImplementations__

#if CP_PRAGMA_ONCE
#pragma once
#endif




#include "MCBasicTypes.h"
#include "MCException.h"
#include "MCCountedPtr.h"
#include "MCCountedObject.h"

#include "I3DExAnimationMethod.h"
#include "I3DExForce.h"
#include "I3DExTweener.h"
#include "I3DExConstraint.h"
#include "I3DExSceneCommand.h"
#include "MCColorRGBA.h"
#include "BasicCOMImplementations.h"


struct I3DShSelection;
struct I3DShTreeElement;
struct I3DShParamTimeLine;
struct ISceneDocument;

//******************************************************************
//Extensions personal Inits, use an empty function if not used
void Extension3DInit(IMCUnknown* utilities);
void Extension3DCleanup();

//******************************************************************
/// \addtogroup BaseClass
/// \{



/***************************************************************************\
*                                                                           *
*             TBasicConstraint                                              *
*                                                                           *
\***************************************************************************/
/// Basic constraint class.  Derive from this for a default implementation of I3DExConstraint
/// \see I3DExConstraint
class TBasicConstraint : public I3DExConstraint, public TBasicDataExchanger 
{
public:
	virtual MCCOMErr 	MCCOMAPI QueryInterface						(const MCIID &riid, void** ppvObj);
	virtual uint32 		MCCOMAPI AddRef								()		{ return TBasicDataExchanger::AddRef(); }

	virtual int16 		MCCOMAPI GetNbrFreedom						() const;
  	virtual MCCOMErr 	MCCOMAPI IncrementFreedomValue				(int16 index, real& increment);
 	virtual MCCOMErr	MCCOMAPI GetMotionLimit						(int16 index, ELimitType& limit) const;
 	virtual MCCOMErr 	MCCOMAPI GetFreedomRange					(int16 index, real& min, real& max) const;
	virtual MCCOMErr	MCCOMAPI GetFreedomValue					(int16 index, real& outValue) const;
	virtual MCCOMErr	MCCOMAPI GetRotationsOrder					(EEulerAnglesOrder& outOrder) const;
	virtual MCCOMErr	MCCOMAPI GetGimbalToLocalRotation			(TMatrix33& outRotation) const;
	virtual MCCOMErr 	MCCOMAPI GetTransform						(TTransform3D& transform)const;
	virtual MCCOMErr 	MCCOMAPI GetTransformPartialDerivate		(int16 index, TTransform3D& transform) const;
	virtual MCCOMErr	MCCOMAPI GetTransformSecondPartialDerivative(int16 index1, int16 index2, TTransform3D& transform) const; 
	virtual MCCOMErr	MCCOMAPI SetTransform						(TTransform3D& transform);
};

class TBasicNewConstraint : public TBasicDataExchanger,
							public I3DExNewConstraint,
							public I3DExNewConstraint2
{
public:
	virtual MCCOMErr 	MCCOMAPI QueryInterface						(const MCIID &riid, void** ppvObj);
	virtual uint32 		MCCOMAPI AddRef								()		{ return TBasicDataExchanger::AddRef(); }

	virtual int16 		MCCOMAPI GetNbrFreedom						() const;
  	virtual MCCOMErr 	MCCOMAPI IncrementFreedomValue				(int16 index, real& increment);
 	virtual MCCOMErr	MCCOMAPI GetMotionLimit						(int16 index, ELimitType& limit) const;
 	virtual MCCOMErr 	MCCOMAPI GetFreedomRange					(int16 index, real& min, real& max) const;
	virtual MCCOMErr	MCCOMAPI GetFreedomValue					(int16 index, real& outValue) const;
	virtual MCCOMErr 	MCCOMAPI GetTransformPartialDerivate		(int16 index, TTransform3D& transform) const;
	virtual MCCOMErr	MCCOMAPI GetTransformSecondPartialDerivative(int16 index1, int16 index2, TTransform3D& transform) const; 
	virtual void		MCCOMAPI ConstrainsTransform				(TTreeTransform& transform) const;
	virtual void		MCCOMAPI ConstrainsInputTransform			(TTreeTransform& transform, boolean changedFromUI) const;
};



/***************************************************************************\
*                                                                           *
*             TBasicTweener                                                 *
*                                                                           *
\***************************************************************************/
/// Basic Tweener class.  Derive from this for a default implementation of I3DExTweener
/// \see I3DExTweener
class TBasicTweener : public I3DExTweener, public TBasicDataExchanger
{
public:
	virtual MCCOMErr 	MCCOMAPI QueryInterface	(const MCIID& riid, void** ppvObj);
	virtual uint32 		MCCOMAPI AddRef			()		{ return TBasicDataExchanger::AddRef(); }

	virtual MCCOMErr 	MCCOMAPI SimpleTween	(real &result, int32 time, int32 time1, int32 time2);
	virtual MCCOMErr 	MCCOMAPI Tween			(I3DShKeyFrame* res,int32 time,I3DShTweenerChainLink* alink);
	virtual MCCOMErr	MCCOMAPI Derivate		(I3DShKeyFrame* res,int32 time,I3DShTweenerChainLink* alink);
	virtual boolean		MCCOMAPI NeedKeyFrameTangents() const { return false; }
};

/// Basic Menu CallBack class.  Derive from this for a default implementation of ISelfPrepareMenuCallBack.
/// \see ISelfPrepareMenuCallBack
class TBasicMenuCallBack : public TMCCountedObject, public ISelfPrepareMenuCallBack
{
	virtual MCCOMErr MCCOMAPI QueryInterface	(const MCIID& riid, void** ppvObj)	{ return TMCCountedObject::QueryInterface(riid,ppvObj); }
	virtual uint32 	 MCCOMAPI AddRef			()									{ return TMCCountedObject::AddRef(); }
	virtual uint32 	 MCCOMAPI Release			()									{ return TMCCountedObject::Release(); }

	virtual boolean MCCOMAPI SelfPrepareMenu(ISceneDocument* sceneDocument) = 0;
};


/***************************************************************************\
*                                                                           *
*             TBasicSceneCommand                                            *
*                                                                           *
\***************************************************************************/
/// Basic Scene Command class.  Derive from this for a default implementation of I3DExSceneCommand
/// \see I3DExSceneCommand
class TBasicSceneCommand :  public I3DExSceneCommand, public TBasicDataExchanger 
{
public:
	TBasicSceneCommand();

	virtual MCCOMErr MCCOMAPI QueryInterface	(const MCIID& riid, void** ppvObj);
	virtual uint32 	 MCCOMAPI AddRef			()		{ return TBasicDataExchanger::AddRef(); }

	virtual void	 MCCOMAPI GetMenuCallBack(ISelfPrepareMenuCallBack** callBack);

	virtual MCCOMErr MCCOMAPI Init				(ISceneDocument* sceneDocument);
	virtual MCCOMErr MCCOMAPI Prepare			();

	virtual boolean  MCCOMAPI CanUndo			();

	virtual boolean  MCCOMAPI Do				();
	virtual boolean  MCCOMAPI Undo				();
	virtual boolean  MCCOMAPI Redo				();

	virtual boolean	 MCCOMAPI PostPrepare		()	{ return true; }

protected:
	boolean fNeedsSelection;
};






/***************************************************************************\
*                                                                           *
*             TBasicAnimationMethod                                         *
*                                                                           *
\***************************************************************************/
/// Basic Animation Method class.  Derive from this for a default implementation of I3DExAnimationMethod.
/// \see I3DExAnimationMethod
class TBasicAnimationMethod :	public I3DExAnimationMethod, public TBasicDataExchanger
{
public:
	TBasicAnimationMethod();
	~TBasicAnimationMethod();

	virtual MCCOMErr MCCOMAPI QueryInterface					(const MCIID &riid, void** ppvObj);
	virtual uint32 	 MCCOMAPI AddRef							()	{return TBasicDataExchanger::AddRef(); }

	//I3DExAnimationMethod
	virtual MCCOMErr MCCOMAPI SetTree							(I3DShTreeElement* tree);
	virtual boolean  MCCOMAPI GetTransform						(TTreeTransform& transform);
	virtual boolean  MCCOMAPI GetInitialTransform				(TTreeTransform& transform);
	virtual MCCOMErr MCCOMAPI SetTransform						(const TTreeTransform& transform);
	virtual boolean  MCCOMAPI OffsetAnimation					(const TTreeTransform& offset);
	virtual boolean  MCCOMAPI TransformIsLocal					();

	virtual MCCOMErr MCCOMAPI GetAnimationKeyTimes				(real inAccuracy, TMCArray<MicroTick>& outKeyTimes,
																 boolean& outAutoGetKeyFrames, boolean& outAutoCurveAnalysis);

	virtual boolean	 MCCOMAPI NeedConvert						() { return false; }
	virtual MCCOMErr MCCOMAPI BeginConvert						(I3DShAnimationMethod* source);
	virtual MCCOMErr MCCOMAPI Convert							(I3DShAnimationMethod* source, const TTreeTransform& transform);
	virtual MCCOMErr MCCOMAPI EndConvert						(I3DShAnimationMethod* source);

	//used to make exact conversions between animation methods when posible,
	//when the following methods are not implemented, the transform returned by GetTransform will be sampled
	virtual MCCOMErr MCCOMAPI GetXTranslationAnimationTrack		(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetYTranslationAnimationTrack		(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetZTranslationAnimationTrack		(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetHotPointAnimationTrack			(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetUniformScalingAnimationTrack	(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetRotationAnimationTrack			(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetRotationAnimationTrack			(I3DShParamTimeLine ** xAnimationTrack,
																 I3DShParamTimeLine ** yAnimationTrack,
																 I3DShParamTimeLine ** zAnimationTrack,
																 I3DShParamTimeLine ** mirrorAnimationTrack,
																 EEulerAnglesOrder&    anglesOrder);
	virtual MCCOMErr MCCOMAPI GetXScalingAnimationTrack			(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetYScalingAnimationTrack			(I3DShParamTimeLine** animationTrack);
	virtual MCCOMErr MCCOMAPI GetZScalingAnimationTrack			(I3DShParamTimeLine** animationTrack);


protected:
	 // this reference should not be counted because the Animation is owned by the tree
	I3DShTreeElement*	fTree;
};





/***************************************************************************\
*                                                                           *
*             TBasicForce                                                   *
*                                                                           *
\***************************************************************************/
/// Basic Force class.  Derive from this for a default implementation of an I3DExForce.
/// \see I3DExForce
class TBasicForce : public I3DExForce
{
public:

	TBasicForce();
	~TBasicForce();

	virtual MCCOMErr	MCCOMAPI GetForceAndTorque		(const TPhysicalState& inPhysicalState, TVector3& outForce, TVector3& outTorque);
	virtual boolean		MCCOMAPI WillApplyForce			();
	virtual boolean		MCCOMAPI WillApplyTorque		();

protected :

	void						 RefreshTimeBasedData	();
};

/// \}
#endif