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

		IMFPart.h

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

		Author:	Greg and Josh
		Date:	4/20/98

		COM interface to internal Part objects.

		Revision History

		when		who			what & why
		==========	==========	======================================================
		11/21/99	Ian			Added SetCursor().
		10/19/99	Yann		Added GetPartBaseWindow()
		09/13/99	Pierre		Added IsShowing to the COM API
		9/01/99		Yann		added Set/GetTextStyle 
		8/31/99		Pierre		added param to GetVisibleRectsInWindow 
		8/22/99		Emil		Added SetMustFullyInvalidate to the COM API
		7/31/99		Pierre		Added SetIsOpaque to the COM API
		5/21/99		Yann		Added GetChildPartsBounds()
		4/20/99		Greg		space conversion routines in API now
		4/5/99		Greg		Added CallPrepareToDestroy
		3/3/99		Pbk			Added GetBufferedGraphicContext() and GetNonBufferedGraphicContext calls
		2/11/99		Joshua		Added SetBoundsInParent, SetPartID, SetEraseBack,
								SetExcludeFromDoubleBuffer, and SetWantsVisibleRegion to API
		1/25/99		Joshua		ProcessUpdates takes a rect to update within
								Added ProcessUpdatesPart
		1/15/98		Eml			Changed return args to out parameters for 
								FindChildIMFPartByID, GetIMFPartParent and GetIMFPartParentWindow
								and renamed them to
								FindChildPartByID, GetPartParent and GetPartParentWindow
		11/25/98	Ian			Renamed SetPosition to SetPositionInParent.
		11/2/98		Joshua		Added SetPosition
		10/22/98	Pbk			Added calls to get the clip bounds 
		10/22/98	Pbk			Added support for visible Regions
		9/18/98		Greg		Added RemoveChildIMFPart()
		9/3/98		Greg		Added GetIMFPartID()
		9/1/98		Eml			Made Enable a COM function
		8/10/98		Joshua		Added ProcessUpdates and Invalidate w/Rect to API
								Remove ImmediateUpdate from API
		8/6/98		Greg		Added a pile of API calls
		7/10/98		Greg		Added SelfMouseDown() COM API call
		6/19/98		Joshua		Added GetValue/SetValue COM API Calls
		6/1/98		Joshua		Added COM API calls
		5/28/98		Joshua		Added COM API calls
		4/20/98		Greg/Josh	Created for COM part support.

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

#ifndef __IMFPART__
#define __IMFPART__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "MCCompObj.h"
#include "MCArray.h"
#include "MCCountedPtrArray.h"
#include "MCPlateformTypes.h"
#include "MCPublicGCTypes.h"
#include "MFPartTypes.h"
#include "MCUITextStyle.h"
#include "MCEvent.h"
#include "MCRect.h"

struct IMCGraphicContext;
struct IMFWindow;
struct IMFAttribute;
struct IMFResponder;
class  TComponentClass;
class  TMFDragFlavors;

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

MCDEFINE_GUID(IID_IMFPart, 0xde9fd1d0, 0xd892, 0x11d1, 0xa0, 0xd5, 0x0, 0xaa, 0x0, 0xd3, 0x7, 0xeb);

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

struct TPartFindingInfo;

/// \addtogroup MCF
/// \{


/******************************************************************************\
*                                                                              *
*           IMFPart                                                            *
*                                                                              *
\******************************************************************************/
/// <P>A Part is the basic element from which MCFrame user interfaces are built.  They draw
/// themselves and handle user interaction.  Generally all useful Parts will implement another
/// more specialized interface as well as the IMFPart interface.</P>
/// <P>Parts are organized in a tree structure, with children considered to be inside their parent.</P>
struct IMFPart : public IMCUnknown
{
	// ****************************************************************************
	//								SetWantsToValidateCaches
	// 
	/// Tells the Part's parent window to call this Part's ValidateCaches() method before the next UI redraw.
	/// 
	/// \return	False if we are not in a window.
	virtual boolean		MCCOMAPI	SetWantsToValidateCaches	() = 0;
	
	// ****************************************************************************
	//								SelfDraw
	// 
	/// Draws the part (use this if in a part extension you want the part (not the extension) to
	/// draw itself).
	/// 
	/// \param inGraphicContext		Graphic context to use for drawing operations. 
	/// \param inUpdateBBox			Clipping rectangle for update - use to avoid redrawing more pixels than necessary
	/// 
	virtual void	 	MCCOMAPI	SelfDraw					(IMCGraphicContext* inGraphicContext, 
																 const TMCRect& 	inUpdateBBox) = 0;

