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

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

		Author:	Arnaud
		Date:	12/5/2001

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

#ifndef __MFAttributes__
#define __MFAttributes__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "MCBasicTypes.h"
#include "MCBasicDefines.h"
#include "PMapTypes.h"


/// \addtogroup MCF
/// \{

/// An interface to pass data to the SetAttribute and from the GetAttribute functions
/// Those functions enable to set/get part properties without a corresponding method (with limited type checking).
/// At this point only sliders implement them though we should add them everywhere.
///
struct IMFAttribute
{
	virtual	IDType		GetID		() const = 0;	// return the id of the part's property to get/set
	virtual	IDType		GetType		() const = 0;	// return the type of the part's data (same as the possible pmap types defined in PMapTypes.h)
	virtual const void*	GetDataPtr	() const = 0;	// return the pointer to the data to get.
	virtual void*		GetDataPtr	() = 0;			// return the pointer to the data to set.
};


/// Base attribute class (stores only ID and Type)
class TMFBaseAttribute : public IMFAttribute
{
public:
	inline TMFBaseAttribute()	{ fID= '****'; fType= '****'; }	
	inline TMFBaseAttribute(IDType propertyID, IDType dataType) { fID= propertyID; fType= dataType; }

	virtual inline IDType GetID		() const 	{ return fID; }
	virtual inline IDType GetType	() const 	{ return fType; }	

protected:
	IDType	fID;		///< The id of the part's property to get/set
	IDType	fType;		///< The type of the part's data (same as the possible pmap types defined in PMapTypes.h)
};


///Generic attribute, keeps a pointer to the real data
///use for big attributes.
class TMFAttribute : public TMFBaseAttribute 
{
public:
	inline TMFAttribute() : TMFBaseAttribute()	{ fDataPtr= NULL; }	
	inline TMFAttribute(IDType propertyID, IDType dataType, void* dataPtr) { MCAssert(dataPtr); fID= propertyID; fType= dataType; fDataPtr= dataPtr; }

	virtual inline const void*	GetDataPtr() const	{ return fDataPtr; }
	virtual inline void*		GetDataPtr()		{ return fDataPtr; }

protected:
	void*	fDataPtr;	///< Pointer to the data to set/get.
};

//the resulting declarations are smaller than with templates.
#define DECLARE_ATTRIBUTE_CLASS(ClassName, CType, DataType) \
class ClassName: public TMFBaseAttribute {\
public:\
	inline ClassName(IDType propertyID, CType value) {fID= propertyID; fType= DataType; fData= value; }	\
	inline const CType&			GetData() const		{ return fData; } \
	inline CType&				GetData()			{ return fData; } \
	virtual inline const void*	GetDataPtr() const	{ return &fData; }	\
	virtual inline void*		GetDataPtr()		{ return &fData; }	\
protected:\
	CType fData; \
};


DECLARE_ATTRIBUTE_CLASS(TMFBooleanAttribute,	boolean,	kBooleanParamType)
DECLARE_ATTRIBUTE_CLASS(TMFInt16Attribute,		int16,		kInt16ParamType)
DECLARE_ATTRIBUTE_CLASS(TMFInt32Attribute,		int32,		kInt32ParamType)
DECLARE_ATTRIBUTE_CLASS(TMFReal32Attribute,		real32,		kReal32ParamType)

/// \}

#endif