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

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

		Author:	Julien
		Date:	9/26/2003

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

#ifndef __IMorphArea__
#define __IMorphArea__

#if CP_PRAGMA_ONCE
#pragma once
#endif


struct IMorphTargetGroup;
struct I3DShParamInfo;


/// \addtogroup ExternalInterface
/// \{


//****** Globally Unique Ids *************************************************
MCDEFINE_GUID_H(IID_IMorphArea);


struct TMetaMorphTargetLink
{
	TMetaMorphTargetLink()
		: fMetaMorphAreaIndex(-1), fMorphTargetIndex(-1), fValueMultiplier(1) {}

	int32	fMetaMorphAreaIndex;
	int32	fMorphTargetIndex;
	real	fValueMultiplier;
};


/// Interface for accessing and modifying the data contained in a MorphArea.
/// A MorphArea is a group of vertices that are under the influence of morph targets.
/// This interface allows you to access some of the Morph Target parameters.
/// To create or to set the vertex positions of a Morph Target, use 
/// I3DExVertexPrimitive and its methods, such as CreateMorphTarget or SetEditMorph.
struct IMorphArea: public IMCUnknown 
{
	// ****************************************************************************
	//								GetMorphAreaName
	// 
	///
	///	\return the name of the area
	virtual TMCString&	MCCOMAPI GetMorphAreaName()=0;

	// ****************************************************************************
	//								SetMorphAreaName
	// 
	// -Description:
	///			sets the name of an area
	virtual void		MCCOMAPI SetMorphAreaName( const TMCString& morphAreaName )=0;

	// ****************************************************************************
	//								GetMorphTargetCount
	// 
	///
	/// \return the number of target countained in this area
	virtual int32		MCCOMAPI GetMorphTargetCount()=0;

	// ****************************************************************************
	//								GetMorphTargetName
	// 
	/// Returns the name of a specific target
	/// 
	/// \param targetIndex      Index of the target.  Must be < GetMorphTargetCount()
	/// \param morphTargetName  Returns the name
	/// 
	virtual void		MCCOMAPI GetMorphTargetName( const int32 targetIndex, TMCString& morphTargetName  )=0;

	// ****************************************************************************
	//								SetMorphTargetName
	// 
	/// Set the name of a specific target
	/// 
	/// \param targetIndex      Index of the target.  Must be < GetMorphTargetCount()
	/// \param morphTargetName  Name to set.
	/// 
	virtual void		MCCOMAPI SetMorphTargetName( const int32 targetIndex, const TMCString& morphTargetName  )=0;

	// ****************************************************************************
	//								GetMorphTargetCoef
	// 
	/// Gets the coefficient of a specific morph target.  This coefficient is animated,
	/// so the returned value depends on the current time.  It determines the degree
	/// to which this morph target applies to the model.
	/// 
	/// \param targetIndex  Index of the target.  Must be < GetMorphTargetCount()
	/// \return the coefficient
	/// 
	virtual real32		MCCOMAPI GetMorphTargetCoef( const int32 targetIndex )=0;

	// ****************************************************************************
	//								SetMorphTargetCoef
	// 
	/// Sets the coefficient of a specific morph target.  This coefficient is animated, so
	/// depending on the time, a keyframe will be created.  This coefficient determines how 
	/// much the morph target will affect the model.  A coefficient of 0 won't cause any 
	/// deformation from this morph target, while a coefficient of 1 will apply the morph 
	/// target fully.  The coefficient can be greater than 1 or smaller than 0, and the target
	/// will be applied correspondingly.
	/// 
	/// \param targetIndex  Index of the target.  Must be < GetMorphTargetCount()
	/// \param coef         the coefficient to set
	/// 
	virtual void		MCCOMAPI SetMorphTargetCoef( const int32 targetIndex, const real32 coef )=0;

	// ****************************************************************************
	//								GetMorphTargetMinMaxCoef
	// 
	/// Gets the minimum and maximum coefficient of a specific morph target.
	/// 
	/// \param targetIndex  Index of the target.  Must be < GetMorphTargetCount()
	/// \param outMin		Minimum coef.
	/// \param outMax		Maximum coef.
	/// 
	virtual void		MCCOMAPI GetMorphTargetMinMaxCoef( const int32 targetIndex, real& outMin, real& outMax )=0;

	// ****************************************************************************
	//								SetMorphTargetMinMaxCoef
	// 
	/// Sets the minimum and maximum coefficient of a specific morph target.
	/// 
	/// \param targetIndex  Index of the target.  Must be < GetMorphTargetCount()
	/// \param min			Minimum coef.
	/// \param max			Maximum coef.
	/// 
	virtual void		MCCOMAPI SetMorphTargetMinMaxCoef( const int32 targetIndex, real min, real max )=0;