	// ****************************************************************************
	//								SelfMouseDown
	// 
	/// Handles a mouse down event within the Part's bounds (use this if in a part extension you
	/// want the part (not the extension) to handle the mouse down).
	/// 
	/// \param inWhere  point in local coordinates of the mouse down
	/// \param inEvent  event information (like click count and modifier keys)
	/// \return A bitfield (see TMFEventResult).  While the previous version returned a boolean, 
	///		    generally you should now return TMFEventResult(result, result).
	virtual TMFEventResult MCCOMAPI SelfMouseDown				(const TMCPoint& 			inWhere, 
																 const TMCPlatformEvent& 	inEvent) = 0;

	// ****************************************************************************
	//								Enable
	// 
	/// Sets the enabled state of the Part.
	/// 
	/// \param beEnabled  should the part be enabled?
	/// 
	virtual void		MCCOMAPI Enable							(boolean beEnabled) = 0;
	
	// ****************************************************************************
	//								Invalidate
	// 
	/// Invalidates the Part, so it will be redrawn on the next UI redraw.
	/// 
	/// 
	virtual void	 	MCCOMAPI Invalidate						() = 0;
	
	// ****************************************************************************
	//								Invalidate
	// 
	/// Invalidates a portion of the Part, so it will be redrawn on the next UI redraw.
	/// 
	/// \param invalRect  TMCRect giving coordinates of the rectangle to invalidate
	/// 
	virtual void		MCCOMAPI Invalidate						(const TMCRect& invalRect) = 0;
	
	// ****************************************************************************
	//								ProcessUpdates
	// 
	/// Call when you need to process updates in the platform window that contains this Part.
	/// 
	/// \param inUpdateRect  Default value will update the entire platform window.  Use other values to 
	///					     specify the sub rectangle of the Part to be updated, specified in the Part's local space.
	/// 
	virtual void		MCCOMAPI ProcessUpdates					(const TMCRect& inUpdateRect=TMCRect::kInvalid) = 0;
	
	// ****************************************************************************
	//								ProcessUpdatesPart
	// 
	/// Call when you need to process updates only on the Part's sub-rect in the platform window that contains this Part.
	/// \param inPostAction	when true, an update action is posted that will be executed later
	///			(can be useful to validate caches)
	///   
	virtual void		MCCOMAPI ProcessUpdatesPart				(boolean inPostAction= false) = 0;
	
	// ****************************************************************************
	//								FindChildPartByID
	// 
	/// Locates a child Part of this Part by its ID value, if it exists.
	/// 
	/// \param outPart			Returns a pointer to the child Part, or NULL if the child doesn't exist.
	/// \param inPartID			ID of the child Part to find.
	/// \param inStopAtGroup	If true, the search will not go through group parts.
	/// 
	/// \return MC_S_OK
	virtual MCCOMErr 	MCCOMAPI FindChildPartByID				(IMFPart** outPart, uint32 inPartID, boolean inStopAtGroup=false) const = 0;


	// ****************************************************************************
	//								FindChildParts
	// 
	/// Finds several child parts at the same time
	/// 
	/// \param inPartArray  the info about the child parts we want to find \see TPartFindingInfo
	/// 
	virtual void		MCCOMAPI FindChildParts					(const TMCArray<TPartFindingInfo>& inPartArray) const = 0;
	
	// ****************************************************************************
	//								AddChildIMFPart
	// 
	/// Adds a Part as a child of this Part.
	/// 
	/// \param inPart  The Part to add as a child
	/// 
	virtual void		MCCOMAPI AddChildIMFPart				(IMFPart* inPart) = 0;
	
	// ****************************************************************************
	//								RemoveFromParent
	// 
	/// Removes this Part as child of its parent Part.
	/// 
	virtual void		MCCOMAPI RemoveFromParent				() = 0;

	// ****************************************************************************
	//								GetChildParts
	// 
	/// Fills an array with the child parts.
	/// 
	virtual void		MCCOMAPI GetChildParts					(TMCCountedPtrArray<IMFPart>& children) const = 0;
	
	// ****************************************************************************
	//								GetSystemWindowPtr
	// 
	/// 
	/// \return A pointer to the System Window that contains this Part.
	/// 
	virtual SystWindowPtr MCCOMAPI GetSystemWindowPtr			() = 0;
	
	// ****************************************************************************
	//								GetNonBufferedGraphicContext
	// 
	/// Gets a pointer to the Graphic Context to be used to draw in this Part's system window.
	/// 
	/// \param outContext  Ends up pointing to the Graphic Context.
	/// 
	virtual	void		MCCOMAPI GetNonBufferedGraphicContext	(IMCGraphicContext** outContext) = 0;

	// ****************************************************************************
	//								GetPartParent
	// 
	/// \return A pointer to the parent Part.
	/// 
	virtual IMFPart*	MCCOMAPI GetPartParent					() const = 0;

	// ****************************************************************************
	//								GetPartParent
	// 
	/// 
	/// \param outPart  Returns a pointer to the parent Part.
	/// 
	virtual MCCOMErr	MCCOMAPI GetPartParent					(IMFPart** outPart) const = 0;
	
