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

		IExtension.h

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

		IExDataExchanger definition                                             

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		8/10/99		cph			remove IExtension (now part of IExDataExchanger)

*****************************************************************************************/
#ifndef __IEXTENSION__
#define __IEXTENSION__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "COMTypes.h"
#include "COMInterfaceIDs.h"

struct IMFResponder;

//****** Globally Unique Ids **************************************************
MCDEFINE_GUID_H(IID_IExDataExchanger);
MCDEFINE_GUID_H(IID_INamedExtension);

/*****************************************************************************\
*  INamedExtension                                                            *
*   
*  enables an extension to do some file handling on its own                   *
*  (gives a starting point for folder scans etc.)                             *
*                                                                             *
\*****************************************************************************/

struct INamedExtension: public IMCUnknown
{
	virtual MCCOMErr MCCOMAPI SetExtensionFullPathName(const int8* fullPathName) = 0;
};



typedef int32 MessageID;
struct IExDataExchanger;

template <class T> class TMCPtrArray;

/// \addtogroup BasicCOM
/// \{

/// Function to handle framework events in the complex contex of multiple selection.
/// IExDataExchanger::HandleEvent is being deprecated. For simple handling, you can implement SimpleHandleEvent.
/// For complex handling you'll have to implement GetUIHandler.
/// With multiple selection, we don't give anymore the component to the external part (through setValue).
/// So if needed, the handler also has to take care of setting the components on your external part(s).
///
/// \note: use inDataExchangers.QueryArray with your class id to get an array of your components (you must implement queryinterface)
///
/// \param message:			the ID of the message being sent (All MessageIDs are preceeded with "kMsg")
/// \param source:			the part that sent the message
/// \param data:			a pointer to private data corresponding to the message
/// \param inDataExchangers	the components attached to the ui
typedef MCCOMErr (*TUIHandlerFunctionPtr)(MessageID message, IMFResponder* source, void* data, const TMCPtrArray<IExDataExchanger>& inDataExchangers);


//  ****************************************************************************
//								IExDataExchanger
// 
///  Contains utility methods that are complements to \ref IMCUnknown, like clone()
///  Allows the Shell to handle the UI of the Component and the Component's 
///  public data.
///  Handles the communication between the Component and the Shell.
///
struct IExDataExchanger: public IMCUnknown
{
	// ****************************************************************************
	//								Clone
	// 
	/// Creates a copy of an external component. You only need to implement this
	/// method if your object has data that are not stored in its Parameter Map (Pmap).
	///
	/// \param clonedObject		: the resulting copy of the current object
	/// \param pUnkOuter		: the internal component that needs to be linked to your object (call SetControllingUnknown(pUnkOuter) on the clone)
	///
	virtual void	 MCCOMAPI Clone(IExDataExchanger** clonedObject,IMCUnknown* pUnkOuter) = 0;
	
	// ****************************************************************************
	//								IsEqual	
	// 
	/// Returns true if the two pointers are referring to the same data exchanger.
	/// When IsEqual is called you can assume that otherDataExchanger is of the same
	/// type as "this"
	///
	/// \param otherDataExchanger the extension to which it will be compared
	///
	virtual boolean  MCCOMAPI IsEqual(IExDataExchanger * otherDataExchanger) = 0;
	
	// ****************************************************************************
	//								GetParameter
	// 
	/// Returns the value of a given parameter of this dataExchanger.
	/// This function is called when the shell cannot find the given parameter in
	/// the Parameter Map (Pmap) of the component
	/// You need to implement this method only if your object has parameters that
	/// are not inside the parameter map.
	///
	/// \param keyword The ID of the parameter.
	/// \param parameter A pointer to buffer where the value of the parameter can be copied.
	///
	virtual MCCOMErr MCCOMAPI GetParameter(IDType keyword, void *parameter) = 0;
	
	// ****************************************************************************
	//								SetParameter	
	// 
	/// Sets the value of a parameter. You need to implement this method only if your object
	/// has parameters that are not inside the parameter map.
	///
	/// \param keyword The ID of the parameter.
	/// \param parameter A pointer to buffer where the value of the parameter can be copied.
	///
	virtual MCCOMErr MCCOMAPI SetParameter(IDType keyword, void *parameter) = 0;
	
	
	// ****************************************************************************
	//								GetExtensionDataBuffer
	// 
	/// Returns a pointer to the buffer that contains the parameter map (Pmap).
	/// This function should always be implemented by your component otherwise the
	/// base address of the object will be used as the address of the Pmap.
	///
	virtual void*    MCCOMAPI GetExtensionDataBuffer() = 0;
	
