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


		IMFDragDrop.h


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


		Author:	Greg
		Date:	2/11/99

		Revision History

		when		who			what & why
		==========	==========	======================================================
		9/28/99		Thierry		removed GC from Hilite parameters
		9/8/99		Greg		Added OnNoDrag
		9/06/99		EricB		GetOrigin parameter changed from void** to IMCUnknown**
		6/10/99		Ian			Array API changes.
		3/23/99		Thierry		GetData & GetOrigin use a return parameter
								IMFExDropArea::GetPart(IMFPart**) instead of IMFPart*&

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

#ifndef __IMFDRAGDROP__
#define __IMFDRAGDROP__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCompObj.h"
#include "MCArray.h"
#include "IMFTabPart.h"

struct IMCGraphicContext;
struct IMFPart;
class  TMCPoint;


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

MCDEFINE_GUID(IID_IMFDropCandidate, 0xac7cf813, 0xc1e5, 0x11d2, 0x81, 0x9c, 0x0, 0x60, 0x8, 0x96, 0x53, 0x92);
MCDEFINE_GUID2(IID_IMFExDropCandidate, R_IID_IMFExDropCandidate);
MCDEFINE_GUID(IID_IMFDropArea, 0xac7cf815, 0xc1e5, 0x11d2, 0x81, 0x9c, 0x0, 0x60, 0x8, 0x96, 0x53, 0x92);
MCDEFINE_GUID2(IID_IMFExDropArea, R_IID_IMFExDropArea);

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

#define kDragFlavor_NoFlavor '****'

enum MFDragDropType
{
	kDragAndDropCopy,
	kDragAndDropMove
};


struct TMFFlavor
{
	IDType		fFlavorID;		///the id of the flavor (eg kDragFlavor_ImportFile)
	IDType		fFlavorHint;	///additional hint to the kind of data associated with the flavor (eg the type of the file to import)

	TMFFlavor()	: fFlavorID(0), fFlavorHint(0) {}
	explicit TMFFlavor(IDType flavorID, IDType flavorHint= 0)	: fFlavorID(flavorID), fFlavorHint(flavorHint) {}
};

/******************************************************************************\
*                                                                              *
*           TMFDragFlavors                                                     *
*                                                                              *
\******************************************************************************/

/// Lists the offered data types (flavors) when doing drag and drop.
///
class TMFDragFlavors : public TMCArray<TMFFlavor>
{
public:
	uint32			GetFlavorIndex	(IDType flavorID) const
	{
		for(uint32 flavorIndex = 0; flavorIndex < GetElemCount(); flavorIndex++)
		{
			if ((*this)[flavorIndex].fFlavorID == flavorID) return flavorIndex;
		}
		return kUnusedIndex;
	}

	boolean			HasFlavor		(IDType flavorID) const
	{
		for(uint32 flavorIndex = 0; flavorIndex < GetElemCount(); flavorIndex++)
		{
			if ((*this)[flavorIndex].fFlavorID == flavorID) return true;
		}
		return false;
	}


	inline void		AddFlavor		(IDType flavorID) { TMCArray<TMFFlavor>::AddElem( TMFFlavor(flavorID) ); }
};


/// \addtogroup MCF
/// \{

// ****************************************************************************
//								IMFDropCandidate
// 
/// IMFDropCandidate is the shell interface for a drop candiate (see IMFExDropCandidate
/// for more informations on Drop Candidates).
///
struct IMFDropCandidate : public IMCUnknown
{
public:

	// ****************************************************************************
	//								GetData
	// 
	/// Returns the data of the object in a given format.
	/// 
	/// \param inFlavor      The format of the data.
	/// \param inMoveOrCopy  Specifies whether the data should be copied or moved.
	/// \param outData       The data.
	/// 
	virtual MCCOMErr MCCOMAPI GetData			(IDType inFlavor, MFDragDropType inMoveOrCopy, void** outData) = 0;

	// ****************************************************************************
	//								GetOrigin
	// 
	/// Returns the origin (for example the scene for an instance) of the drop  candidate  for use
	/// in determining whether to move or copy the item
	/// (clients should check for non-NULL).
	/// 
	/// \param outOrigin  A pointer to the origin.
	/// 
	virtual void	 MCCOMAPI GetOrigin			(void**	outOrigin) = 0;

	// ****************************************************************************
	//								GetOfferedFlavors
	// 
	/// Returns the list of format in which the data can be converted.
	/// 
	/// \param outFlavors  The list of formats.
	/// 
	virtual void	 MCCOMAPI GetOfferedFlavors	(TMFDragFlavors& outFlavors) = 0;

	virtual boolean  MCCOMAPI NeedToBeDropedOnTree(IDType inFlavor, MFDragDropType inMoveOrCopy) = 0;

	virtual void	 MCCOMAPI SetDropCandidateExtensionTabPart	(IMFTabPart* tabPart) = 0;


};

/// \}


/// \addtogroup MCF
/// \{

// ****************************************************************************
//								IMFExDropCandidate
// 
/// IMFExDropCandidate is the interface for a drop candidate. A drop candidate
/// is the object that excapsulate that object that is drag and dropped.
///
/// To create your own drop candiate, you should derive your object from TBasicDropCandidate
/// that provides a default implementation of IMFExDropCandidate. The family ID for a 
/// drop area is <B>'drpC'</B>.
///
struct IMFExDropCandidate : public IMCUnknown
{
public:
	