	// ****************************************************************************
	//								GetPartParentWindow
	// 
	/// Gets the topmost window (will be the desktop window in a windoid based system)
	/// 
	/// \param outPart  Returns a pointer to the window.
	/// 
	virtual MCCOMErr 	MCCOMAPI GetPartParentWindow			(IMFPart** outPart) = 0;

	// ****************************************************************************
	//								GetPartBaseWindow
	// 
	/// Gets the window containing this Part.
	/// 
	/// \param outPart  Returns a pointer to the window.
	/// 
	virtual MCCOMErr 	MCCOMAPI GetPartBaseWindow				(IMFPart** outPart) = 0;	// Return the window containing the part

	// ****************************************************************************
	//								GetPartBaseWindowNoAddRef
	// 
	/// Gets the window containing this Part without increasing the window's reference count.
	/// 
	/// \return A pointer to the Window.
	/// 
	virtual IMFWindow*	MCCOMAPI GetPartBaseWindowNoAddRef		() = 0;

	// ****************************************************************************
	//								GetSize
	// 
	/// Accessor for the size of a given Part in pixels.
	/// 
	/// \param ioSize  Returns a TMCPoint whose x coordinate is the width and whose y coordinate is the height of this Part.
	/// 
	virtual void		MCCOMAPI GetSize						(TMCPoint& ioSize) const = 0;
	
	// ****************************************************************************
	//								GetIMFPartID
	// 
	/// Accessor for this Part's ID
	///
	/// \return The Part's ID. 
	/// 
	virtual IDType		MCCOMAPI GetIMFPartID					(void) const = 0;

	// ****************************************************************************
	//								GetActive
	// 
	/// 
	/// \return True if the window containing this part is active.
	/// 
	virtual boolean		MCCOMAPI GetActive						(void) const = 0;

	// ****************************************************************************
	//								GetPositionInWindow
	// 
	/// Returns the postion of the Part in window coordinate space.
	/// 
	/// \param ioPosition  Returns the position as a TMCPoint
	/// 
	virtual void		MCCOMAPI GetPositionInWindow			(TMCPoint& ioPosition) const = 0;

	// ****************************************************************************
	//								GetPositionInParent
	// 
	/// Returns the postion of the Part in parent coordinate space.
	/// 
	/// \param ioPosition  Returns the position as a TMCPoint
	/// 
	virtual void		MCCOMAPI GetPositionInParent			(TMCPoint& ioPosition) const = 0;

	// ****************************************************************************
	//								GetPositionInLocal
	// 
	/// Returns the postion of the Part in local coordinate space.
	/// 
	/// \param ioPosition  Returns the position as a TMCPoint
	/// 
	virtual void		MCCOMAPI GetPositionInLocal				(TMCPoint& ioPosition) const = 0;

	// ****************************************************************************
	//								GetBoundsInParent
	// 
	/// Returns the bounds of the Part in parent coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetBoundsInParent				(TMCRect& ioBounds) const = 0;

	// ****************************************************************************
	//								GetBoundsInWindow
	// 
	/// Returns the bounds of the part in window coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetBoundsInWindow				(TMCRect& ioBounds) const = 0;

	// ****************************************************************************
	//								GetBoundsInLocal
	// 
	/// Returns the bounds of the Part in local coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetBoundsInLocal				(TMCRect& ioBounds) const = 0;

	// ****************************************************************************
	//								GetClipBoundsInLocal
	// 
	/// Returns the Part clipping bounds in local coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetClipBoundsInLocal			(TMCRect& ioBounds) const = 0;
	
	// ****************************************************************************
	//								GetClipBoundsInParent
	// 
	/// Returns the Part clipping bounds in parent coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetClipBoundsInParent			(TMCRect& ioBounds) const = 0;
	
	// ****************************************************************************
	//								GetClipBoundsInWindow
	// 
	/// Returns the Part clipping bounds in window coordinate space.
	/// 
	/// \param ioBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetClipBoundsInWindow			(TMCRect& ioBounds) const = 0;

	// ****************************************************************************
	//								GetChildPartsBounds
	// 
	/// Get the rectangle that bounds all of this Part's child Parts, in coordinates local to this Part
	/// 
	/// \param outBounds  Returns the bounds as a TMCRect
	/// 
	virtual void		MCCOMAPI GetChildPartsBounds			(TMCRect& outBounds) const = 0;

	// ****************************************************************************
	//								SetSize
	// 
	/// Resizes this Part.  Performs a call to SetBoundsInParent() with the new size.
	/// 
	/// \param inSize        TMCPoint specifying the new size for the Part
	/// \param inInvalidate  If true, invalidates the Part
	/// \param inNotify      If true, notifies the parent Part of the bounds change
	/// 
	virtual void	 	MCCOMAPI SetSize						(const TMCPoint& 	inSize, 
																 boolean 			inInvalidate, 
																 boolean 			inNotify) = 0;

