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

		IExRegisterer.h

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

		Author:	Emil
		Date:	1/28/99

		Revision History

		when		who			what & why
		==========	==========	======================================================
		2/24/98		Eml			removed ComInterfaceIDs, it was wrong
		2/22/99		Alec		added ComInterfaceIDs to complete header
*****************************************************************************************/
#ifndef __IExRegisterer__
#define __IExRegisterer__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "COMTypes.h"
#include "COMInterfaceIDs.h"
#include "MCString.h"
#include "CommonComDefines.h"


class TMCResource;

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

//

/// \addtogroup BasicCOM
/// \{

//	NOTE: The size of the TMCStrings in that structure MUST match exactly the size declared in the ExternalAPI.r file
//
/// Represents the 'COMP' resource. <BR>
///	<P>Along with the GUID resource, it defines a Component Class (see also TComponentClassInfo) 
///	that is a description of the C++ class in your extension. <BR>
/// When the application calls your MakeCOMObject() function to create a new C++ instance of your C++ class, 
/// we also say that it creates a new Component Instance of your Component Class. 
/// Sometimes "class" or "instance" is omited in the documentation, 
/// but the context should tell you whether we're talking about the class or the instance of a component. </P>
///
/// <P>Component Classes are grouped into Compoment Families. A Family is associated with a particular C++ interface 
/// that all the component classes of the family must implement (eg the Shaders family is associated with I3DExShader).</P>
///
/// <P>Within a family, Component Classes are grouped into <B>sub families</B>. This is only used to enhance the user interface 
/// (generally to group related Component Classes into a sub menu like "Pattern Functions").
/// Sub families are identified by the #fSubFamilyName field. </P>
///
/// <P>To handle versioning, it is allowed to have two Component Classes with the same ID (#fClass), 
/// as long as they have different version numbers (#fVersion). By default, the application will instanciate 
/// the latest version of a Componment class. But when reading an old file, the old instance will be created and used.
/// A <B>"Component Super Class"</B> is simply the list of all the different versions of a Component Class. </P>
///
struct APICOMPData : public TMCObject
{
	IDType 			fFamily;		///< The ID of the family to which the component belongs (eg 'shdr')
	IDType 			fClass;			///< The unique ID (within its family) of the component class (eg 'schk')
	TMCString63 	fName;			///< The name of the component class (eg "Checker Shader")
	TMCString63 	fSubFamilyName; ///< The name of the sub family to which that component class belongs (eg "Pattern Functions")
	int32 			fVersion;		///< The version of the component (1 if it is the only version)
	TMCString31 	fVersionStr;	///< The string representation of the version number
	TMCString255 	fComment;		///< Additionnal data that can be used by the UI (generally for Carrara shaders)
	int32			fAPIVersion;	///< The Carrara API version number the component class uses.

	APICOMPData()
	{
		fFamily		= 0;
		fClass		= 0;
		fVersion	= 0;
		fAPIVersion	= 0;
	}
};

/// \}


/// \addtogroup BasicCOM
/// \{

//	This structure should NEVER contain strings (use references to STR# resources...)
//
/// Represents the 'CINF' resource (Contains exta component info)
///
struct TComponentInfo : public TMCObject
{
	IDType 			fPrefsCompID;	///< The ID of the component (of the kRID_PreferencesFamilyID family) that stores the preferences for this component (0 for no prefs)
	uint16			fPlatforms;		///< On which platform(s) is the component running (use platform defines from CommonComDefines.h)
	uint16			fAppKinds;		///< On which application version(s) (light/std/pro) is the component running (use host defines from CommonComDefines.h)
	uint16			fAppModes;		///< On which application mode(s) (normal/demo) is the component running (use host defines from CommonComDefines.h)

	TComponentInfo()
	{
		fPrefsCompID	= kNoPrefs;
		fPlatforms		= kAnyPlatform;
		fAppKinds		= kAnyAppKind;
		fAppModes		= kAnyAppMode;
	}
};

/// \}

/// \addtogroup BasicCOM
/// \{

/// is used to read a resource of type 'CPUI'
///
struct APICPUIData : public TMCObject
{
	IDType 			fBigPartID;
	IDType 			fMiniPartID;
	uint32			fStyle;
	uint32			fPlaceParamsBeforeChildren;
	boolean			fIsCollapsible;
};

/// Represents the 'CPUI' resource (Contains component info used by the user interface)
///
/*struct APIPrivateData : public TMCObject
{
	void*  fPrivateData;
	uint32 fPrivateDataLength;
};*/

/// \}

/// \addtogroup BasicCOM
/// \{

/// is used to read a resource of type 'GUID'
///
struct APIGUIDData : public TMCObject
{
	MCGUID fIID;	/// The GUID of the external interface that defines the family
	MCGUID fCLSID;	/// The GUID of the component class (Class ID).
};
/// \}


/// \addtogroup ExternalInterface
/// \{

// ****************************************************************************
//								IExRegisterer
// 
/// A Registerer is an object that can register components dynamically (by opposition
/// with the static registration that is done using the resource). It is typically used
/// when the existance of components is conditionned by other installed software.
///
struct IExRegisterer : public IMCUnknown
{
	/// Returns the number of component that needs to be registered.
	///
	virtual uint32   MCCOMAPI GetComponentCount() = 0;

	/// Returns the registration info of each component.
	///
	/// \param index The index of the component between 0 and GetComponentCount().
	/// \param compData The 'COMP' resource.
	/// \param privateData A resource associated with that component class
	/// \param guidData The GUID resource.
	///
	virtual MCCOMErr MCCOMAPI GetComponentData(uint32 index, APICOMPData& compData,TMCResource*& privateData, APIGUIDData& guidData) = 0;

	/// Called once the component are not used anymore
	///
	virtual MCCOMErr MCCOMAPI UnregisterComponents() = 0;
};

/// \}


#endif
