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

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

		Author:	Arnaud
		Date:	11/26/2003

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

#ifndef __I3DWireFrameSet__
#define __I3DWireFrameSet__

#if CP_PRAGMA_ONCE
#pragma once
#endif


#include "APITypes.h"
#include "MCCompObj.h"


#include "I3DShRenderable.h"
#include "MCPtrArray.h"
#include "MCColorRGB.h"

struct FacetMesh;
struct I3DFacetCache;
struct I3DShTreeElement;
struct I3DShCamera;
struct I3DShConicalTransform;
struct I3DLineDrawer;
struct IMCGraphicContext;
struct Ray3D;
class  TTreeProjectionTransform;


//Note about wireframes:
//I3DShWireFrame and I3DExWireFrame are DEPRECATED (but kept for old code)
//so you should use I3DShWireFrameSet and I3DExWireFrameSet instead.
//I3DShWF and I3DExWF are just two interfaces used to manipulate either the deprecated or the new interface pointers.
//they will be violently replaced in the future by the I3DShWireFrameSet and I3DExWireFrameSet interfaces...


//****** Globally Unique Ids *************************************************
MCDEFINE_GUID(IID_I3DShWF, 0x8bf609d8, 0xb061, 0x451c, 0x9d, 0x58, 0x51, 0xad, 0x96, 0x61, 0xe8, 0xc2);
MCDEFINE_GUID(IID_I3DExWF, 0x5d1b5ba0, 0xae3b, 0x49cc, 0xa6, 0x4c, 0xe1, 0x2e, 0x10, 0x42, 0xa0, 0x63);

MCDEFINE_GUID(IID_I3DShWireFrameSet, 0x3279c201, 0xbd5a, 0x4aaa, 0xb1, 0xfd, 0x7f, 0x6f, 0x44, 0x9a, 0x9c, 0x8b);
MCDEFINE_GUID(IID_I3DExWireFrameSet, 0x73836687, 0x220a, 0x457b, 0x95, 0x4b, 0x2f, 0x4f, 0x88, 0x7a, 0xbf, 0xec);
//****************************************************************************

/// Defines the style in which a point should be drawn in the interactive renderer.
/// Used by TWFPointList
///
enum EWFHandleType
{
	//Keep those constants ordered and starting from 0!
	kWFNone				=	0,	///< no drawing
	kWFSquareHandle		=	1,	///< a full square point
	kWFRoundHandle		=	2,	///< a full round point
	kWFEmptySquareHandle=	3,	///< an empty square point
	kWFEmptyRoundHandle	=	4,	///< an empty round point
	kWFRoundHandleNoHit	=	5,	///< a full round point but that won't be hit

	kWFInvalidHandle	= 0x7FFFFFFF //to force 32 bits
};

enum EWFModifierKeys
{
	kWFShift=0x1, 
	kWFCommand=0x2,
	kWFOption=0x4,
	kWFControl=0x8
};

/// The diferent kinds of wireframe lists
/// keep values as bitfield!
///
enum EWFListType
{
	kWFPointList		=	0x1,	///< TWFPointList
	kWFConnectionList	=	0x2,	///< TWFConnectionList
	kWFFacetList		=	0x4,	///< not supported yet

	kWFAllListTypes		=	kWFPointList+kWFConnectionList+kWFFacetList,
	kWFInvalidListType	= 0x7FFFFFFF //to force 32 bits/deprecated api
};

/// The diferent kinds of wireframe elements
/// keep values as bitfield!
///
enum EWFElementType
{
	kWFPoint			=	0x1,	///< a point
	kWFEdge				=	0x2,	///< a segment
	kWFFacet			=	0x4,	///< not supported yet

	kWFAllElements		=	kWFPoint+kWFEdge+kWFFacet,
	kWFInvalidElemType	= 0x7FFFFFFF //to force 32 bits
};