	// ****************************************************************************
	//								SetPositionInParent
	// 
	/// Sets the Part's position in its parent Part.  Performs a call to SetBoundsInParent() with the new position.
	/// 
	/// \param inPosition    TMCPoint specifying the new position in parent coordinate space
	/// \param inInvalidate  If true, invalidates the Part
	/// \param inNotify      If true, notifies the parent Part of the bounds change
	/// 
	virtual void	 	MCCOMAPI SetPositionInParent			(const TMCPoint& 	inPosition, 
																 boolean 			inInvalidate, 
																 boolean 			inNotify) = 0;

	// ****************************************************************************
	//								SetBoundsInParent
	// 
	/// Sets the size and position of the Part in parent coordinate space.  This function does NOT
	/// take size and position constraints into account.
	/// 
	/// \param inBounds		TMCRect specifying the new bounds in parent coordinate space
	/// \param invalidate	If true, invalidates the Part
	/// \param notify		If true, notifies the parent Part of the bounds change
	/// 
	virtual void		MCCOMAPI SetBoundsInParent				(const TMCRect& inBounds,
																 boolean invalidate = true,
																 boolean notify = false) = 0;


	// ****************************************************************************
	//								SwapOrientation
	// 
	/// Swaps the orientation of the part
	/// 
	/// \param inHorizontal  whether or not the new orientation will be horizontal 
	/// (only used for toolbars, the part swaps anyways)
	/// 
	virtual void		MCCOMAPI SwapOrientation				(boolean inHorizontal) = 0;

	// ****************************************************************************
	//								GetValue
	// 
	/// GetValue is used to access a value associated with the Part.  It does not free resources if 
	/// outValue contains a previous value.
	/// 
	/// \param outValue     Returns a pointer to the value
	/// \param inValueType  Specifies which type of value to access (See MFPartTypes.h)
	/// 
	virtual void	 	MCCOMAPI GetValue						(void* 				outValue, 
																 MFPartValueType 	inValueType) const = 0;

	// ****************************************************************************
	//								SetValue
	// 
	/// SetValue is used to set a value associated with the Part. 
	/// 
	/// \param inValue       Pointer to the value being passed
	/// \param inValueType   Specifies the type of the value passed (See MFPartTypes.h)
	/// \param inInvalidate  If true, invalidates the Part
	/// \param inNotify      If true, notifies the parent that the Part value has changed
	/// 
	virtual void	 	MCCOMAPI SetValue						(const void* 		inValue, 
																 MFPartValueType 	inValueType, 
																 boolean 			inInvalidate, 
																 boolean 			inNotify) = 0;

	// ****************************************************************************
	//								SetShown
	// 
	/// Sets whether or not this Part is Showing.
	/// 
	/// \param inShown   If true, the Part is Showing
	/// \param setChilds If true, recursively sets the children of this Part to inShown
	/// 
	virtual void		MCCOMAPI SetShown						(boolean			inShown,
																 boolean			setChilds = false) = 0;

	// ****************************************************************************
	//								IsShowing
	// 
	/// \return True if the Part is Showing.
	/// 
	/// 
	virtual boolean		MCCOMAPI IsShowing						() const = 0;
	
	// ****************************************************************************
	//								SetPartID
	// 
	/// Sets the Part ID
	/// 
	/// \param inPartID  The Part ID to set
	/// 
	virtual void		MCCOMAPI SetPartID						(MFPartID inPartID) = 0;
	
	// ****************************************************************************
	//								SetCursorID
	// 
	/// Sets the Cursor ID to use when the mouse is in the Part.
	/// 
	/// \param inCursorID  The Cursor ID
	/// 
	virtual void		MCCOMAPI SetCursorID					(MFCursorID inCursorID) = 0;
	
	// ****************************************************************************
	//								SetCursor
	// 
	/// Sets the Cursor ID to use when the mouse is in the Part, and changes the cursor to that ID immediately.
	/// 
	/// \param inCursorID  The Cursor ID
	/// 
	virtual void		MCCOMAPI SetCursor						(MFCursorID inCursorID) = 0;
	
	// ****************************************************************************
	//								SetEraseBack
	// 
	/// Sets whether or not to erase the background behind the Part before drawing the Part.
	/// 
	/// \param inEraseBack If true, the Part will erase the background before drawing. 
	/// 
	virtual void		MCCOMAPI SetEraseBack					(boolean inEraseBack) = 0;
	
	// ****************************************************************************
	//								SetMustFullyInvalidate
	// 
	/// Sets whether or not we can optimize by only invalidating the new boundaries of the Part when
	/// resizing or moving the Part. 
	/// 
	/// \param inMust  If true, the Part must be fully invalidated when changed.
	/// 
	virtual void		MCCOMAPI SetMustFullyInvalidate			(boolean inMust) = 0;
	
