#pragma once

#include "Proxies.hpp"
#include "ChildProxy.hpp"

namespace Proxies {

	class SceneProxy;

	//
	//#########################################################################
	//#########################    LightProxy    ##############################
	//#########################################################################
	//
	class _declspec(novtable) LightProxy:
		public ChildProxy
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors
	//
	protected:
		LightProxy(
			ClassData *class_data,
			SceneProxy *scene,
			GroupProxy *parent
		);
		~LightProxy();

	public:
		//
		// Copies the elements of the given material into this material
		//

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Testing
	//
	public:
		void
			TestInstance() const;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Process support
	//
	public:
		void
			FindLights(BurnLightsProcess *process);
		virtual void
			Copy(
				CopyProcess *process,
				LightProxy *light
			);
		void
			GetCentroid(Stuff::Point3D *center);
		void
			FitBoundingSphere(Stuff::Sphere *sphere);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Light functions
	//
	public:
		//
		// ambient color functions
		//
		virtual void
			GetColor(Stuff::RGBColor *color) = 0;
		virtual void
			SetColor(const Stuff::RGBColor &color) = 0;

		//
		// Ambience.  If the light is ambient (it isn't by default), then its
		// local to parent and local to world matrices are not valid
		//
		virtual bool
			IsAmbient() = 0;
		virtual void
			SetAmbient(bool ambient) = 0;

		//
		// light falloff.  The light is infinite if the GetFalloffDistance
		// function return false.  Lights default to infinite unless
		// SetFalloffDistance is called
		//
		virtual bool
			GetFalloffDistance(
				Stuff::Scalar *n,
				Stuff::Scalar *f
			) = 0;
		virtual void
			SetFalloffDistance(
				Stuff::Scalar n,
				Stuff::Scalar f
			) = 0;

		//
		// spotlight spread.  This value is only valid if the light had falloff
		//
		virtual bool
			GetSpreadAngle(Stuff::Radian *angle) = 0;
		virtual void
			SetSpreadAngle(const Stuff::Radian &radian) = 0;
	};

}
