#ifndef __CountedRenderable__
#define __CountedRenderable__
/****************************************************************************************

		CountedRenderable.h

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

		Author:	Joshua
		Date:	11/20/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		9/1/99		Alec		added TSimpleShapeRenderable
		08/10/99	Arnaud		FacetMesh is now counted.
		4/8/99		Alec		BasicRenderable -> TRenderable, 
									derives from TMCCountedObject instead of TBasicUnknown
		2/4/99		Alec		removed obsolete facet cache calls, fixed up GetFMesh
									prototype
		12/7/98		Alec		moved the fcache routines from Instance to here
		11/20/98	Joshua		Created

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

#pragma once

#include "MCCountedObject.h"
#include "MCBasicTypes.h"

#include "I3DShRenderable.h"


/// \addtogroup Data
/// \{

/// Class used to pass geometry/rendering data to the renderer.  Note that the GetBoundingBox function must always
/// return a valid bounding box, so that the renderer can optimize properly.  The TCountedRenderable supplies one 
/// kind of geometry (I3DShRenderable::EType) to the renderer, along with flags describing how to render the geometry.
/// \see I3DShRenderable
class TCountedRenderable 
	:	public TMCSMPCountedObject, 
		public I3DShRenderable
{
public:
	 TCountedRenderable();
	~TCountedRenderable();

	// don't we need a copy constructor and destructor ?, we should not copy the facet cache	
	virtual MCCOMErr			MCCOMAPI QueryInterface(const MCIID &riid, void** ppvObj);
	virtual uint32				MCCOMAPI AddRef() { return TMCSMPCountedObject::AddRef(); }
	virtual uint32				MCCOMAPI Release(){ return TMCSMPCountedObject::Release(); }

	// each renderer supports the following kinds of geometry, the renderable supplies one
	virtual I3DShRenderable::EType MCCOMAPI GetGeometryType() const;
	
	virtual const TPointMesh*		MCCOMAPI GetPointMesh() const;
	virtual const TSegmentMesh*		MCCOMAPI GetSegmentMesh() const;	
	virtual MCCOMErr				MCCOMAPI GetFMesh(real lod, FacetMesh** amesh);
	virtual const TMCPixelBucket*	MCCOMAPI GetPixelBucket(TMCRect& rect) const;

	virtual TRenderableFlags	MCCOMAPI GetRenderableFlags( void ) const;
	virtual MCCOMErr			MCCOMAPI SetRenderableFlags(const TRenderableFlags flags );
	virtual void				MCCOMAPI SetFinalRenderingFlag(boolean finalRendering) {}
	
	// a standard shader/texture approximating surface properties of the object (default implementation,
	// should not be overriden, see SelfGetShadingApproximation and SelfGetFlatennedTexturesAsync).
	virtual MCCOMErr MCCOMAPI GetShadingApproximation(TShadingApproximation& shadingApprox, uint32 uvSpaceID) const;
	virtual MCCOMErr MCCOMAPI GetFlatennedTexturesAsync(uint32 uvSpaceID, UVMaps & maps, TextureAvailableProc proc, void * privData, TMCRealRect * range = nil) const;
	
	// the bbox must always be specified, optimize for rendering which only needs a bbox
	virtual void	 MCCOMAPI GetBoundingBox(TBBox3D& bb);

	// retrieve the total uvspaces, the renderer may have to do multiple passes
	virtual uint32   MCCOMAPI GetUVSpaceCount(); // const

	virtual MCCOMErr MCCOMAPI GetInstance(I3DShInstance **instance);

	// ****************************************************************************
	//								GetLodParamType
	//
	// The default (generic) implementation returns kLod_PixelSpaceDiagonalLength
	/// \return The type of information used to calculate the appropriate LOD
	/// 
	virtual ELODParamType	MCCOMAPI GetLODParamType() const;
	// ****************************************************************************
	//                             GetRecommendedTextureSize
	//
	/// Calculate the intrinsic appropriate texture size.
	// \return true if there is such a size, or false of the texture is procedural 
	virtual boolean  MCCOMAPI GetRecommendedTextureSize(uint32 uvSpaceID, uint32 channelIndex, uint32& width, uint32& height) const;

	// ****************************************************************************
	//                             GetRelevantTextureBucketCache
	//
	/// Get the texture map file associated to the specified shading domain.
	virtual void MCCOMAPI GetRelevantTextureBucketCache(uint32 uvSpaceID, uint32 channelIndex, boolean allowMultiplierModification, IShTextureMapBucketCache **outTextureMapFile) const;
protected:
	virtual MCCOMErr MCCOMAPI SelfGetShadingApproximation(TShadingApproximation& shadingApprox, uint32 uvSpaceID) const;
	virtual MCCOMErr MCCOMAPI SelfGetFlatennedTexturesAsync(uint32 uvSpaceID, UVMaps & maps, TextureAvailableProc proc, void * privData, TMCRealRect * range = nil) const;
};

// this is the implementation of the particle renderable, just aliases to internal data
/// Implements a simple renderable where the shape data is aliased in the structure.
/// No LOD or deformation support, just returns shape data directly to the caller.
/// Perfect for wireframes, etc.  Shape creation and bbox calculations are not deferred.
/// Renderable flags can be specified directly.
///
class TSimpleShapeRenderable 
		: 	public TCountedRenderable
{
	public:
		static void Create(	TSimpleShapeRenderable ** renderable );

	protected:
		TSimpleShapeRenderable();

	public:
		// I3DShRenderable
		virtual I3DShRenderable::EType 	MCCOMAPI GetGeometryType() const;
		virtual const TPointMesh*		MCCOMAPI GetPointMesh() const;
		virtual const TSegmentMesh*		MCCOMAPI GetSegmentMesh() const;
		virtual MCCOMErr 				MCCOMAPI GetFMesh( real lod, FacetMesh** amesh );
		virtual void					MCCOMAPI GetBoundingBox(TBBox3D& bb)					{ bb = fBox; }

		virtual TRenderableFlags		MCCOMAPI GetRenderableFlags( void ) const;
		virtual MCCOMErr				MCCOMAPI SetRenderableFlags(const TRenderableFlags flags );
	
		TRenderableFlags			fFlags;
		TBBox3D 					fBox;
		const void* 				fMesh;
		I3DShRenderable::EType		fGeometryType;
		TShadingApproximation		fShader;

	protected:
		virtual MCCOMErr				MCCOMAPI SelfGetShadingApproximation(TShadingApproximation& shadingApprox, uint32 uvSpaceID) const;

};

//******************************************************************
class TInstanceRenderable : public TCountedRenderable // I3DShRenderable
{
	// Note that renderable and instance are no longer tied so don't QI.
	// This is an implementation of a single facet mesh, so this hasn't quite broken the single object
	// dependency.  See AppendToRenderables for a workaround.
	public:
		static void Create(TInstanceRenderable ** instanceRenderable);

	protected:
		TInstanceRenderable();
		TInstanceRenderable( I3DShInstance* instance );

	public:
		void SetInstance( I3DShInstance* instance );
	
		TRenderableFlags MCCOMAPI		GetRenderableFlags() const;
		MCCOMErr MCCOMAPI 				SetRenderableFlags(const TRenderableFlags flags)	{fFlags = flags; return MC_S_OK;}

		I3DShRenderable::EType MCCOMAPI GetGeometryType() const;
		MCCOMErr MCCOMAPI 				GetFMesh(real lod, FacetMesh** amesh);

		// the bbox must always be specified, optimize for rendering which only needs a bbox
		virtual void MCCOMAPI 			GetBoundingBox(TBBox3D& bb );
	
		// retrieve the total uvspaces, the renderer may have to do multiple passes
		uint32   MCCOMAPI				GetUVSpaceCount(); // const

		MCCOMErr MCCOMAPI GetInstance(I3DShInstance **instance)
		{
			TMCCountedGetHelper<I3DShInstance> result(instance);
			result = (I3DShInstance *)fInstance;
			return MC_S_OK;
		}

		I3DShInstance* MCCOMAPI			GetInstance()	{ return fInstance; }
		virtual ELODParamType	MCCOMAPI GetLODParamType() const;
		// ****************************************************************************
		//                             GetRecommendedTextureSize
		//
		/// Calculate the intrinsic appropriate texture size.
		// \return true if there is such a size, or false of the texture is procedural 
		virtual boolean  MCCOMAPI GetRecommendedTextureSize(uint32 uvSpaceID, uint32 channelIndex, uint32& width, uint32& height) const;

		// ****************************************************************************
		//                             GetRelevantTextureBucketCache
		//
		/// Get the texture map file associated to the specified shading domain.
		virtual void MCCOMAPI GetRelevantTextureBucketCache(uint32 uvSpaceID, uint32 channelIndex, boolean allowMultiplierModification, IShTextureMapBucketCache **outTextureMapFile) const;
	protected:
		// a standard shader/texture approximating surface properties of the object
		virtual MCCOMErr MCCOMAPI		SelfGetFlatennedTexturesAsync(uint32 uvSpaceID, UVMaps & maps, TextureAvailableProc proc, void * privData, TMCRealRect * range = nil) const;
		virtual MCCOMErr MCCOMAPI 		SelfGetShadingApproximation(TShadingApproximation& shadingApprox, uint32 uvSpaceID) const;

	private:
		TRenderableFlags	fFlags;
		I3DShInstance*		fInstance;

		mutable TMCClassArray< TShadingApproximation>	fShadingApproximation;
		mutable TMCArray<boolean>						fShadingApproximationValid;
};

/// \}
#endif


