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

		I3DShMaster.h

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

		Author:	EricB
		Date:	5/31/99

		Revision History

		when		who			what & why
		==========	==========	======================================================

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

#ifndef __I3DSHMASTER__
#define __I3DSHMASTER__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "ComTypes.h"
#include "APITypes.h"
#include "MCCountedPtr.h"
#include "MCString.h"

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

MCDEFINE_GUID(IID_I3DShMaster, 0x1cf7278a, 0x1767, 0x11d3, 0x9c, 0x85, 0x0, 0x0, 0xe8, 0xdd, 0x97, 0xd2);

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

class  TMCPixelBucket;
struct I3DShObject;
struct I3DShMasterShader;
struct IChangeChannel;
struct I3DMasterListener;
template <class T> class TMCCountedPtrArray;

#define kChange_IconUpdated	'IcnU'

/// \addtogroup ShellInterface
/// \{

/// I3DShMaster provides a generic interface to access object that can be instanced. It is
/// implemented by Master Objects, Groups, Shaders and Sounds.
///
struct I3DShMaster: public IMCUnknown
{
public:
	// ****************************************************************************
	//								GetInstancesCount
	// 
	/// Returns the number of instances of this master in the scene.
	/// 
	virtual uint32	 MCCOMAPI	GetInstancesCount		() = 0;
	
	// ****************************************************************************
	//								SetName
	// 
	/// Sets the name of a master. Note that you should not call this method
	/// once the master is inserted in a scene because it does not garantee the
	/// unicity of the name. 
	///
	/// <P>If you want to change the name of a Master Object once
	/// it is inserted in a scene, you should call: I3DShScene::Rename3DObject().</P>
	///
	/// <P>If you want to change the name of a Master Shader once it is inserted in
	/// a scene, you should call I3DShScene::RenameMasterShader().</P>
	/// 
	/// \param name  The new name of the master.
	/// 
	virtual MCCOMErr MCCOMAPI	SetName					(const TMCString& name) = 0;
	
	// ****************************************************************************
	//								GetName
	// 
	/// Returns the name of the Master.
	/// 
	/// \param name  The name of the Master.
	/// 
	virtual MCCOMErr MCCOMAPI	GetName					(TMCString& name) = 0;

	// ****************************************************************************
	//								GetIcon
	// 
	/// Returns an icon that can be used to display a preview of the object. This
	/// method is asynchronous.
	/// 
	/// \param size              The size in pixel of the icon.
	/// \param outBucket         A pointer to a pixel bucket that contains the image.
	/// \param withAlphaChannel  True if the pixel buckets contains alpha channel.
	/// 
	virtual MCCOMErr MCCOMAPI	GetIcon					(const uint32 size, TMCPixelBucket** outBucket, boolean withAlphaChannel ) = 0;
	
	// ****************************************************************************
	//								GetIconNow
	// 
	/// Same as GetIcon() but this method will block until the icon has been
	/// calculated.
	/// 
	/// \param size              The size in pixel of the icon.
	/// \param outBucket         A pointer to a pixel bucket that contains the image.
	/// \param withAlphaChannel  True if the pixel buckets contains alpha channel.
	/// 
	virtual MCCOMErr MCCOMAPI	GetIconNow				(const uint32 size, TMCPixelBucket** outBucket, boolean withAlphaChannel ) = 0;
	
	// ****************************************************************************
	//								GetPreview
	// 
	/// Returns a preview of the master. This method is asynchronous.
	/// 
	/// \param width             The width of the preview.
	/// \param height            The height of the preview.
	/// \param outBucket         A pointer to a pixel bucket that contains the preview.
	/// \param withAlphaChannel  True if the pixel buckets contains alpha channel.
	/// 
	virtual MCCOMErr MCCOMAPI	GetPreview				(const uint32 width, const uint32 height, TMCPixelBucket** outBucket, boolean withAlphaChannel ) = 0;
	
	// ****************************************************************************
	//								GetPreviewNow
	// 
	/// Same as GetPreview() except that it will block until the preview has been
	/// calculated.
	/// 
	/// \param width             The width of the preview.
	/// \param height            The height of the preview.
	/// \param outBucket         A pointer to a pixel bucket that contains the preview.
	/// \param withAlphaChannel  True if the pixel buckets contains alpha channel.
	/// 
	virtual MCCOMErr MCCOMAPI	GetPreviewNow			(const uint32 width, const uint32 height, TMCPixelBucket** outBucket, boolean withAlphaChannel ) = 0;

	// ****************************************************************************
	//								GetIconChangeChannel
	// 
	/// Returns the a change channel that can be used to be notified when an icon
	/// has been calculated (see GetIcon()).
	/// 
	/// \param channel  A pointer to the change channel.
	/// 
	virtual MCCOMErr MCCOMAPI	GetIconChangeChannel	(IChangeChannel** channel) = 0;

	// ****************************************************************************
	//								GetAlwaysCloneOnModify
	// 
	/// Returns true if a new copy of the Master should be created each time it
	/// is modified.
	/// 
	virtual boolean  MCCOMAPI	GetAlwaysCloneOnModify	() = 0;

	// ****************************************************************************
	//								SetSourceFile
	// 
	/// Sets the file full pathname of the object, if any. Used only if the object belongs to the Browser.
	/// 
	/// \param sourceFile  The full pathname.
	/// 
	virtual MCCOMErr MCCOMAPI			SetSourceFile	(const TMCString& sourceFile) = 0;

	// ****************************************************************************
	//								GetSourceFile
	// 
	/// Gets the file full pathname of the object, if any.
	/// Used only if the object belongs to the Browser.
	/// 
	/// \return NULL if the object does not belong to the Browser.
	///
	virtual const TMCString* MCCOMAPI	GetSourceFile	() const = 0;

	// ****************************************************************************
	//								RegisterListener
	// 
	/// Registers a listener.
	/// 
	virtual void 	MCCOMAPI RegisterListener	(I3DMasterListener* 	listener) = 0;
	
	// ****************************************************************************
	//								UnregisterListener
	// 
	/// Unregister a listener.
	/// 
	virtual void 	MCCOMAPI UnregisterListener	(I3DMasterListener* 	listener) = 0;
};


struct I3DMasterListener
{
	// ****************************************************************************
	//								MasterHasChanged
	// 
	/// Called when a master we depend on has changed
	/// 
	/// \param master  the master that was modified
	/// 
	virtual void 	MCCOMAPI MasterHasChanged(I3DShMaster* master) = 0;

	// ****************************************************************************
	//								PostChange
	// 
	/// Called when a master post a message.
	/// 
	/// \param master		the master that was modified
	/// \param inChangeID	the change posted
	/// 
	virtual void	MCCOMAPI PostChange(I3DShMaster* master, int32 inChangeID) = 0;
};

/// \}

#endif //__I3DSHMASTER__