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

		COMTreePrim.h

		Copyright (c)1990 - 1999 MetaCreations. All rights reserved.

		Author:	Jerome Bignon
		Date:	05/17/99

		Revision History

		when		who			what & why
		==========	==========	======================================================
		08/20/99	cph			updated to remove IExtension and remove COM prefix
		06/11/99	Jerome		Added animation and saving
		05/17/99	Jerome		Creation
		07/22/99	Mael		added GetPolygonInfo

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

#ifndef __COMTREEPRIM__
#define __COMTREEPRIM__  

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "I3DShModule.h"
#include "ModelerDef.h"
#include "ITreePrim.h"
#include "BasicPrimitive.h"
#include "AnimUtilities.h"
#include "I3dExAnimation.h"
#include "IModelerView.h"
#include "PublicUtilities.h"
#include "IShTokenStream.h"

// Define the TreePrim CLSID ( see the ModelerTreeDef.h file to get R_CLSID_TreePrim value )
extern const MCGUID CLSID_TreePrim;

class TreeData : public TCountedTimeBased
{
	public :
		TreeData();
		~TreeData();

		int16	fNbBranches;	// Number of branches of the 3D Tree 
		real	fAngle;			// Angle for branches
		int16	fRecursiv;		// Recursivity number for tree construction

	protected :
		virtual void RegisterParams();
};
 

// Tree Object definition : 
// TreePrimitive Object :

class TreePrim : public TBasicPrimitive,
				 public I3DExAnimated,
				 public IExStreamIO,
				 public ITreePrim
{
	struct TPMap
	{
		TPMap() : fScalingFactor(1) {}

		real32		fScalingFactor;
	};

	public :   
		TreePrim();

		virtual MCCOMErr 	MCCOMAPI QueryInterface			(const MCIID &riid, void** ppvObj);
 		virtual uint32 		MCCOMAPI AddRef 				();
		STANDARD_RELEASE;
		
		// IExtension
		virtual void MCCOMAPI Clone(IExDataExchanger** res, IMCUnknown* pUnkOuter);
  
		// IExDataExchanger methods :
		virtual void*		MCCOMAPI GetExtensionDataBuffer	()			{ return &fPMap; }
		virtual int32		MCCOMAPI GetParamsBufferSize	() const	{ return sizeof(fPMap);}
		virtual MCCOMErr	MCCOMAPI ExtensionDataChanged();
		virtual int16		MCCOMAPI GetResID();
  
		// I3DExGeometricPrimitiv methods
		// Geometric Calls
		virtual void	 	MCCOMAPI GetBoundingBox(TBBox3D& bbox);
		virtual MCCOMErr	MCCOMAPI EnumPatches(EnumPatchesCallback callback, void* privData, boolean& closed);
		virtual MCCOMErr    MCCOMAPI GetNbrLOD(int16 &nbrLod);
		virtual MCCOMErr	MCCOMAPI GetFacetMesh(uint32 index, FacetMesh** outMesh); // index is the lod number
		virtual boolean     MCCOMAPI CanBeSplit();
		virtual MCCOMErr    MCCOMAPI SplitPrimitive(TMCCountedPtrArray<I3DExGeometricPrimitive>& subParts, TMCArray<TTransform3D>& subPartPositions);

		virtual boolean		MCCOMAPI AutoSwitchToModeler() const;
		
		// Handle scene magnitude
		virtual boolean		MCCOMAPI IsScalable() const			{ return true; }
		virtual real32		MCCOMAPI GetScalingFactor()	const	{ return fPMap.fScalingFactor; }
		virtual void		MCCOMAPI SetScalingFactor(real32 inValue) { fPMap.fScalingFactor = inValue; }


		// Shading Calls
		virtual uint32		MCCOMAPI GetUVSpaceCount();
		virtual MCCOMErr 	MCCOMAPI GetUVSpace( uint32 uvSpaceID, UVSpaceInfo* uvSpaceInfo);
		virtual MCCOMErr    MCCOMAPI UV2XYZ(TVector2* uv, uint32 uvSpaceID, TVector3* resultPosition, boolean* inUVSpace); // Optional - Return E_NOTIMPL if not implemented
		virtual MCCOMErr    MCCOMAPI GetUVSpaceRDS5(uint32 uvSpaceID, UVSpaceInfoRDS5* uvSpaceInfoRDS5); // To be implemented only if your primitive existed in RDS 5 or earlier, so that UV spaces can be mapped properly to the new 0..1 boundaries
		virtual MCCOMErr	MCCOMAPI AppendToRenderables(const TTransform3D& worldFromModelTfm,
															TRenderableAndTfmArray& renderableAndTfm );
  		

		virtual boolean		MCCOMAPI SetData(const TreeData* data);		
		virtual void		MCCOMAPI GetData(TreeData** data);

		virtual real		MCCOMAPI GetAngleAndPoint( TMCPoint *pt, TMCPoint *pt0, int16 numView, real zoom );	
		virtual	boolean		MCCOMAPI GetIfDataChanged();
		
		// I3DExAnimated calls
		virtual MCCOMErr	MCCOMAPI RegisterParams();
		virtual MCCOMErr	MCCOMAPI InvalidateCaches(int32 itsID);
		virtual MCCOMErr	MCCOMAPI CopyTimeData(IMCUnknown *dest);

		// IExStreamIO calls
		virtual MCCOMErr	MCCOMAPI Read(IShTokenStream* stream, ReadAttributeProc readUnknown, void* privData); // readUnknown should be called by extention if unknown keyword is encountered (instead of calling SkipTokenData)
		virtual MCCOMErr	MCCOMAPI Write(IShTokenStream* stream);

		void CopyData(TreePrim* dest) const;

		virtual MCCOMErr MCCOMAPI FinishRead		(IStreamContext* streamContext) {return MC_S_OK;}
		virtual MCCOMErr MCCOMAPI InvalidateCaches(int32 itsID, int32 itsIndex) {return MC_S_OK;}

	protected:	
		TMCCountedPtr<TreeData>	fData;       // Tree Data

		MCCOMErr	UpdateBoundingBox( TVector3 *Coordinate );
		TVector3	Rotate( TVector3 &Vertex , TVector3 &angle );
		TVector3	Normal( TVertex3D	*fVertices );
	
		TVector3	Cube(FacetMeshAccumulator *accum, real SizeZ , real SizeXY , TVector3 &angle , TVector3 &translate);
		MCCOMErr	GetFacetsTree(FacetMeshAccumulator *accum, int16 level , TVector3 angle , TVector3 translate );

		TBBox3D 	fTreeBox;   // BoundingBox
		boolean		fDataChanged;	// true if Data changed

		TPMap		fPMap;

	private :
		friend class TreeData;
		TMCCountedPtr<I3DShTimeBasedData> fTimeBasedData;
};


#endif // __TreePrimitive__