	// ****************************************************************************
	//								ExtensionDataChanged
	// 
	/// Called each time a parameter of the parameter map (Pmap) is modified. This
	/// should only be used to invalidate caches and should be quick since it can
	/// be called many times.
	///
	virtual MCCOMErr MCCOMAPI ExtensionDataChanged() = 0;
	
	// ****************************************************************************
	//								HandleEvent
	// 
	/// \deprecated
	/// (doesn't work with multiple selections)
	virtual MCCOMErr MCCOMAPI HandleEvent(MessageID message, IMFResponder* source, void* data) = 0;

	// ****************************************************************************
	//								SimpleHandleEvent
	/// Replaces the deprecated HandleEvent ONLY IN SIMPLE CASES.
	/// This function MUST NOT change the user interface (its called for every selected component).
	/// Example of allowed use : 
	///		if (source && (source->GetInstanceID() == 'shfl'))
	///		{
	///			fPMap.fSeed = gShellUtilities->TickCount();
	///			ExtensionDataChanged();
	///		}
	///
	/// \param message:			the ID of the message being sent (All MessageIDs are preceeded with "kMsg")
	/// \param source:			the part that sent the message (can be NULL !)
	/// \param data:			a pointer to private data corresponding to the message
	virtual MCCOMErr MCCOMAPI SimpleHandleEvent(MessageID message, IMFResponder* source, void* data) = 0;

	// ****************************************************************************
	//								GetUIHandler
	// 
	/// Returns a static function that handles complex ui events.
	/// That function is allowed to change the UI, but it must take into account all the components 
	/// and use the multivalue mode for parts. 
	/// \see LoadMultiValue (in MFPartUtilities.h)
	/// Each implementation MUST always return the same handler !
	/// If needed, you can implement both GetUIHandler and SimpleHandleEvent.
	virtual void	 MCCOMAPI GetUIHandler(TUIHandlerFunctionPtr& outHandler) = 0;
	
	// ****************************************************************************
	//								GetResID
	// 
	/// Returns the resource ID of the NodePart used for the properties of the component.<BR>
	/// Return 0 to use the default node id (the same number than the one used for the 'COMP' resource). This is the default.<BR>
	/// Return -1 if you want an auto pmap (very rarely needed)
	///
	/// Each implementation MUST always return the same value !
	virtual int16	 MCCOMAPI GetResID() = 0;

	// ****************************************************************************
	//								GetMiniPartID
	// 
	/// Returns the resource ID of the NodePart used for the MiniPart of the component.<BR>
	/// If you want this value to be used, implement OverridesMiniPartID.
	virtual int16		MCCOMAPI GetMiniPartID() = 0;

	// ****************************************************************************
	//								OverridesMiniPartID
	// 
	/// Returns the resource ID of the NodePart used for the properties of the component.<BR>
	/// Return MC_E_NOTIMPL to use the default node id (the same number than the one used for the 'COMP' resource). This is the default.<BR>
	/// Return MC_S_OK if you want to use the ID from GetMiniPartID.
	virtual MCCOMErr	MCCOMAPI OverridesMiniPartID() = 0;


	// ****************************************************************************
	//								InitComponent
	// 
	///	Set the data of a component to their default value
	/// Returns kNotImplementedError if not implemented, MC_S_OK otherwise.
	///
	virtual MCCOMErr MCCOMAPI InitComponent() = 0;

	// ****************************************************************************
	//								CopyComponentExtraData
	// 
	/// Some components can contain data that aren't part of its pMap but need to 
	///	copy during the Undo/Redo action for example. Implement this method to copy 
	///	these "outside the pmap" data. Typicaly, it should copy the extra data that 
	///	are cloned in the Clone method implementation.
	///
	///	\param dest The component where the date should be copied.
	///
	virtual MCCOMErr MCCOMAPI CopyComponentExtraData(IExDataExchanger* dest) = 0;


	/// returns the size of the buffer based on the C code (eg sizeof(fPmap))
	/// so that the application can check the calculated pmap size
	virtual int32		MCCOMAPI GetParamsBufferSize		() const = 0;
};
/// \}


#endif

