#pragma once

#include "Mix/Geometry/Sphere.h"
#include "Mix/Scene/IPointLight.h"
#include "Mix/Private/Scene/Common/OctreeObject.h"
#include "Mix/Private/Scene/Common/RendererObject.h"

namespace Mix{ namespace Scene{ namespace Common{

	class PointLight : public Mix::Scene::IPointLight, public Mix::Scene::Common::RendererObject
	{
	public:
		struct PARAM
		{
			Mix::Vector3 pos;
			Mix::Vector3 atten;
			Mix::Vector4 color;
			Float32 outerRadius;
			Float32 invDiffRadius;
		};

	public:
		static PointLight* CreateInstance( void );

	private:
		Boolean m_bEnabled;
		Mix::Scene::Common::LocalLightObject* m_pOctObj;
		Mix::Geometry::Sphere m_Bounds;
		PointLight::PARAM m_Param;
		Float32 m_InnerRadius;

	private:
		PointLight( void );
		virtual ~PointLight( void );

		void UpdateBounds( void );

	public:
		void Attach( Mix::Scene::Common::LocalLightObject* pOctreeObj );
		void Detach( void );

		const PointLight::PARAM& GetParam( void ) const;

#ifdef _DEBUG
		void Debug_Draw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer, UInt32 flags );
#endif //_DEBUG

	public:
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IPointLight
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Float32 GetInnerRadius( void ) const;
		virtual Float32 GetOuterRadius( void ) const;
		virtual void SetRadius( Float32 innerRadius, Float32 outerRadius );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::ILocalLight
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual const Mix::Vector4& GetColor( void ) const;
		virtual void SetColor( const Mix::Vector4& color );

		virtual Float32 GetLinearAttenuation( void ) const;
		virtual Float32 GetQuadraticAttenuation( void ) const;
		virtual Float32 GetExponentAttenuation( void ) const;
		virtual void SetAttenuation( Float32 l, Float32 q, Float32 e );

		virtual const Mix::Vector3& GetPosition( void ) const;
		virtual void SetPosition( const Mix::Vector3& pos );

		virtual void Refresh( void );

		virtual const Mix::Geometry::Sphere& GetBounds() const;

		virtual Boolean IsIllegal( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::ILight
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Boolean IsEnabled( void ) const;
		virtual void SetEnabled( Boolean state );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IRendererObject
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Mix::Scene::IRendererObject::TYPE GetType( void ) const;
		virtual Boolean IsRendering( void ) const;

	public:
		static const wchar_t* FAILED_CREATE;

		static const Float32 MIN_DIFF_RADIUS;
		static const Float32 MIN_INV_DIFF_RADIUS;
	};

}}}
