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

		BasicMCFCOMImplementations.h

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

		Author:	Ray Dream
		Date:	3/2/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		10/27/99	Yann		Added TBasicPart::BaseWindowBecameVisible
		10/13/99	Yann		Added support for IMFExPart::SetShown
		10/05/99	EricB		IShMouseAction can now be 'not constrained to the view' they apply to.
								To do so, you just need to override the method ConstrainedToView, and return false.
								Default (TBasicMouseAction) returns true, to keep the previous behavior.
		9/28/99		Thierry		removed GC from Hilite parameters
		09/12/99	Pierre		Merged BecameFirstResponder and ResignedFirstResponder
		9/8/99		Greg		Added OnNoDrag
		9/06/99		EricB		DropCandidate::GetOrigin parameter changed from void** to IMCUnknown**
		8/16/99		Ian			Added override of NeedsToPrepareMenus.
		8/1/99		Ian			Mouse moved API change.
		06/11/99	del			Added GetIndirectToolAction()
		4/20/99		Greg		Added GetThisPartNoAddRef()
		4/5/99		Greg		Added SelfPrepareToDestroy in BasicPart
		3/23/99		Greg		DragDrop cleanup, DragDrop tool support in BasicPart
		3/3/99		Greg		Added GetValue and SetValue to BasicPart
		2/17/99		EricB		Added 'nextAction' as a return argument to IShMouseAction::Track
		2/16/99		Greg		Added TBasicPart::GetDropArea, TBasicDropArea and TBasicDropCandidate
		2/11/99		Joshua		Added IMFExPart::ParentChangedBounds
		1/13/99		Eml			Added IMFExPart::FinishRead
		11/24/98	Joshua		Added SelfToolAction
		11/23/98	pbk			splif from BASICCOMIMPLEMENTATIONS
								
*****************************************************************************************/
#ifndef __BASICMCFCOMIMPLEMENTATIONS__
#define __BASICMCFCOMIMPLEMENTATIONS__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCountedPtr.h"
#include "BasicCOMImplementations.h"
#include "IMFExResponder.h"
#include "IMFExPart.h"
#include "IMFDragDrop.h"
#include "IMFPart.h"
#include "IMFExListPart.h"
#include "IShUtilities.h"


/// \addtogroup BaseClass
/// \{