	// ****************************************************************************
	//								SetExcludeFromDoubleBuffer
	// 
	/// Sets whether or not to exclude this Part from double buffering.
	/// 
	/// \param inExclude  If true, the Part will be accumulated and drawn non-double-buffered.
	/// 
	virtual void		MCCOMAPI SetExcludeFromDoubleBuffer		(boolean inExclude) = 0;
	
	// ****************************************************************************
	//								SetWantsVisibleRegion
	// 
	/// Sets whether or not the Part cares about visible regions - an advanced topic generally 
	/// not required for normal UI work.
	/// 
	/// \param inWantsVisibleRegion  If true, the Part wants to have visible regions calculated
	/// 
	virtual void		MCCOMAPI SetWantsVisibleRegion			(boolean inWantsVisibleRegion) = 0;

	// ****************************************************************************
	//								SelfMouseEntering
	// 
	/// Function called when the mouse enters the Part.  Use when the Part needs to handle mouseovers, for 
	/// example to change appearance when the mouse is over it.
	/// 
	/// \param inWhere      Point in local coordinate space where the cursor is
	/// \param inModifiers  Bitfield (see TMCModifiers) listing the modifier keys currently active.
	/// 
	virtual void		MCCOMAPI SelfMouseEntering				(const TMCPoint&		inWhere,const TMCModifiers&	inModifiers) = 0;
	
	// ****************************************************************************
	//								SelfMouseStillInside
	// 
	/// Function called when the mouse tracks within the Part.  
	/// 
	/// \param inWhere      Point in local coordinate space where the cursor is
	/// \param inModifiers  Bitfield (see TMCModifiers) listing the modifier keys currently active.
	/// 
	virtual void		MCCOMAPI SelfMouseStillInside			(const TMCPoint&		inWhere,const TMCModifiers&	inModifiers) = 0;
	
	// ****************************************************************************
	//								SelfMouseLeaving
	// 
	/// Function called when the mouse leaves the Part.  Use when the Part needs to handle mouseovers, for 
	/// example to change appearance when the mouse is over it.
	/// 
	/// \param inModifiers  Bitfield (see TMCModifiers) listing the modifier keys currently active.
	/// 
	virtual void		MCCOMAPI SelfMouseLeaving				(const TMCModifiers&	inModifiers) = 0;

	// ****************************************************************************
	//								SelfTrackDragAndDropEntering
	// 
	/// Function called when the mouse enters the Part during a drag and drop.
	/// 
	/// \param inWhere			 Point in local coordinate space where the cursor is
	/// \param inOfferedTypeList Flavors offered by the current drop candiadate.
	/// 
	virtual void		MCCOMAPI SelfTrackDragAndDropEntering(const TMCPoint& inWhere,
															  const TMFDragFlavors& inOfferedTypeList) = 0;

	// ****************************************************************************
	//								SelfTrackDragAndDropStillInside
	// 
	/// Function called when the mouse track within the Part during a drag and drop.
	/// 
	/// \param inWhere			 Point in local coordinate space where the cursor is
	/// \param inOfferedTypeList Flavors offered by the current drop candiadate.
	/// 
	virtual void		MCCOMAPI SelfTrackDragAndDropStillInside(const TMCPoint& inWhere,
																 const TMFDragFlavors& inOfferedTypeList) = 0;

	// ****************************************************************************
	//								SelfTrackDragAndDropLeaving
	// 
	/// Function called when the mouse leaves the Part during a drag and drop.
	/// 
	/// \param inOfferedTypeList Flavors offered by the current drop candiadate.
	/// 
	virtual void		MCCOMAPI SelfTrackDragAndDropLeaving(const TMFDragFlavors& inOfferedTypeList) = 0;

	// ****************************************************************************
	//								BindGraphicContext
	// 
	/// Sets up the passed-in graphic context to operate within the Part.
	/// 
	/// \param drawContext  The graphic context to bind to
	/// 
	virtual void		MCCOMAPI BindGraphicContext				(IMCGraphicContext* drawContext = nil)  = 0;

	// ****************************************************************************
	//								BindNonBufferGraphicContext
	// 
	/// Same as BindGraphicContext but specific to Non Buffered Graphic Context.
	/// 
	/// \param drawContext  The graphic context to bind to (Should not be NULL)
	/// 
	virtual void		MCCOMAPI BindNonBufferedGraphicContext	(IMCGraphicContext* drawContext) = 0;
	
	// ****************************************************************************
	//								ClipContextToPart
	// 
	/// Clips the passed-in graphic context to this Part's bounds.  If no context is passed in, 
	/// expands clip area of the view's current graphic context to enclose the view's clip rectangle.
	/// (See GetClipBoundsInWindow)
	/// 
	/// \param drawContext    The graphic context to clip
	/// 
	virtual void		MCCOMAPI ClipContextToPart				(IMCGraphicContext* drawContext = nil) = 0;