/// Stores information about which element was hit (selected) in a I3DShWireFrameSet (or a I3DShWireFrame for compatibility)
///
struct TWFHitInfo
{
	EWFListType		fListType;		///< which subset kind was hit
	int32			fListIndex;		///< the index of the list that contains the hit element
	EWFElementType	fElemType;		///< the type of the element that was hit
	int32			fElemIndex;		///< the index of the element that was hit
	real			fHitError;		///< the distance to the element that was hit
	TVector3		fHitPointGlob;	///< the hit point in wireframe global coordinates

	TWFHitInfo()
	{
		fListType	= kWFInvalidListType;
		fListIndex	= kUnusedIndex;
		fElemType	= kWFInvalidElemType;
		fElemIndex	= kUnusedIndex;
		fHitError	= 1e35f;
		fHitPointGlob	= TVector3::kZero;
	}
};


struct I3DShWireFrameSet;
struct I3DShWireFrame;
struct I3DExWireFrameSet;
struct I3DExWireFrame;

/// \addtogroup ShellInterface
/// \{

// ****************************************************************************
//								GetNewInterface
// 
/// I3DShWF will become I3DShWireFrameSet when we get rid of the deprecated I3DShWireFrame.
/// It represents a set of wireframe that are applied to an object.
/// 
struct I3DShWF : public IMCUnknown
{
	// ****************************************************************************
	//								GetNewInterface
	// 
	/// Returns a pointer to the new interface (I3DShWireFrameSet) for wireframes if it is supported
	/// and returns NULL if it is not. In which case you should use GetDeprecatedInterface()
	/// instead.
	/// 
	virtual I3DShWireFrameSet*	MCCOMAPI GetNewInterface			() = 0;	
	
	// ****************************************************************************
	//								GetDeprecatedInterface
	// 
	/// Returns a pointer to the new interface for wireframes if it is supported
	/// and returns NULL if it is not. In which case you should use GetDeprecatedInterface()
	/// instead.
	/// 
	virtual I3DShWireFrame*		MCCOMAPI GetDeprecatedInterface		() = 0;

	// ****************************************************************************
	//								Transform
	// 
	/// Returns the transform of the wireFrame.
	/// 
	/// \param trans  
	/// 
	virtual void				MCCOMAPI Transform					(const TTreeProjectionTransform& trans) = 0;

	// ****************************************************************************
	//								TestHit
	// 
	/// Returns true if the wireframe is selected by clicking on a given point.
	/// 
	/// \param inScreenPoint    The point in screen coordinates.
	/// \param inMaxHitError    The maximum distance for selection.
	/// \param inSelectionMask  Selection mask (use a combination of the constants in EWFElementType)
	/// \param outInfo          The hit information if there is one.
	/// 
	virtual boolean				MCCOMAPI TestHit					(const TVector2& inScreenPoint, 
																	 const real		inMaxHitError,
																	 const int32	inSelectionMask,
																	 const boolean	selectBehindCamera,
																	 TWFHitInfo&		outInfo			) const = 0;

	// ****************************************************************************
	//								AddRenderables
	// 
	/// Appends the renderables of the wireframe set.
	/// 
	/// \param renderables  The renderable list.
	/// 
	virtual void				MCCOMAPI AddRenderables				(TMCPtrArray<I3DShRenderable>& renderables) = 0;

	// ****************************************************************************
	//								HasWFExcludedFromZBuffer
	// 
	/// Returns true if it contains wireframes that are excluded from the ZBuffer.
	/// 
	/// 
	virtual boolean				MCCOMAPI HasWFExcludedFromZBuffer	() const = 0;

	// ****************************************************************************
	//								SetSelectedState
	// 
	/// Sets the selection state.
	/// 
	/// \param selected  True if the wireframe is selected.
	/// 
	virtual void				MCCOMAPI SetSelectedState			(const boolean selected) = 0;
};

/// \}

/// \addtogroup ExternalInterface
/// \{