//******************************************************************
/// Basic Part class.  Derive from this to get a default implementation of an IMFExPart.  
/// \see IMFExPart
class TBasicPart :	public TBasicUnknown,
					public IMFExResponder, public IMFExPart
{
	public:
		TBasicPart();
	
		virtual MCCOMErr 	MCCOMAPI QueryInterface		(const MCIID &riid, void** ppvObj);
		virtual uint32		MCCOMAPI AddRef				() { return TBasicUnknown::AddRef(); }

		virtual void		MCCOMAPI ValidateCaches		() {}
		virtual void		MCCOMAPI SelfActivate		(boolean beActive);
		virtual void		MCCOMAPI SetShown			(boolean inShown);
		virtual void		MCCOMAPI BaseWindowBecameVisible(boolean inShown);
		virtual boolean		MCCOMAPI SelfMouseMoved		(const TMCPoint& inWhere, const TMCModifiers& inModifiers);
		virtual void		MCCOMAPI SelfMouseEntering	(const TMCPoint& inWhere, const TMCModifiers& inModifiers);
		virtual void		MCCOMAPI SelfMouseStillInside(const TMCPoint& inWhere, const TMCModifiers& inModifiers);
		virtual void		MCCOMAPI SelfMouseLeaving	(const TMCModifiers& inModifiers);
		virtual TMFEventResult MCCOMAPI SelfMouseDown	(const TMCPoint& inWhere, const TMCPlatformEvent& inEvent);
		virtual boolean		MCCOMAPI SelfContextMouseDown(const TMCPoint& inWhere, const TMCPlatformEvent& inEvent);
		virtual boolean		MCCOMAPI SelfMiddleMouseDown(const TMCPoint& inWhere, const TMCPlatformEvent& inEvent);
		virtual void		MCCOMAPI SelfTrackDragAndDropEntering(const TMCPoint& inWhere, const TMFDragFlavors& inOfferedTypeList);
		virtual void		MCCOMAPI SelfTrackDragAndDropStillInside(const TMCPoint& inWhere, const TMFDragFlavors& inOfferedTypeList) ;
		virtual void		MCCOMAPI SelfTrackDragAndDropLeaving(const TMFDragFlavors& inOfferedTypeList);
		virtual boolean		MCCOMAPI SelfMouseWheel		(const TMCPoint& inWhere, const TMCModifiers& inModifiers, int16 inWheelDelta);
		virtual void		MCCOMAPI SelfDraw			(IMCGraphicContext* inContext, const TMCRect& inUpdateBBox);
		virtual void		MCCOMAPI SelfPrepareToDestroy();
		virtual void		MCCOMAPI FinishRead			();
		virtual void		MCCOMAPI FinishCreateFromResource()					{}
		virtual TMCPlatformWindow*	MCCOMAPI GetPlatformWindow()				{ return NULL; }
		virtual void		MCCOMAPI FillContextualMenu	(IMFMenu* inMenu)		{}
		virtual boolean		MCCOMAPI OverridesContextualMenuID()				{ return false; }
		virtual ResourceID	MCCOMAPI GetContextualMenuID()						{ return -1; }

		virtual boolean		MCCOMAPI ParentChangedBounds(const TMCRect& oldBounds,const TMCRect& newBounds,boolean inval);
		virtual void		MCCOMAPI GetDropArea(
										const TMCPoint&		inWhere,
										IMFDropCandidate&	inCandidate,
										IDType&				outAcceptedFlavor,
										IMFDropArea**		outDropArea,
										boolean&			outDrawDropCandidate);
		virtual boolean	 	MCCOMAPI GetValue(
										void* 				outValue, 
										MFPartValueType 	inValueType) const;

		virtual boolean		MCCOMAPI SetValueLowLevel	(const void* inValue,
														 MFPartValueType inValueType);
		// IMFExResponder
		virtual	boolean		MCCOMAPI Receive			(int32 message, IMFResponder* source, void* data);
		virtual boolean		MCCOMAPI SelfMenuAction		(ActionNumber actionNumber);
		virtual void		MCCOMAPI SelfPrepareMenus	();
		virtual boolean		MCCOMAPI SelfKeyDown		(TMCPlatformEvent* event);
		virtual void		MCCOMAPI SelfKeyUp			(TMCPlatformEvent* event);
		virtual boolean		MCCOMAPI SelfToolAction		(int32 inOldTool, int32 inNewTool);
		virtual boolean		MCCOMAPI GetToolDropCandidate(
										IMFDropCandidate**	outDropCandidate,
										int32				inToolID,
										IMFToolbarPart*		inToolbarPart);
		virtual boolean	MCCOMAPI GetIndirectToolAction(
									IShMouseAction**	outAction,
									ActionNumber&		outActionNumber,
									IMFResponder**		outContext,
									IMFPart**			outPart,
									const TMCPoint&		inWhere,
									int32 				inToolID,
									IMFToolbarPart*		inToolbarPart);

		virtual boolean		MCCOMAPI  ChangedBounds(const TMCRect& oldBounds, const TMCRect& newBounds, boolean inval);


		virtual TComponentClass* MCCOMAPI GetCursorID		(const TMCPoint& inWhere, MFCursorID& outCursorID) const
		{
			outCursorID= GetCursorID(inWhere);
			return NULL;
		}

		//old method kept so that we don't need to change everybody
		virtual MFCursorID	MCCOMAPI GetCursorID			(const TMCPoint& inWhere) const;

		virtual void		MCCOMAPI  BecameFirstResponder(boolean on);

		virtual boolean		MCCOMAPI ReadAttribute(int32 inKeyword, TMCiostream& inStream){return false;}


		//returns true as long as SelfPrepareToDestroy was never called
		inline boolean		GetNeverCalledDestroy	()	{ return fNeverCalledDestroy; }

		//Caches this part in a counted pointer, so you should NEVER call it after SelfPrepareToDestroy is called
		//(it would create a leak)
		IMFPart*			GetThisPartNoAddRef		() const;
		


		// -Description:
		//		called only by TSimpleMouseAction
		//		override to react to the mouse
		virtual void		TrackMouse(const int16 stage, const TMCPoint& first, const TMCPoint& prev, const TMCPoint& cur) {}


		// -Description:
		//		sends a message that originates from this part
		//		(calls thisResponder->BroadcastMessageUp)
		void				BroadcastUp(MessageID message, void* data);
		
	protected:
	
		mutable TMCCountedPtr<IMFPart>	fThisPart;
		boolean							fNeverCalledDestroy;	//true as long as SelfPrepareToDestroy was never called
};