	// ****************************************************************************
	//								GetVisibleRectsInWindow
	// 
	/// Creates and returns a TMCArray<TMCRect> which describe the visible rectangles in the parent window
	/// 
	/// \param fullyVisibleOnly   If true, restricts the array to fully-visible windows only.
	/// \return A pointer to the array generated.  Don't forget to free it when finished.
	/// 
	virtual TMCArray<TMCRect>* MCCOMAPI	GetVisibleRectsInWindow	(boolean fullyVisibleOnly=true) = 0;

	// ****************************************************************************
	//								ImmediateUpdate
	// 
	/// Immediately causes a redraw of this Part.  Use this sparingly - only when constant redraw and 
	/// interactivity are needed.  Otherwise, just Invalidate.
	/// 
	/// \param useDoubleBuffer  If true, uses a buffered graphics context to draw
	/// \param inBounds         A rectangle specifying the clip bounds to update.  If nil, updates the whole part.
	/// 
	virtual void		MCCOMAPI ImmediateUpdate				(boolean useDoubleBuffer=false,
																 const TMCRect* inBounds=nil) = 0;
	
	// ****************************************************************************
	//								CallPrepareToDestroy
	// 
	/// Call this function before destroying a Part, either manually or by letting its refcount go to 0. 
	/// It unregisters the Part as a responder and otherwise unhooks it from the UI.
	/// 
	virtual void		MCCOMAPI CallPrepareToDestroy			() = 0;

	// ****************************************************************************
	//								LocalToParent
	// 
	/// Converts a TMCPoint from local to parent coordinate space
	/// 
	/// \param ioParentPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	LocalToParent						(TMCPoint& ioParentPoint) const = 0;

	// ****************************************************************************
	//								LocalToParent
	// 
	/// Converts a TMCRect from local to parent coordinate space
	/// 
	/// \param ioParentRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	LocalToParent						(TMCRect& ioParentRect) const = 0;

	// ****************************************************************************
	//								LocalToWindow
	// 
	/// Converts a TMCPoint from local to window coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	LocalToWindow						(TMCPoint& ioWindowPoint) const = 0;
	
	// ****************************************************************************
	//								LocalToWindow
	// 
	/// Converts a TMCRect from local to window coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	LocalToWindow						(TMCRect& ioWindowRect) const = 0;
	
	// ****************************************************************************
	//								LocalToBaseWindow
	// 
	/// Converts a TMCPoint from local to base window coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	LocalToBaseWindow					(TMCPoint& ioWindowPoint) const = 0;
	
	// ****************************************************************************
	//								LocalToBaseWindow
	// 
	/// Converts a TMCRect from local to base window coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	LocalToBaseWindow					(TMCRect& ioWindowRect) const = 0;

	// ****************************************************************************
	//								LocalToScreen
	// 
	/// Converts a TMCPoint from local to screen/global coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	LocalToScreen						(TMCPoint& ioWindowPoint) const = 0;
	
	// ****************************************************************************
	//								LocalToScreen
	// 
	/// Converts a TMCRect from local to screen/global coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	LocalToScreen						(TMCRect& ioWindowRect) const = 0;

	// ****************************************************************************
	//								ParentToLocal
	// 
	/// Converts a TMCPoint from parent to local coordinate space
	/// 
	/// \param ioParentPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	ParentToLocal						(TMCPoint& ioParentPoint) const = 0;
	
	// ****************************************************************************
	//								ParentToLocal
	// 
	/// Converts a TMCRect from parent to local coordinate space
	/// 
	/// \param ioParentRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	ParentToLocal						(TMCRect& ioParentRect) const = 0;

	// ****************************************************************************
	//								WindowToLocal
	// 
	/// Converts a TMCPoint from window to local coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	WindowToLocal						(TMCPoint& ioWindowPoint) const = 0;
	// ****************************************************************************
	//								WindowToLocal
	// 
	/// Converts a TMCRect from window to local coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	WindowToLocal						(TMCRect& ioWindowRect) const = 0;
	
	// ****************************************************************************
	//								BaseWindowToLocal
	// 
	/// Converts a TMCPoint from base window to local coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	BaseWindowToLocal					(TMCPoint& ioWindowPoint) const = 0;

	// ****************************************************************************
	//								BaseWindowToLocal
	// 
	/// Converts a TMCRect from base window to local coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	BaseWindowToLocal					(TMCRect& ioWindowRect) const = 0;
	
	// ****************************************************************************
	//								ScreenToLocal
	// 
	/// Converts a TMCPoint from screen/global to local coordinate space
	/// 
	/// \param ioWindowPoint  The point to be converted
	/// 
	virtual void MCCOMAPI	ScreenToLocal						(TMCPoint& ioWindowPoint) const = 0;
	
	// ****************************************************************************
	//								ScreenToLocal
	// 
	/// Converts a TMCRect from screen/global to local coordinate space
	/// 
	/// \param ioWindowRect  The rectangle to be converted
	/// 
	virtual void MCCOMAPI	ScreenToLocal						(TMCRect& ioWindowRect) const = 0;
	
