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

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

		Author:	Charles
		Date:	11/8/2001

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

#ifndef __I3DExRendererBox__
#define __I3DExRendererBox__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "InteractiveRenderDefs.h"
#include "Vector2Fwd.h"

#include "InterfaceIDs.h"

#include "IExtension.h"
#include "I3DShRenderable.h"
#include "I3DShLightSource.h"
#include <MCPlateformTypes.h>

struct I3DShCamera;
struct IWorkingBox;
struct I3DShRenderable;
struct IMCGraphicContext;

class TBBox2D;
class TMCRect;
class TMCColorRGB;
class TMCColorRGBA;


// ****************************************************************
//				definition of the GUIDs
//
MCDEFINE_GUID2	(IID_I3DExRendererBox,	R_IID_I3DExRendererBox);

#define kRendererBoxFamilyID 'RndB'


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

// ****************************************************************
//				struct I3DExRendererBox
//
/// A Renderer Box is a real time renderer used to display objects in the 3D view window.
/// (For instance OpenGL is implemented as a renderer box.
///
struct I3DExRendererBox	: public IExDataExchanger
{	
	// ****************************************************************************
	//								SetCamera	
	// 
	/// Called by the 3D database to inform the renderer that the rendering camera changed
	///
	/// \param camera:			The camera used for the rendering
	/// \param viewPane:		The coordinates of the view pane (be careful this is not in camera coordinates!
	///					You need to apply the zoom and pan to the camera coordinates).
	///
	virtual void MCCOMAPI	SetCamera(I3DShCamera* camera, const TBBox2D& viewPane)=0;


	// ****************************************************************************
	//								SetScene
	// 
	/// Sets the scene that is going to rendered. (used to get the backdrop)
	///
	/// \param scene:			the scene that is going to be rendered.
	///
	virtual void MCCOMAPI	SetScene(I3DShScene* scene)=0;
	
	/// To set the working box information, don't forget to invalidate renderer if it changes
	///
	///
	/// \param workingBox	: a pointer to the working box (can be NULL)
	///
	virtual void MCCOMAPI		SetWorkingBox(IWorkingBox* workingBox)=0;

	/// Delete a single renderable cache
	///
	/// \param renderable	: the renderable whose cache should be deleted
	///
	virtual void MCCOMAPI DeleteRenderableCache(I3DShRenderable& renderable)=0;
	

	/// Called at the beginning of the rendering
	///
	///
	/// \param awnd					: pointer to a system window ( specific to the platform )
	/// \param windowContentRect	: rectangle corresponding to the content of the window
	/// \param windowUpdateRect		: rectangle that needs to be rendered
	///
	virtual void MCCOMAPI PreDraw(SystWindowPtr awnd, const TMCRect& windowContentRect, const TMCRect& windowUpdateRect)=0;

	/// Render the instances (should be called after PreDraw())
	///
	///
	/// \param instances	: array of renderables that needs to be drawn
	/// \param renderables2D	: array of renderables 2D that needs to be drawn
	///
	virtual void MCCOMAPI DrawInstances(const TRenderableAndTfmArray& instances,const TRenderable2DArray& renderables2D)=0;

	/// Finishes the rendering (should be called after DrawInstances())
	///
	virtual MCErr MCCOMAPI PostDraw()=0;
	
	/// This is an opportunity for the renderer to update the screen without re-rendering
	///
	/// \param awnd:				Window where the rendering should be blitted.
	/// \param windowContentRect:	Rectangle of the window content
	/// \param windowUpdateRect:	Rectangle that needs to be updated
	///
	/// \return MC_S_OK if the blit succeeded
	///
	virtual MCCOMErr MCCOMAPI DrawOnScreen(SystWindowPtr awnd,const TMCRect& windowContentRect, const TMCRect& windowUpdateRect)=0;
	
	/// Update the screen without rerendering
	///
	/// \param gc:					graphic context where the rendering should be blitted
	/// \param windowContentRect:	Rectangle of the window content
	/// \param windowUpdateRect:	Rectangle that needs to be updated
	///
	/// \return MC_S_OK if the blit succeeded
	///
	virtual MCCOMErr MCCOMAPI DrawInGC(IMCGraphicContext* gc,const TMCRect& windowContentRect, const TMCRect& windowUpdateRect)=0;