//******************************************************************
/// Basic List Part class.  Derive from this for a default implementation of a list part.
class TBasicListPart :public TBasicUnknown, public IMFExListPart
{
	public:
	
		virtual MCCOMErr 	MCCOMAPI QueryInterface		(const MCIID &riid, void** ppvObj);
		virtual uint32		MCCOMAPI AddRef				() { return TBasicUnknown::AddRef(); }

		//-- IMFExListPart methods
		virtual void		MCCOMAPI SelfDrawCell(IMCGraphicContext* graphicContext, const TMCRect& cellRect, int32 inCell, boolean isSelected);
		virtual void		MCCOMAPI SelfHiliteCell(IMCGraphicContext* context, const TMCRect& cellRect, int32 inCell, boolean isSelected);
		virtual boolean		MCCOMAPI SelfClick(const TMCPoint& mouse, int32 hitCell);
		virtual void		MCCOMAPI SelfDoubleClick(const TMCPoint& mouse, int32 hitCell);
		virtual void		MCCOMAPI SelfDragDrop(const TMCRect& cellRect, int32 hitCell, const TMCPoint& m2);
		virtual void		MCCOMAPI SelfDragCell(int32 fromCell, int32 toCell);
		virtual int32		MCCOMAPI GetMinimumWidth() { return 0; }
};

//******************************************************************
/// Basic Action class.  Derive from this for a default implementation of IShAction
/// \see IShAction
class TBasicAction : public TBasicUnknown, public IShAction
{
public:
	virtual MCErr	 MCCOMAPI QueryInterface		(const MCIID& riid, void** ppvObj);
	virtual uint32	 MCCOMAPI AddRef				()					{ return TBasicUnknown::AddRef(); }
	
	virtual MCCOMErr MCCOMAPI Do					();
	virtual MCCOMErr MCCOMAPI Undo					();
	virtual MCCOMErr MCCOMAPI Redo					();
	virtual boolean  MCCOMAPI WillCauseChange		();
	virtual boolean  MCCOMAPI CanUndo				();
	virtual void	 MCCOMAPI GetPartToRedraw		(IMFPart** outPart, int32 stage);
	virtual MCCOMErr MCCOMAPI GetName				(TMCString& name);
	virtual boolean  MCCOMAPI NeedsToPrepareMenus	(void);
};

//******************************************************************
/// Basic Mouse Action class.  Derive from this for a default implementation of an IShMouseAction
/// \see IShMouseAction
class TBasicMouseAction : public TBasicUnknown, public IShMouseAction
{
public:
	virtual MCErr	 MCCOMAPI QueryInterface		(const MCIID& riid, void** ppvObj);
	virtual uint32	 MCCOMAPI AddRef				()					{ return TBasicUnknown::AddRef(); }
	virtual uint32	 MCCOMAPI Release				() = 0;

	virtual MCCOMErr MCCOMAPI Do					();
	virtual MCCOMErr MCCOMAPI Undo					();
	virtual MCCOMErr MCCOMAPI Redo					();
	virtual boolean  MCCOMAPI WillCauseChange		();
	virtual boolean  MCCOMAPI CanUndo				();
	virtual MCCOMErr MCCOMAPI GetName				(TMCString& name);
	virtual void	 MCCOMAPI Track					(IMCGraphicContext* gc, int16 stage, TMCPoint& first, TMCPoint &prev, TMCPoint &cur,boolean moved, IShMouseAction**	nextAction);
	virtual void	 MCCOMAPI TrackEx				(IMCGraphicContext* gc, int16 stage, const TMFTabletMouseSample& first, const TMFTabletMouseSample& prev, const TMFTabletMouseSample& cur, boolean moved, IShMouseAction** nextAction);
	virtual MCCOMErr MCCOMAPI Feedback				(IMCGraphicContext* gc, int16 stage,const TMCPoint& first,const TMCPoint &prev,const TMCPoint &cur,boolean moved,boolean show);
	virtual void	 MCCOMAPI GetPartToRedraw		(IMFPart** outPart, int32 stage);
	virtual MCCOMErr MCCOMAPI Constrain				(IMCGraphicContext* gc, int16 stage,const TMCPoint& first,const TMCPoint &prev,TMCPoint &cur,boolean moved); 
	virtual boolean  MCCOMAPI NeedsToPrepareMenus	(void);
	virtual boolean	 MCCOMAPI ConstrainedToView		(void);
	virtual boolean  MCCOMAPI IsPerpetualMouseAction(void);
	virtual boolean  MCCOMAPI ShouldHideCursor		(void);
	virtual boolean  MCCOMAPI ShouldAutoScroll		(void);
	virtual boolean  MCCOMAPI KeepTracking			();
	virtual boolean	 MCCOMAPI WantsTabletTracking	();
};