/// I3DExWF will become I3DExWireFrameSet when we get rid of the deprecated I3DExWireFrame.
///
struct I3DExWF : public IMCUnknown
{
	virtual I3DExWireFrameSet*	MCCOMAPI GetNewInterface() = 0;	
	virtual I3DExWireFrame*		MCCOMAPI GetDeprecatedInterface() = 0;

	///the following methods MUST BE common to I3DExWireFrameSet and I3DExWireFrame:
	virtual MCCOMErr MCCOMAPI GetWireFrameBBox	(TBBox3D* outBBox, int16	proj, I3DShTreeElement*	tree) = 0;
	
	///Tells your wireframe to show or not its tools (if any)
	virtual void	 MCCOMAPI ShowWFTools		(boolean show) = 0;
	virtual boolean	 MCCOMAPI HandlesTool		(int16 inTool) = 0;

	///Tells if BBox is always used to calculate parent BBox
	///In cases we do not want all helper objects
	virtual boolean  MCCOMAPI IsBBoxAlwaysUsedForParentBBox() = 0;
};

/// \}

class TWFPointList;
class TWFConnectionList;

/// \addtogroup ShellInterface
/// \{

/// Used for wireframe controls in the 3dview
/// Stores a list of TWFPointList and a list of TWFConnectionList
///
struct I3DShWireFrameSet: public IMCUnknown
{
	// ****************************************************************************
	//								HasNoEmptyList
	// 
	/// Call this function in an assert after building the set to check that every list is "valid"
	/// 
	virtual boolean				MCCOMAPI HasNoEmptyList		() = 0;

	// ****************************************************************************
	//								AllocateLists
	// 
	/// Allocates the lists of points and connections (segments).
	/// 
	/// \param pointListsCount       The number of list of points.
	/// \param connectionListsCount  The number of list of connections (segments).
	/// 
	virtual void				MCCOMAPI AllocateLists		(int32 pointListsCount, int32 connectionListsCount) = 0;

	/// Returns the number of lists of the given type
	virtual int32				MCCOMAPI GetListsCount		(EWFListType inListType) const = 0;

	// ****************************************************************************
	//								GetPointList
	// 
	/// Returns a reference to a point list.
	/// 
	/// \param pointListIndex  The index of the point list.
	/// 
	virtual TWFPointList&		MCCOMAPI GetPointList		(int32 pointListIndex) = 0;

	// ****************************************************************************
	//								GetConnectionList
	// 
	/// Returns a reference to a connection list.
	/// 
	/// \param connectionListIndex  
	/// 
	virtual TWFConnectionList&	MCCOMAPI GetConnectionList	(int32 connectionListIndex) = 0;

	// ****************************************************************************
	//								InvalidateCache
	// 
	/// Call this if you modify the positions/connections of an existing object 
	/// (AllocateLists does it for you)
	/// 
	virtual void				MCCOMAPI InvalidateCache	() = 0;
	
	// ****************************************************************************
	//								GetColor
	// 
	/// Returns the color of the elements of a list.
	/// 
	/// \param inListType   The type of list (segment or points)
	/// \param inListIndex  The index of the list.
	/// \param outColor     The color of the elements.
	/// 
	virtual void				MCCOMAPI GetColor			(EWFListType inListType, int32 inListIndex, TMCColorRGB& outColor) const = 0;

	// ****************************************************************************
	//								SetColor
	// 
	/// Sets the color of the elements of a list.
	/// 
	/// \param inListType   The type of list (segment or points)
	/// \param inListIndex  The index of the list.
	/// \param inColor      The color of the elements.
	/// 
	virtual void				MCCOMAPI SetColor			(EWFListType inListType, int32 inListIndex, const TMCColorRGB& inColor) = 0;


	// ****************************************************************************
	//								Transform
	// 
	/// Return the transform of the wireframe set.
	/// 
	/// \param trans  
	/// 
	virtual void				MCCOMAPI Transform			(const TTreeProjectionTransform& trans) = 0;