	// ****************************************************************************
	//								SetIsOpaque
	// 
	/// Sets the overall opacity of the Part over its full bounds.
	/// 
	/// \param isOpaque  If true, the Part is fully opaque.
	/// 
	virtual void MCCOMAPI	SetIsOpaque							(boolean isOpaque) = 0;

	// ****************************************************************************
	//								SetTextStyle
	// 
	/// Sets the text style for the Part.  This is not used by every Part, but for those 
	///	that do, this determines the type of text to draw in the Part by default.
	/// You can either pass a defined ETextStyle (kUIFont_Medium for example) and null
	/// values for the following three parameters, or you can pass kUseTextStyle and then
	/// specify a custom text style using the following three parameters.
	/// 
	/// \param inTextStyle  Either kUseTextStyle or one of the predefined ETextStyles
	/// \param inFontName   A string with the name of the font to use
	/// \param inSize       Point size of the font to use
	/// \param inFace       Style of font to use (Normal, bold, italic, etc. See IMCFont.h) 
	/// 
	virtual void MCCOMAPI	SetTextStyle						(ETextStyle			inTextStyle,
															 	 const TMCString&	inFontName,
																 uint16				inSize,	
																 uint16				inFace) = 0;

	// ****************************************************************************
	//								GetTextStyle
	// 
	/// Gets the Part's text style. \see SetTextStyle
	/// 
	/// \param outTextStyle  Returns the ETextStyle used for the Part
	/// \param outFontName   Returns the name of the font used
	/// \param outSize       Returns the point size of the font used
	/// \param outFace       Returns the style of the font used.
	/// 
	virtual void MCCOMAPI	GetTextStyle						(ETextStyle&		outTextStyle,
																 TMCString&			outFontName,
																 uint16&				outSize,
																 uint16&				outFace) = 0;


	// ****************************************************************************
	//								GetWebLink
	// 
	/// Returns the url associated with a part, null if there is none
	/// 
	virtual const TMCString* MCCOMAPI	GetWebLink	()	const = 0;


	// ****************************************************************************
	//								SetWebLink
	// 
	/// Sets the url associated with a part.
	/// 
	/// \param inLink  the url to use when open a web browser as the user clicks on the part.
	/// 
	virtual void MCCOMAPI				SetWebLink	(const TMCString& inLink) = 0;


	// ****************************************************************************
	//								SetIMFPartID
	// 
	/// Sets the Part ID.  This function is identical to SetPartID, and should not be called.
	/// It may be removed in future versions of the SDK.
	/// 
	/// \param partID  The Part ID to set.
	/// 
	virtual void MCCOMAPI	SetIMFPartID						(IDType partID) = 0;


	// ****************************************************************************
	//								SetAttribute
	// 
	/// Sets the Attribute of the Part.  This is used to set several properties of the Part,
	/// with some type checking.  <B>Note: This is currently only implemented by slider parts.</B>
	/// 
	/// \see IMFAttribute
	/// \param inAttribute  The IMFAttribute to set on this Part
	/// 
	virtual void MCCOMAPI	SetAttribute(const IMFAttribute& inAttribute) = 0;

	// ****************************************************************************
	//								GetAttribute
	// 
	/// Gets the Attribute of the Part.  This is used to get several properties of the Part,
	/// with some type checking.  <B>Note: This is currently only implemented by slider parts.</B>
	///
	/// \see IMFAttribute
	/// 
	/// \param outAttribute  Returns the IMFAttribute from the Part
	/// 
	virtual void MCCOMAPI	GetAttribute(IMFAttribute& outAttribute) = 0;

	// ****************************************************************************
	//								ResignAsResponder
	// 
	/// If this Part is the first responder, sets the first responder to be this Part's base window.
	/// If this Part is the first window responder of its base window, sets the first windor responder to the window
	/// \note You only need to call this if you are doing unusual stuff like removing a slider from a part by hand. 
	///		  Otherwise, the resignation is automatically made in SelfPrepareToDestroy.
	/// 
	virtual void MCCOMAPI	ResignAsResponder() = 0;

	// ****************************************************************************
	//								GetSystemDeviceContextPtr
	// 
	/// Returns the device context associated with the window returned by GetSystemWindowPtr()
	/// 
	/// \return A pointer to the system graphic device context
	/// 
	virtual SystemGCPtr	MCCOMAPI	GetSystemDeviceContextPtr (void) = 0;

	// ****************************************************************************
	//								FindParentPartByID
	// 
	/// Searches the hierarchy of Parts upwards from this Part, looking for a parent Part with 
	/// a given ID.
	/// 
	/// \param inPartID  The ID of the parent Part to find
	/// 
	/// \return A pointer to the parent Part, or NULL if no parent has the specified ID
	///
	virtual IMFPart*	MCCOMAPI	FindParentPartByID(uint32 inPartID) const = 0;