	// ****************************************************************************
	//								GetData
	// 
	/// Returns the data of the object in a given format.
	/// 
	/// \param inFlavor      The format of the data.
	/// \param inMoveOrCopy  Specifies whether the data should be copied or moved.
	/// \param outData       The data.
	/// 
	virtual MCCOMErr MCCOMAPI GetData			(IDType inFlavor, MFDragDropType inMoveOrCopy, void** outData) = 0;

	// ****************************************************************************
	//								GetOrigin
	// 
	/// Returns the origin (for example the scene for an instance) of the drop  candidate  for use
	/// in determining whether to move or copy the item
	/// (clients should check for non-NULL).
	/// 
	/// \param outOrigin  A pointer to the origin.
	/// 
	virtual void	 MCCOMAPI GetOrigin			(void** outOrigin) = 0;

	// ****************************************************************************
	//								GetOfferedFlavors
	// 
	/// Returns the list of format in which the data can be converted.
	/// 
	/// \param outFlavors  The list of formats.
	/// 
	virtual void	 MCCOMAPI GetOfferedFlavors	(TMFDragFlavors& outFlavors) = 0;

	// ****************************************************************************
	//								PrepareToDrag
	// 
	/// Called at the beginning of the drap
	/// 
	virtual void	 MCCOMAPI PrepareToDrag		() = 0;
	
	// ****************************************************************************
	//								FinishedDrag
	// 
	/// Called at the end of the drap.
	/// 
	/// \param inSuccessful  True ifthe drop was successful.
	/// 
	virtual void 	 MCCOMAPI FinishedDrag		(boolean inSuccessful) = 0;
	
	// ****************************************************************************
	//								OnNoDrag
	// 
	/// Called when no drag occured.
	/// 
	virtual void	 MCCOMAPI OnNoDrag			() = 0;

	virtual boolean  MCCOMAPI NeedToBeDropedOnTree(IDType inFlavor, MFDragDropType inMoveOrCopy) = 0; 

};

/// \}

/// \addtogroup MCF
/// \{

// ****************************************************************************
//								IMFDropArea
// 
/// IMFDropArea is the shell interface for a drop area object (see IMFExDropArea
/// for more informations on Drop Areas.
/// 
/// It is usually returned by IMFEXPart::GetDropArea()
///
struct IMFDropArea : public IMCUnknown
{
public:

	// ****************************************************************************
	//								SetPart
	// 
	/// Sets the part where the drop will occur.
	/// 
	/// \param inPart  A pointer to the part.
	/// 
	virtual void	MCCOMAPI SetPart			(IMFPart* inPart) = 0;
	
	// ****************************************************************************
	//								DragIsAcceptable
	// 
	/// Returns true if a particular object can be dropped on this area.
	/// 
	/// \param inOfferedFlavors  The type of the object that is dropped.
	/// \param outAcceptedFlavor  Returns the type that was accepted.
	/// \param inWhere           The point where the object is dropped.
	/// 
	virtual boolean MCCOMAPI DragIsAcceptable	(TMFDragFlavors& inOfferedFlavors, IDType& outAcceptedFlavor, const TMCPoint& inWhere) = 0;
};

/// \}


/// \addtogroup MCF
/// \{

// ****************************************************************************
//								IMFExDropArea
// 
/// This is the interface to create a drop area. A drop area is an object that
/// is associated to a part and deal with the drag&drop on this part.
///
/// To create your own drop area, you should derive your object from TBasicDropArea
/// that provides a default implementation of IMFExDropArea. The family ID for a 
/// drop area is <B>'drpA'</B>
/// 
struct IMFExDropArea : public IMCUnknown
{
public:

	// ****************************************************************************
	//								DragIsAcceptable
	// 
	/// Returns true if a particular object can be dropped on this area.
	/// 
	/// \param inOfferedFlavors  The type of the object that is dropped.
	/// \param outAcceptedFlavor  Returns the type that was accepted.
	/// \param inWhere           The point where the object is dropped.
	/// 
	virtual boolean	MCCOMAPI DragIsAcceptable	(TMFDragFlavors& inOfferedFlavors, IDType& outAcceptedFlavor, const TMCPoint& inWhere) = 0;

	// 
	// ****************************************************************************
	//								Hilite
	// 
	/// Highlight or not the part depending on inIsHilited.
	/// 
	/// \param inIsHilited  TRUE for highlight, FALSE for unhighlight.
	/// 
	virtual void	MCCOMAPI Hilite				(boolean inIsHilited) = 0;
	
	// ****************************************************************************
	//								IsEqualTo
	// 
	/// Returns true if the tow drop areas are the same.
	/// 
	virtual boolean	MCCOMAPI IsEqualTo			(IMFExDropArea* inArea) = 0;
	
	// ****************************************************************************
	//								ReceiveDrop
	// 
	/// Called when a drop is made on the part.
	/// 
	/// \param dropCandidate  The object that encapsulate the object that is dropped.
	/// \param acceptedType   Returns the type that was accepted.
	/// \param moveOrCopy     Specifies whether the object should be copied or moved.
	/// \param mousePos       The position of the mouse in the part.
	/// 
	virtual void	MCCOMAPI ReceiveDrop		(IMFDropCandidate* dropCandidate, IDType& acceptedType,
												 MFDragDropType moveOrCopy, const TMCPoint& mousePos) = 0;
	
	// ****************************************************************************
	//								GetPart
	// 
	/// Returns a pointer to the part to which the drop area corresponds.
	/// 
	/// \param outPart  A pointer to the part to which the drop area corresponds.
	/// 
	virtual void	MCCOMAPI GetPart			(IMFPart** outPart) = 0;
};


/// \}

#endif