	// ****************************************************************************
	//								TestHit
	// 
	/// Returns true if one of the set's elements was hit
	/// 
	/// \param inScreenPoint    The screen point in uv camera space
	/// \param inMaxHitError    The selection zone arround each element
	/// \param inSelectionMask  A bitfield of EWFElementType values used to ignore some elements
	/// \param outInfo          The infomation about whic element was hit. Not modified if there is no hit.
	/// 
	virtual boolean		MCCOMAPI TestHit			(	const TVector2& inScreenPoint, 
														const real		inMaxHitError,
														const int32		inSelectionMask,
														const boolean	selectBehindCamera,
														TWFHitInfo&		outInfo			) const = 0;

	// ****************************************************************************
	//								AddRenderables
	// 
	/// Adds the renderables.
	/// 
	virtual void		MCCOMAPI AddRenderables		(TMCPtrArray<I3DShRenderable>& renderables) = 0;

	// ****************************************************************************
	//								HasWFExcludedFromZBuffer
	// 
	/// Returns true if some wireframes are excluded from the Z buffer
	/// 
	/// 
	virtual boolean		MCCOMAPI HasWFExcludedFromZBuffer	() const = 0;


	// ****************************************************************************
	//								SetSelectedState
	// 
	/// Sets the selection state of the wireframe.
	/// 
	virtual void		MCCOMAPI SetSelectedState			(const boolean selected) = 0;
};

/// \}

/// Info used when tracking wireframes (I3DExWireFrameSet::TrackWireFrame)
///
struct TRACKINFO
{
	TVector2	fScreenLoc;
	TVector3	fGlobalLoc;
	TVector3	fGlobalOrthoLoc;
	TVector2	fHitLoc;
	TVector2	fHitOrthoLoc;
	TVector3	fLoc;
	TVector3	fOrthoLoc;
	TVector3	fGlobalRayDirection;
	TVector3	fRayDirection;
	int32		fModifiers;			///< /see EWFModifierKeys
	int16		fStage;				///< kShBeginTracking, kShContinueTracking or kShFinishTracking
};

/// \addtogroup ExternalInterface
///
/// \{


/// Defines a set of wireframe that can be use to control certain properties of an object,
/// deformer,...
///
struct I3DExWireFrameSet: public IMCUnknown
{
	// ****************************************************************************
	//								TrackWireFrame
	// 
	/// This function is called whenever the wire frame is tracked in 3dview.
	/// 
	/// \param wireFrame  The internal wireframe
	/// \param proj       This is the 'hit' projection 	(-1: invalid, 0: XY, 1: YZ, 2: XZ, 3: 3D)
	/// \param tree       The tree that has the wireframe
	/// \param handle     The element which is tracked
	/// \param startinfo  The track info when the track started
	/// \param previnfo   The last track info before this call
	/// \param nextinfo   The new track info
	/// \param camera	  The camera of the current view	
	/// 
	virtual MCCOMErr MCCOMAPI TrackWireFrame	(	I3DShWireFrameSet* wireFrame, 
													int16				proj, 
													I3DShTreeElement*	tree, 
													const TWFHitInfo&	handle,
													const TRACKINFO& startinfo, 
													const TRACKINFO& previnfo, 
													const TRACKINFO& nextinfo,
													I3DShCamera*		camera) = 0;

	// ****************************************************************************
	//								DataToWireFrame
	// 
	/// This is where you should create the wireframe
	/// 
	/// \param wireFrame		The internal wireframe
	/// \param proj				This is the 'hit' projection 	(-1: invalid, 0: XY, 1: YZ, 2: XZ, 3: 3D)
	///								WARNING : other projections than 3 are deprecated
	/// \param tree				The tree that has the wireframe
	/// \param camera			The camera of the current view
	/// 
	virtual MCCOMErr MCCOMAPI DataToWireFrame	(I3DShWireFrameSet* wireFrame, 
												 int16				proj, 
												 I3DShTreeElement*  tree, 
												 I3DShCamera*		camera) = 0;