	/// Sets the rendering mode
	///
	/// \param renderingMode : the new rendering mode
	///
	virtual void MCCOMAPI SetRenderingMode(const InteractiveSettings::ERenderMode renderingMode)=0;
	
	/// Returns the current rendering mode
	///
	/// \return the current rendering mode
	///
	virtual uint32	 MCCOMAPI GetRenderingMode()=0;
	
	/// Returns the different rendering modes
	///
	/// \param renderingModes: returns the list of rendering modes supported by this rendering
	///
	virtual void MCCOMAPI GetRenderingModeIDs(TMCArray<ResourceID>& renderingModes)=0;
	
	/// Tell the renderer about the render activity taking place
	///
	/// \param renderActivity: the rendering activity
	///
	virtual void MCCOMAPI SetRenderActivity(const InteractiveSettings::ERenderActivity renderActivity)=0;

	/// Sets the zoom and pan
	///
	/// \param zoom:	the zoom to be set
	/// \param pan:		the pan to be set
	///
	virtual void MCCOMAPI Set2DZoomAndPan(const TVector2& zoom,const TVector2& pan) = 0;

	/// Free all render buffers to dehydrate InteractiveRenderer when it's not activated
	///
	virtual void MCCOMAPI Dehydrate() = 0;

	/// Called when the renderer must be active again
	///
	virtual void MCCOMAPI Rehydrate() = 0;

	/// An optional call that the default interactive renderer supports.
	/// The caller supplies pixel buckets to render channel data from the renderer into.
	/// Only two channels at a time, so multiple passes may be required to generate the
	/// various channels.  This call is followed with DrawInstances, PostDraw.
	///
	/// \note This call is only supported by software renderers
	///
	/// \param colorChannel:		A pointer to the bucket where the color channel must be stored (can be NULL)
	/// \param depthChannel:		A pointer to the bucket where the depth channel must be stored (can be NULL)
	/// \param objectChannel:		A pointer to the bucket where the object channel must be stored (can be NULL)
	/// \param useAverageZ:			If true the depth channel will be filled with the average value of z
	///
	virtual MCCOMErr MCCOMAPI PreDrawChannels(	TMCPixelBucket*			colorChannel,
												TMCPixelBucket*			depthChannel,
												TMCPixelBucket*			objectChannel,
												const boolean			useAverageZ) = 0;

	/// Tells the application if the renderer needs to draw in its own platform window
	///
	///	\return True if the renderer needs to draw in its own platform window
	///
	virtual boolean	 MCCOMAPI MustDrawInSeparateWindow() = 0;

	/// Called by the shell to notify the renderer that it is not going to be
	/// used anymore. This allow the renderer to delete caches and references to windows or
	/// context.
	///
	virtual void PrepareToDestroy() = 0;

	/// Sets a pointer to an image to be display before display the scene in real time
	/// rendering. This image won't be rendered in the final rendering, it's just 
	/// an helper image.
	/// <P>Note that the Sree software rendere does not support this mode</P>
	///
	/// \param bucket pointer to the image
	/// \param startPoint in window where to start the rendering
	///
	virtual void		MCCOMAPI SetPlaneImage(TMCPixelBucket* bucket, TMCPoint& startPoint) = 0;

    enum EAdvancedRednerCapabilities
    {
        kBumpMap		= 0,
        kSpecularMap    = 1,
		kNonPowerOfTwoTextureSize,
    };

    virtual boolean MCCOMAPI    DoesSupportCapability(EAdvancedRednerCapabilities querriedCapability) const = 0;
    
    // Iff true no blitting is possible, and in order to obtain the proper content a full render is required
    virtual boolean MCCOMAPI    DoesRequireReRender() const = 0;

    virtual void MCCOMAPI GetRenderWindow(IShowBackBufferWindow** window, TMCRect& bounds) = 0;
};

/// \}


#endif