	// ****************************************************************************
	//								GetCursorID
	// 
	/// Returns the Identifier of the cursor that should be used when the mouse
	/// pointer is over the part.
	/// 
	/// \param inWhere      The position of the mouse cursor.
	/// \param outCursorID  the Identifier of the cursor
	///	\return a pointer to the component class the app needs to use in order to load the cursor's resource (very rarely needed).
	///			Returning null will use this (IMFExPart) resources.
	/// 
	virtual TComponentClass* MCCOMAPI GetCursorID		(const TMCPoint& inWhere, MFCursorID& outCursorID) const = 0;

	// ****************************************************************************
	//								GetThisResponder
	// 
	/// A Part is always a Responder, so this method returns a pointer to the IMFResponder interface of the Part.
	/// \return A pointer to the IMFResponder interface of the Part
	/// 
	virtual IMFResponder* MCCOMAPI	GetThisResponder()= 0;

	// ****************************************************************************
	//								FindChildPartByID
	// 
	/// Finds a child Part of the current Part by ID, and returns it without incrementing the child's refcount.
	/// 
	/// \param inPartID			The ID to search for
	/// \param inStopAtGroup	If true, the search will not go through group parts.
	/// \return A pointer to the resulting child Part, or NULL if no child Part with that ID exists.
	/// 
	virtual IMFPart*	MCCOMAPI	FindChildPartByID	(IDType inPartID, boolean inStopAtGroup=false) const = 0;

	// ****************************************************************************
	//								SetOpacityKind
	// 
	/// Sets the type of opacity used by the Part.  Parts can be fully, partially, or not opaque.
	/// \see EOpacityKind
	/// 
	/// \param inOpacityKind  
	/// 
	virtual void		MCCOMAPI	SetOpacityKind		(EOpacityKind inOpacityKind) = 0;

	// ****************************************************************************
	//								IsChildOf
	// 
	/// Given a Part, determines if this Part is a child of the given Part. If it is
	/// the same part, it returns true.
	/// 
	/// \param inPart  The Part to check for parentage of this Part
	/// \return True if this part is a child of inPart.
	/// 
	virtual boolean		MCCOMAPI	IsChildOf			(const IMFPart*	inPart) const = 0;

	///Sets whether this part is a group or not
	virtual void		MCCOMAPI	SetIsGroup			(boolean isGroup) = 0;

	///Gets whether this part is a group or not
	virtual boolean		MCCOMAPI	GetIsGroup			() const = 0;

	///Gets the first group containing this part (going up), returns null is there's none.
	virtual IMFPart*	MCCOMAPI	GetParentGroup		() const = 0;

	/// Activates the multiple values mode. 
	/// In that mode, the part can be asked to represent several values at the same time
	/// (eg both true and false)
	virtual void		MCCOMAPI	SetMultiValueMode	(boolean activateMultiValueMode) = 0;

	/// Returns true if the multiple values mode is on.
	virtual boolean		MCCOMAPI	IsInMultiValueMode	() const = 0;

	/// Returns true when the multiple values mode is on and different values have been set.
	virtual boolean		MCCOMAPI	IsValueUndefined	() const = 0;

	/// Activates multivalue mode if needed and marks the value as undefined
	virtual void		MCCOMAPI	UndefineValue		() = 0;

	/// When the part is in multiple values mode, 
	/// this must be called before repeated calls to SetValue
	virtual void		MCCOMAPI	BeginSetMultiValues	() = 0;

	/// When the part is in multiple values mode, 
	/// this must be called after repeated calls to SetValue (with the same type !)
	virtual void		MCCOMAPI	EndSetMultiValues	(MFPartValueType inValueType) = 0;

};


/// Simple struct that facilitates finding several parts at the same time
struct TPartFindingInfo : public TMCObject
{
	IDType			fPartID;		///< the id of the part to find
	const MCIID*	fInterfaceID;	///< the interface for which ask that part
	boolean			fThrowIfNil;	///< throw an exception if the part is not found or doesn't support the interface
	mutable void**	fPartPointer;	///< where to store the result

	TPartFindingInfo(IDType inPartID, const MCIID&	inInterfaceID, boolean inThrowIfNil, void**	inPartPointer)
	{
		fPartID			= inPartID;
		fInterfaceID	= &inInterfaceID;
		fThrowIfNil		= inThrowIfNil;
		fPartPointer	= inPartPointer;
	}

	TPartFindingInfo (const TPartFindingInfo& other) { *this= other; }

	TPartFindingInfo& operator= (const TPartFindingInfo& other)
	{
		fPartID			= other.fPartID;
		fInterfaceID	= other.fInterfaceID;
		fThrowIfNil		= other.fThrowIfNil;
		fPartPointer	= other.fPartPointer;
		return *this;
	}
};

/// \}

#endif