	virtual MCCOMErr MCCOMAPI WireFrameToData	(I3DShWireFrameSet* wireFrame, 
												 int16 proj, 
												 I3DShTreeElement* tree,
												 I3DShCamera*		camera) = 0;

	// ****************************************************************************
	//								GetWireFrameBBox
	// 
	/// Gets the wire frame bounding box
	/// 
	/// \param outBBox    The resulting bounding box
	/// \param proj       This is the 'hit' projection 	(-1: invalid, 0: XY, 1: YZ, 2: XZ, 3: 3D)
	/// \param tree       The tree that has the wireframe
	/// 
	virtual MCCOMErr MCCOMAPI GetWireFrameBBox	(TBBox3D* outBBox, int16	proj, I3DShTreeElement*	tree) = 0;
	
	///	Gets the transform to apply to the wireframe data to convert it into global space
	///
	/// \note Only implement this method if your wf data is not stored in the tree's local coordinates
	///
	///	\param tree				the tree that has the wireframe
	///	\param outTransform		the wfdata to world transform
	/// 
	///	\return MC_S_OK if outTransform is set, or MC_E_NOTIMPL to use the default
	///
	virtual MCCOMErr MCCOMAPI GetGlobalTransform(I3DShTreeElement* tree, TTransform3D& outTransform) = 0;

	// ****************************************************************************
	//								ShowWFTools
	// 
	/// Give the component a change to show or hide the Wire Frame tools
	/// 
	/// \param show  True if should show the tools, False if should hide.
	/// 
	virtual void	 MCCOMAPI ShowWFTools		(boolean show) = 0;

	// ****************************************************************************
	//								HandlesTool
	// 
	/// Return true if the given tool is to be used on handles.
	/// 
	/// \param inTool  The given tool ID.
	/// 
	virtual boolean	 MCCOMAPI HandlesTool		(int16 inTool) = 0;

	/// For wireframes that consider themselves surfaces (eg scale manipulators)
	/// computes the intersection of the given ray and the wire's surface
	///
	/// \param tree		The tree.
	/// \param localRay The ray with which the intersection is calculated.
	/// \param outInfo	The info about the intersection if there is one.
	///
	/// \return true is there is an intersection and fills outInfo
	///
	virtual boolean	 MCCOMAPI TestHit			(I3DShTreeElement* tree, const Ray3D& localRay,const real64	tmin, TWFHitInfo& outInfo) = 0;

	//  ***************************************************************************
	//								IsViewDependent
	/// Must return True if the wireframe depends on the view, to False otherwise
	///
	virtual boolean  MCCOMAPI IsViewDependent	() const = 0;


	/// Returns the name of the action associated with TrackWireFrame (displayed by undo)
	/// If that function is not implemented, the default name is "Move"
	///
	/// \param outName The name of the action.
	///
	virtual void	 MCCOMAPI GetActionName		(TMCString& outName) = 0;

	/// Returns the name scaling factor that should be applied to the object
	///
	virtual real32	 MCCOMAPI GetScalingFactor()	const = 0;

	/// Sets the scaling factor to be applied to the object
	///
	/// \param inValue the scaling factor
	///
	virtual void	 MCCOMAPI SetScalingFactor(real32 inValue) = 0;
};

/// \}





/// A list of points (in local coordinates) with a single handle style to draw them (only one style for hardware optimisation)
///
class TWFPointList
{
public:
	TWFPointList()														
	{ 
		fHandleType				= kWFNone; 
		fIsExcludedFromZBuffer	= false;
		fDrawProjections		= false;
		fIsSelected				= false;
	}

	// ****************************************************************************
	//								Clear
	// 
	void				Clear				() { fLocalPoints.ArrayFree(); }