// -Description:
//		helper class so that you don't have to override TBasicMouseAction each time you need to do a little bit of tracking
//		instead call TSimpleMouseAction::PostSimpleMouseAction(inWhere, this); in the SelfMouseDown method of the class you derived from TBasicPart
//
//
class TSimpleMouseAction : public TBasicMouseAction
{
protected:
	TSimpleMouseAction(TBasicPart* trackingPart);
	~TSimpleMouseAction();

public:
	static void PostSimpleMouseAction(const TMCPoint& inWhere, TBasicPart* trackingPart);
	STANDARD_RELEASE;

	//will automatically call fTrackingPart->TrackMouse (if the mouse moved)
	virtual void	 MCCOMAPI Track(IMCGraphicContext* gc, int16 stage, TMCPoint& first, TMCPoint &prev, TMCPoint &cur,boolean moved, IShMouseAction**	nextAction);

protected:
	TBasicPart* fTrackingPart;
};

//******************************************************************
/// Basic Drop Area class.  Derive from this for a default implementation of an IMFExDropArea.
/// \see IMFExDropArea
class TBasicDropArea : public TBasicUnknown,
					   public IMFExDropArea
{
	public:
		
								TBasicDropArea();
		
		virtual MCCOMErr 	MCCOMAPI QueryInterface		(const MCIID &riid, void** ppvObj);
		virtual uint32		MCCOMAPI AddRef				() { return TBasicUnknown::AddRef(); }

		virtual boolean		MCCOMAPI DragIsAcceptable(
										TMFDragFlavors&		inOfferedFlavors,
										IDType&				outAcceptedFlavor,
										const TMCPoint&		inWhere);

		virtual void		MCCOMAPI Hilite(
										boolean 			inIsHilited);

		virtual boolean		MCCOMAPI IsEqualTo(
										IMFExDropArea* 		inArea);

		virtual void		MCCOMAPI ReceiveDrop(
										IMFDropCandidate*	dropCandidate,
										IDType&				acceptedType,
										MFDragDropType		moveOrCopy,
										const TMCPoint&		mousePos);
		
		virtual void		MCCOMAPI GetPart(
										IMFPart** 			outPart);
									
	protected:
		
		IMFPart*			fPart;
		
};

//******************************************************************
/// Basic Drop Candidate class.  Derive from this for a default implementation of an IMFExDropCandidate.
/// \see IMFExDropCandidate
class TBasicDropCandidate: public TBasicPart,
						   public IMFExDropCandidate
{
public:

						TBasicDropCandidate			();

	virtual MCCOMErr 	MCCOMAPI QueryInterface		(const MCIID &riid, void** ppvObj);
	virtual uint32		MCCOMAPI AddRef				() { return TBasicPart::AddRef(); }
	
	virtual MCCOMErr	MCCOMAPI GetData(
									IDType 			inFlavor, 
									MFDragDropType 	inMoveOrCopy,
									void**			outData);

	virtual void		MCCOMAPI GetOrigin(
									void**	outOrigin);
		// returns the origin of the drop candidate for use
		// in determining whether to move or copy the item
		// (clients should check for non-NULL).

	virtual void		MCCOMAPI GetOfferedFlavors		(TMFDragFlavors& outFlavors);

	virtual void		MCCOMAPI PrepareToDrag			();
	
	virtual void 		MCCOMAPI FinishedDrag			(boolean inSuccessful);
	
	virtual void		MCCOMAPI OnNoDrag				();

	virtual boolean  MCCOMAPI NeedToBeDropedOnTree(IDType inFlavor, MFDragDropType inMoveOrCopy) { return false; }

	
protected:

	TMFDragFlavors	fFlavors;
};

/// \}

#endif

