//==========================================================================//
// File:	 gosFX_PointLight.hpp										//
// Project:  gosFX					                                        //
// Contents: Base PointLight Particle									//
//--------------------------------------------------------------------------//
// Date      Who    Modification                                            //
// 09/28/98  JTR    Created													//
//																			//
//--------------------------------------------------------------------------//
// Copyright (C) 1997-1998, Virtual World Entertainment, Inc.               //
// All Rights reserved worldwide                                            //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL              //
//==========================================================================//
//
#pragma once

#include "Adept.hpp"
#include <ElementRenderer\LightElement.hpp>

namespace MidLevelRenderer {
	class MLRInfiniteLightWithFalloff;
	class MLRPointLight;
	class MLRSpotLight;
	class MLRAmbientLight;
	class MLRInfiniteLight;
	class MLRLookUpLight;
	class MLRProjectLight;
	class MLRShadowLight;
	class MLRCenterPointLight;
}

namespace Adept
{
	//########################################################################
	//#######################  EnvironmentalLight  ###########################
	//########################################################################

	class __declspec(novtable) EnvironmentalLight:
		public gosFX::Light
	{
	public:
		EnvironmentalLight(MidLevelRenderer::MLRLight* light);
		~EnvironmentalLight();

		typedef gosFX::Light BaseClass;
	};

	//########################################################################
	//##########################  AmbientLight  ##############################
	//########################################################################

	class AmbientLight:
		public EnvironmentalLight
	{
	public:
		AmbientLight(MidLevelRenderer::MLRAmbientLight* light);

		MidLevelRenderer::MLRAmbientLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRAmbientLight*, m_light);}

		typedef EnvironmentalLight BaseClass;
	};

	//########################################################################
	//##########################  InfiniteLight  #############################
	//########################################################################

	class InfiniteLight:
		public EnvironmentalLight
	{
	public:
		InfiniteLight(MidLevelRenderer::MLRInfiniteLight* light);

		MidLevelRenderer::MLRInfiniteLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRInfiniteLight*, m_light);}

		typedef EnvironmentalLight BaseClass;
	};

	//########################################################################
	//##########################  InfiniteLight  #############################
	//########################################################################

	class LookupLight:
		public InfiniteLight
	{
	public:
		LookupLight(MidLevelRenderer::MLRLookUpLight* light);

		MidLevelRenderer::MLRLookUpLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRLookUpLight*, m_light);}

		typedef InfiniteLight BaseClass;
	};

	//########################################################################
	//###########################  FiniteLight  ##############################
	//########################################################################

	class __declspec(novtable) FiniteLight:
		public gosFX::Light
	{
	public:
		FiniteLight(MidLevelRenderer::MLRInfiniteLightWithFalloff* light);
		~FiniteLight();

		void
			ChangeLight(gosFX::LightManager::Info *info);
		void
			GetInfo(gosFX::LightManager::Info *info);

		MidLevelRenderer::MLRInfiniteLightWithFalloff*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRInfiniteLightWithFalloff*, m_light);}

		BYTE
			m_minRow,
			m_maxRow,
			m_minColumn,
			m_maxColumn;

		typedef gosFX::Light BaseClass;
	};

	//########################################################################
	//############################  PointLight  ##############################
	//########################################################################

	class PointLight:
		public FiniteLight
	{
	public:
		PointLight(MidLevelRenderer::MLRPointLight* light);

		MidLevelRenderer::MLRPointLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRPointLight*, m_light);}

		typedef FiniteLight BaseClass;
	};

	//########################################################################
	//############################  SpotLight  ###############################
	//########################################################################

	class SpotLight:
		public FiniteLight
	{
	public:
		SpotLight(MidLevelRenderer::MLRSpotLight* light);

		void
			ChangeLight(gosFX::LightManager::Info *info);
		void
			GetInfo(gosFX::LightManager::Info *info);

		MidLevelRenderer::MLRSpotLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRSpotLight*, m_light);}

		typedef FiniteLight BaseClass;
	};

	//########################################################################
	//##########################  ProjectLight  ##############################
	//########################################################################

	class ProjectLight:
		public FiniteLight
	{
	public:
		ProjectLight(MidLevelRenderer::MLRProjectLight* light);

		void
			ChangeLight(gosFX::LightManager::Info *info);
		void
			GetInfo(gosFX::LightManager::Info *info);

		MidLevelRenderer::MLRProjectLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRProjectLight*, m_light);}

		typedef FiniteLight BaseClass;
	};

	//########################################################################
	//##########################  ShadowLight  ##############################
	//########################################################################

	class ShadowLight:
		public FiniteLight
	{
	public:
		ShadowLight(MidLevelRenderer::MLRShadowLight* light);

		void
			ChangeLight(gosFX::LightManager::Info *info);
		void
			GetInfo(gosFX::LightManager::Info *info);

		MidLevelRenderer::MLRShadowLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRShadowLight*, m_light);}

		ElementRenderer::Element
			*m_shadowCaster;

		typedef FiniteLight BaseClass;
	};

	//########################################################################
	//#########################  CenterPointLight  ###########################
	//########################################################################

	class CenterPointLight:
		public FiniteLight
	{
	public:
		CenterPointLight(MidLevelRenderer::MLRCenterPointLight* light);

		MidLevelRenderer::MLRCenterPointLight*
			GetMLRLight()
				{return Cast_Pointer(MidLevelRenderer::MLRCenterPointLight*, m_light);}

		typedef FiniteLight BaseClass;
	};

	//############################################################################
	//#########################  TiledLightManager  ##############################
	//############################################################################

	class TiledLightManager:
		public ElementRenderer::LightElementManager
	{
	public:
		static void
			InitializeClass(Stuff::NotationFile *startup_ini);
		static void
			TerminateClass(Stuff::NotationFile *startup_ini);

		static TiledLightManager* &Instance;

		TiledLightManager();
		~TiledLightManager();

		gosFX::Light*
			MakeAmbientLight();
		gosFX::Light*
			MakeInfiniteLight();
		gosFX::Light*
			MakeLookupLight();

		gosFX::Light*
			MakePointLight(
				const char* light_map=NULL,
				bool light_vertex=true
			);
		gosFX::Light*
			MakeSpotLight(
				const char* light_map=NULL,
				bool light_vertex=true
			);
		gosFX::Light*
			MakeProjectLight(
				const char* light_map=NULL,
				bool light_vertex=true
			);
		gosFX::Light*
			MakeShadowLight(
				const char* light_map=NULL,
				bool light_vertex=true
			);
		gosFX::Light*
			MakeCenterPointLight(
				const char* light_map=NULL,
				bool light_vertex=true
			);

		gosFX::Light*
			MakeLight(MidLevelRenderer::MLRLight *light);

	//
	//-----------------
	// Shadow functions
	//-----------------
	//
	public:
		enum ShadowMode {
			e_NoShadows,
			e_Shadows,
			e_ArticulatedShadows
		};

		static ShadowMode
			s_ShadowMode;

		void
			CastShadows(ElementRenderer::CameraElement *camera);

	protected:
		Stuff::ChainOf<ShadowLight*>
			m_shadows;
	};

}