	// ****************************************************************************
	//								GetPointsCount
	// 
	/// Get the number of point in this point list
	/// 
	/// \return the count of points
	int32				GetPointsCount		()					 const			{ return fLocalPoints.GetElemCount(); }

	// ****************************************************************************
	//								GetPointRef
	// 
	/// Get a point from the list.
	/// 
	/// \param inPointIndex  The point's index.
	/// 
	const TVector3&		GetPointRef			(int32 inPointIndex) const 			{ return fLocalPoints[inPointIndex]; }	

	//You can preallocate space and add points
	// ****************************************************************************
	//								PreAllocatePoints
	// 
	/// Prepare space for points in this list. After that you can use #AddPoint.
	/// 
	/// \param inPointsCount  The number of points there will be here.
	/// 
	void				PreAllocatePoints	(int32 inPointsCount)				{ fLocalPoints.SetElemSpace(inPointsCount); }

	// ****************************************************************************
	//								AddPoint
	// 
	/// Add a point in the list. You could call #PreAllocatePoints before adding points, but you don't have to.
	/// 
	/// \param pt  The point to add.
	/// 
	void				AddPoint			(const TVector3& pt)				{ fLocalPoints.AddElem(pt); }

	//Or create the exact number of points and set them
	// ****************************************************************************
	//								AllocatePoints
	// 
	/// Create a list with a special number of points. To access to the point use #GetPointRef.
	/// 
	/// \param inPointsCount  The number of points.
	/// 
	void				AllocatePoints		(int32 inPointsCount)				{ fLocalPoints.SetElemCount(inPointsCount); }

	// ****************************************************************************
	//								GetPointRef
	// 
	/// Get a reference to a point in the list.
	/// 
	/// \param inPointIndex  The point's index.
	/// 
	TVector3&			GetPointRef			(int32 inPointIndex)				{ return fLocalPoints[inPointIndex]; }
	
	// ****************************************************************************
	//								SetHandleType
	// 
	/// Set the handle type of the points in this list.
	/// 
	/// \param inHandleType  The new handle type.
	/// 
	void				SetHandleType		(EWFHandleType inHandleType)		{ fHandleType= inHandleType; }

	// ****************************************************************************
	//								GetHandleType
	// 
	/// Get the handle type of the points.
	/// 
	/// \return The current handle type.
	EWFHandleType		GetHandleType		()					const			{ return fHandleType; }

	// ****************************************************************************
	//								SetIsExcludedFromZBuffer
	// 
	/// When points are excluded from Z buffer they are displayed even when behind other objects.
	/// 
	/// \param inExcluded  True to exclude from Z buffer.
	/// 
	void				SetIsExcludedFromZBuffer	(boolean inExcluded)		{ fIsExcludedFromZBuffer= inExcluded;}

	// ****************************************************************************
	//								GetIsExcludedFromZBuffer
	// 
	/// Return the exclusion from Z buffer status of the points in the list.
	/// \see SetIsExcludedFromZBuffer
	/// 
	/// 
	boolean				GetIsExcludedFromZBuffer	()			const			{ return fIsExcludedFromZBuffer;}

	void				SetIsSelected		(boolean inSelected)				{ fIsSelected= inSelected; }
	boolean				GetIsSelected		()					const			{ return fIsSelected;}

	// ****************************************************************************
	//								SetDrawWBProjs
	// 
	/// Sets if the wireframe should be drawn on the working box planes.
	/// 
	/// \param drawProjections  True to draw projections
	/// 
	void				SetDrawWBProjs		(boolean drawProjections)			{ fDrawProjections= drawProjections; }

	// ****************************************************************************
	//								GetDrawWBProjs
	// 
	/// Return whether the projections of this list of points is drawn or not
	/// 
	/// \see SetDrawWBProjs
	boolean				GetDrawWBProjs		()					const			{ return fDrawProjections; }

protected:
	EWFHandleType		fHandleType;			///< The type of handle to use to display all the points
	TMCArray<TVector3>	fLocalPoints;			///< The points in object's local coordinates
	boolean				fIsExcludedFromZBuffer;
	boolean				fDrawProjections;
	boolean				fIsSelected;
};


