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

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

		Author:	Charles
		Date:	1/14/2002

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

#ifndef __BasicDistantLight__
#define __BasicDistantLight__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "BasicCameraLightGel.h"
#include "MCColorRGBA.h"
#include "MCArray.h"

/// \addtogroup BaseClass
/// \{

/// Basic Distant Light class.  Derive from this for a default implementation of an I3DExLightsource for a distant type light
/// \see I3DExLightsource
class TBasicDistantLight : public TBasicLight,public I3DExDistantLight
{
public:
	TBasicDistantLight();
	~TBasicDistantLight();

	virtual MCCOMErr 	MCCOMAPI QueryInterface(const MCIID &riid, void** ppvObj);
	virtual uint32 		MCCOMAPI AddRef() { return TBasicLight::AddRef(); }

	virtual MCCOMErr MCCOMAPI ExtensionDataChanged();
	virtual MCCOMErr MCCOMAPI SetTransform(TTransform3D* transform);
	virtual MCCOMErr MCCOMAPI GetDirection(const TVector3 &point,TVector3 &resultDirection,real &resultDistance);
	virtual boolean  MCCOMAPI GetColor(const TVector3 &point,const TVector3 &direction,const real distance,TMCColorRGB &result,real& ShadowIntensity);
	virtual boolean  MCCOMAPI IsVisibleInPerspective();
	virtual uint32   MCCOMAPI GetPrimitiveID();
	virtual MCCOMErr MCCOMAPI ForEachShadowBuffer(ForEachShadowBufferCallback proc, void* priv);
	virtual boolean  MCCOMAPI GetUVfromDirection(TVector2 &uv,const TVector3 &direction) const;

	// retrieve a standard description of the light for use in the interactive renderer
	virtual MCCOMErr MCCOMAPI GetStandardLight( TStandardLight& light ) const;

	virtual void	 MCCOMAPI InitSampling(const TBBox3D&	sceneBoundingBox,
										   real&			solidAngle,
										   int32&			regionCount);
	virtual void	 MCCOMAPI GetRandomRay(int32 regionIndex,Ray3D& ray) const;

	virtual int32	 MCCOMAPI GetShadowBufferCount() const;
	virtual void	 MCCOMAPI GetShadowBuffer(int32 bufferIndex,I3DShCamera** camera,TBBox2D& uvBox) const;

	virtual real32	MCCOMAPI GetScalingFactor()	const { return fData.fScalingFactor; }
	virtual void	MCCOMAPI SetScalingFactor(real32 inValue) { fData.fScalingFactor = inValue; }

	virtual real MCCOMAPI UpdateLightRadius(const real radiusFromShadowFeature) const;


	static const MCGUID ClassId;

public:
	struct Data
	{
		Data();

		TMCColorRGBA	fColor;
		real			fBrightness;
		real			fShadows;
		TVector3		fDirection; // this is a redundant rotation
		boolean			fShadowOn;
		real32			fScalingFactor;
	};

	Data				fData;

protected:
	TMCColorRGB		fBritColor;

	TTransform3D	fTransform;

	TVector3		fI,fJ,fD;		// (fI,fJ,fD) is an orthonormal base, fD is the direction of the light

	TVector2		fMin;			// min coordinates of the scene rectangle
	TVector2		fMax;			// max coordinates of the scene rectangle

	real			fSamplingDistance;

	mutable TMCArray<TMCAtomicCounter*>		fSampleIndices;

	static const real32	sRealMax;
};

/// \}

#endif