	// ****************************************************************************
	//								LinkToMetaMorphTarget
	// 
	/// Link a morph target to another morph target of a meta morph area.
	/// 
	/// \param morphAreaIndex		Index of this morph area
	/// \param targetIndex			Index of the target.  Must be < GetMorphTargetCount()
	/// \param metaMorphAreaIndex   The index of meta morph area
	/// \param metaMorphTargetIndex The index of morph target in the meta morph area
	//
	/// \return false if an error occured
	/// 
	virtual boolean		MCCOMAPI LinkToMetaMorphTarget( const int32 morphAreaIndex,const int32 targetIndex, const int32 metaMorphAreaIndex, const int32 metaMorphTargetIndex, real multiplier = 1.0f )=0;

	// ****************************************************************************
	//								GetLinkedMetaMorphTarget
	// 
	/// Get the meta morph target linked to this morph target.
	/// 
	/// \param targetIndex		Index of the target.  Must be < GetMorphTargetCount()
	//
	/// \return an array that contains the information
	/// 
	virtual const TMCArray<TMetaMorphTargetLink>&		MCCOMAPI GetLinkedMetaMorphTarget( const int32 targetIndex ) =0;

	// ****************************************************************************
	//								IsMetaMorphArea
	// 
	/// \return true if this morph area is a meta morph
	/// 
	virtual boolean		MCCOMAPI IsMetaMorphArea() const =0;


	// ****************************************************************************
	//								GetMorphAreaIndex
	// 
	/// \returns the index of the morph area.
	/// 
	virtual int32 MCCOMAPI GetMorphAreaIndex() = 0;

	// ****************************************************************************
	//								CreateMorphTargetGroup
	//
	/// \param parentGroup		parent group (NULL if a the top level).
	//
	/// \return the morph target group created.
	/// 
	virtual IMorphTargetGroup*	MCCOMAPI CreateMorphTargetGroup(IMorphTargetGroup* parentGroup, const TMCString& name) =0;

	// ****************************************************************************
	//								GetMorphTargetGroupRoot
	//
	/// \return the morph target group root.
	virtual IMorphTargetGroup*	MCCOMAPI GetMorphTargetGroupRoot() const =0;

	// ****************************************************************************
	//								AddMorphTargetToGroup
	//
	/// Add a morph target to a group (note that if this morph target already belong the a group,
	/// the target will be removed from it).
	//
	/// \param group	the group where you want to add the target (NULL if a the top level).
	/// \param index	index of the morph target.
	///
	virtual void		MCCOMAPI AddMorphTargetToGroup(IMorphTargetGroup* group, int32 index) =0;

	// ****************************************************************************
	//								GetMorphTargetParamInfo
	//
	/// Gets the param info corresponding to the morph target value.
	//
	/// \param morphTargetIndex		index of the morph target.
	///
	virtual I3DShParamInfo*		MCCOMAPI GetMorphTargetParamInfo(int32 morphTargetIndex) =0;

	// ****************************************************************************
	//								FindTargetIndexFromAnimation
	//
	/// Gets the morph target index corresponding to the param info value.
	//
	/// \param paramInfo		the param info from the animation.
	virtual int32		MCCOMAPI FindTargetIndexFromAnimation(I3DShParamInfo* paramInfo) = 0;

	// ****************************************************************************
	//								GetTargetCount
	//
	/// Returns the number of Morph Targets.
	//
	virtual int32       MCCOMAPI GetTargetCount() = 0;

	// ****************************************************************************
	//								EnableGlobalDeformer
	//
	/// Enables a deformer on the morph area.
	//
	/// \param deformer		the deformer (should be attached to the primitive).
	/// \param enable		enable or disable.
	///
	virtual void		MCCOMAPI EnableGlobalDeformer(int32 deformerIndex, boolean enable) =0;

	// ****************************************************************************
	//								SetGlobalDeformerStrength
	//
	/// Sets the strength of a deformer on the morph area.
	//
	/// \param deformer		the deformer (should be attached to the primitive).
	/// \param strength		the strength.
	///
	virtual void		MCCOMAPI SetGlobalDeformerStrength(int32 deformerIndex, real32 strength) =0;

	// ****************************************************************************
	//								GetGlobalDeformerStrength
	//
	/// Gets the strength of a deformer on the morph area (NOTE the function returns 0 
	/// if the deformer is not enabled for ths morph area).
	//
	/// \param deformer		the deformer (should be attached to the primitive).
	///
	virtual real32		MCCOMAPI GetGlobalDeformerStrength(int32 deformerIndex) =0;

	// ****************************************************************************
	//								GetGlobalDeformerStrengthParamInfo
	//
	/// Gets the param info cooresponding to the deformer strength.
	//
	/// \param deformer		the deformer (should be attached to the primitive).
	///
	virtual I3DShParamInfo*		MCCOMAPI GetGlobalDeformerStrengthParamInfo(int32 deformerIndex) =0;
};


/// \}



#endif