/// TWFConnection represents a segment between two points of a TWFPointList
///
struct TWFConnection
{
	int32 fFromPoint;
	int32 fToPoint;

	inline TWFConnection()												{ fFromPoint= fToPoint= 0; }
	inline TWFConnection(int32 fromPoint, int32 toPoint)				{ fFromPoint= fromPoint; fToPoint= toPoint; }

	inline void SetValues(int32 fromPoint, int32 toPoint)				{ fFromPoint= fromPoint; fToPoint= toPoint; }
};


/// A list of connections in a TWFPointList with a single color to draw them.
/// (single color for hardware optimisation)
///
class TWFConnectionList : public TWFPointList
{
public:
	TWFConnectionList()													{ fIsSelectable= false; }

	// ****************************************************************************
	//								Clear
	// 
	void				Clear				() { TWFPointList::Clear(); fConnections.ArrayFree(); }

	// ****************************************************************************
	//								GetConnectionsCount
	// 
	/// Get the number of connections in this connections list
	/// 
	/// \return the count of connections.
	/// 
	int32					GetConnectionsCount		()							const	{ return fConnections.GetElemCount(); }

	// ****************************************************************************
	//								GetConnectionRef
	// 
	/// Get a connection from the list 
	/// 
	/// \param inConnectionIndex  The connection's index
	/// 
	const TWFConnection&	GetConnectionRef		(int32 inConnectionIndex)	const	{ return fConnections[inConnectionIndex]; }

	// ****************************************************************************
	//								PreAllocateConnections
	// 
	/// Prepare space for connections in this list. After that you can use #AddConnection.
	/// 
	/// \param inConnectionsCount  The number of points there will be here.
	/// 
	void					PreAllocateConnections	(int32 inConnectionsCount)			{ fConnections.SetElemCount(inConnectionsCount); }

	// ****************************************************************************
	//								AddConnection
	// 
	/// Add a connection in the list. You can call #PreAllocatePoints before adding points, but you don't have to.
	/// 
	/// \param cnx  The connexion to add.
	/// 
	void					AddConnection			(const TWFConnection& cnx)			{ fConnections.AddElem(cnx); }

	// ****************************************************************************
	//								AddConnection
	// 
	/// Add a connection in the list. You can call #PreAllocatePoints before adding points, but you don't have to.
	/// 
	/// \param from  The start point of the connection.
	/// \param to    The end point of the connection.
	/// 
	inline void				AddConnection			(const TVector3& from, 
													 const TVector3& to);

	// ****************************************************************************
	//								AllocateConnections
	// 
	/// Create a list with a special number of connections. To access to the connections use #GetPointRef.
	/// 
	/// \param inConnectionsCount  The number of connections.
	/// 
	void					AllocateConnections		(int32 inConnectionsCount)			{ fConnections.SetElemCount(inConnectionsCount); }

	// ****************************************************************************
	//								GetConnectionRef
	// 
	/// Get a reference to a connection in the list.
	/// 
	/// \param inConnectionIndex  The connection's index.
	/// 
	TWFConnection&			GetConnectionRef		(int32 inConnectionIndex)			{ return fConnections[inConnectionIndex]; }
	
	void					SetIsSelectable			(boolean inSelectable)				{ fIsSelectable= inSelectable; }
	boolean					GetIsSelectable			()							const	{ return fIsSelectable;}

protected:
	TMCArray<TWFConnection>		fConnections;
	boolean						fIsSelectable;

	friend class TCachedWFConnectionList;
};



void TWFConnectionList::AddConnection(const TVector3& from, const TVector3& to)
{ 
	const int32 pointIndex= GetPointsCount();
	AddPoint(from);
	AddPoint(to);
	fConnections.AddElem(TWFConnection(pointIndex,  pointIndex+1));	
}

#endif