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

		I3DExLinkedParamController.h
		Copyright: (c) 2002 Eovia Corp. All rights reserved.

		Author:	Pierre
		Date:	8/18/2006

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

#ifndef __I3DExLinkedParamController__
#define __I3DExLinkedParamController__

#if CP_PRAGMA_ONCE
#pragma once
#endif


struct I3DShParamInfo;
class TParamHolder;
struct I3DShAttributesSet;


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

MCDEFINE_GUID_H(IID_I3DExLinkedParamController);

struct ILinkedParamFunction;


/// \addtogroup ExternalInterface
/// \{

// ****************************************************************************
//								I3DExLinkedParamController
// 
/// External interface to manipulate the linked param controller. Its class ids
/// are 'atsc', 'link'.
///
/// \see I3DShAttributesSetControler
///
struct I3DExLinkedParamController : public IMCUnknown
{
	// ****************************************************************************
	//								LinkParametersAdditive
	// 
	/// Link two parameters together using the formula: dest += factor*source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param factor		Factor used to multiply the source before adding the value to the dest
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	/// 
	virtual boolean				MCCOMAPI LinkParametersAdditive(I3DShParamInfo* source, I3DShParamInfo* dest, real32 factor, int32 sourceIndex=-1, int32 destIndex=-1) = 0;
	
	// ****************************************************************************
	//								LinkParametersMultiplicative
	// 
	/// Link two parameters together using the formula: dest = dest*source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	///
	virtual boolean				MCCOMAPI LinkParametersMultiplicative(I3DShParamInfo* source, I3DShParamInfo* dest, int32 sourceIndex=-1, int32 destIndex=-1) = 0;
	
	// ****************************************************************************
	//								LinkParametersSubtraction
	// 
	/// Link two parameters together using the formula: dest = dest-source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	///
	virtual boolean				MCCOMAPI LinkParametersSubtraction(I3DShParamInfo* source, I3DShParamInfo* dest, int32 sourceIndex=-1, int32 destIndex=-1) = 0;

	// ****************************************************************************
	//								LinkParametersPlus
	// 
	/// Link two parameters together using the formula: dest += source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	///
	virtual boolean				MCCOMAPI LinkParametersPlus(I3DShParamInfo* source, I3DShParamInfo* dest, int32 sourceIndex=-1, int32 destIndex=-1) = 0;

	// ****************************************************************************
	//								LinkParametersDivideBy
	// 
	/// Link two parameters together using the formula: dest = dest/source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	///
	virtual boolean				MCCOMAPI LinkParametersDivideBy(I3DShParamInfo* source, I3DShParamInfo* dest, int32 sourceIndex=-1, int32 destIndex=-1) = 0;

	// ****************************************************************************
	//								LinkParametersDivideInto
	// 
	/// Link two parameters together using the formula: dest = source/dest. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	///
	virtual boolean				MCCOMAPI LinkParametersDivideInto(I3DShParamInfo* source, I3DShParamInfo* dest, int32 sourceIndex=-1, int32 destIndex=-1) = 0;

	// ****************************************************************************
	//								LinkParametersOverride
	// 
	/// Link two parameters together using the formula: dest = factor*source. Returns
	/// true if the two parameters has been linked.
	///
	/// \param source		The source
	/// \param dest			The destination
	/// \param factor		Factor used to multiply the source before setting the value to the dest
	/// \param sourceIndex	Index if the source param type is a vector
	/// \param destIndex	Index if the dest param type is a vector
	/// 
	virtual boolean				MCCOMAPI LinkParametersOverride(I3DShParamInfo* source, I3DShParamInfo* dest, real32 factor, int32 sourceIndex=-1, int32 destIndex=-1) = 0;

	// ****************************************************************************
	//								UnlinkParameters
	// 
	/// Unlink two parameters.
	///
	/// \param source		The source (if NULL means 'any')
	/// \param dest			The destination (if NULL means 'any')
	///
	/// \see I3DExLinkedParamController::LinkParameters
	/// 
	virtual void				MCCOMAPI UnlinkParameters(I3DShParamInfo* source = NULL, I3DShParamInfo* dest = NULL) = 0;

	// ****************************************************************************
	//								GetLinksCount
	// 
	/// Returns the number of links.
	virtual int32				MCCOMAPI GetLinksCount		() const = 0;

	virtual void				MCCOMAPI GetLinkByIndex		(	const int32 linkIndex, 
																int32&		outSourceParamIndex,
																int32&		outDestParamIndex,
																boolean&	outIsEnabled) const = 0;

	virtual boolean				MCCOMAPI IsLinkEnabled		(	const int32 linkIndex) const = 0;

	virtual void				MCCOMAPI SetLinkEnabled		(	const int32 linkIndex,
																boolean		isEnabled) = 0;

	virtual ILinkedParamFunction* MCCOMAPI GetLinkFunction	(	const int32 linkIndex) const = 0;

	///takes ownership of the function
	virtual boolean				MCCOMAPI LinkParameters		(	I3DShParamInfo*			source, 
																I3DShParamInfo*			dest, 
																ILinkedParamFunction*	function) = 0;

	virtual void                MCCOMAPI GetLinkedParamsIndexes(int32 paramIndex, TMCArray<int32>& linkedParamsIndexes) = 0;

	virtual int32				MCCOMAPI RegisterLookupParameter(I3DShParamInfo* param) = 0;
	virtual I3DShParamInfo*		MCCOMAPI GetRegisteredLookupParameter(int32 index) = 0;

	virtual void				MCCOMAPI EnableController(boolean enabled) = 0;

	virtual void                MCCOMAPI GetSourcesParamsIndexes(int32 paramIndex, TMCArray<int32>& linkedParamsIndexes) = 0;
};



///ILinkedParamFunction
struct ILinkedParamFunction : public IMCUnknown
{
	virtual void		MCCOMAPI Apply(const TParamHolder* prevSrc, const TParamHolder& src, TParamHolder& dst) = 0;
	virtual boolean		MCCOMAPI ApplyInverse(const TParamHolder* prevSrc, const TParamHolder& src, TParamHolder& dst) = 0;
	virtual boolean		MCCOMAPI IsLinkValid(I3DShParamInfo* source, I3DShParamInfo* dest) = 0;

	virtual IDType		MCCOMAPI GetKeyword() = 0;
	virtual void		MCCOMAPI Read(IShTokenStream& stream) = 0;
	virtual void		MCCOMAPI Write(IShTokenStream& stream) = 0;

	virtual void		MCCOMAPI Clone(ILinkedParamFunction** outFunction) = 0;

	virtual real32		MCCOMAPI GetFactor() = 0;
};


/// \}


#endif
