#pragma once

#include "Mix/Scene/IWaterPool.h"
#include "Mix/Private/Scene/Common/RendererObject.h"

namespace Mix{ namespace Scene{ namespace Common{

	class WaterPoolObject;

	class DefaultWaterPoolContext : public Mix::Scene::IWaterPoolContext
	{
	public:
		static DefaultWaterPoolContext* CreateInstance( const Mix::Vector3& halfExtents );

	private:
		Mix::Vector3 m_HalfExtents;
		Mix::Geometry::AABB m_Bounds;

	private:
		DefaultWaterPoolContext( const Mix::Vector3& halfExtents );
		virtual ~DefaultWaterPoolContext( void );

	public:
		virtual void Update( const Mix::Matrix4x4& worldMat );

		virtual const Mix::Geometry::AABB& GetBounds( void ) const;

		virtual Float32 Contains( const Mix::Vector3& pos ) const;
		virtual Mix::Scene::WATER_CONTAINS_RESULT Contains( const Mix::Geometry::AABB& bounds ) const;
		virtual Mix::Scene::WATER_CONTAINS_RESULT Contains( const Mix::Geometry::Sphere& bounds ) const;
	};

	class WaterPool : public Mix::Scene::IWaterPool, public Mix::Scene::Common::RendererObject
	{
	public:
		static WaterPool* CreateInstance( Mix::Scene::IWaterPoolContext* pContext );

	private:
		Mix::Scene::IWaterPoolContext* m_pContext;
		Boolean m_bRefraction;
		Mix::Scene::IWaterPool::VISUAL_PARAM m_VisualParam;
		Mix::Matrix4x4 m_WorldMat;
		Mix::Scene::Common::WaterPoolObject* m_pOctObj;

	private:
		WaterPool( Mix::Scene::IWaterPoolContext* pContext );
		virtual ~WaterPool( void );

	public:
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Common::WaterPool
		////////////////////////////////////////////////////////////////////////////////////////////////////

		void Attach( Mix::Scene::Common::WaterPoolObject* pOctObj );
		void Detach( void );

		Mix::Scene::IWaterPoolContext* GetContextPtr( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IWaterPool
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Boolean IsRefraction( void ) const;
		virtual void SetRefraction( Boolean state );

		virtual const Mix::Scene::IWaterPool::VISUAL_PARAM& GetVisualParam( void ) const;
		virtual void SetVisualParam( const Mix::Scene::IWaterPool::VISUAL_PARAM& param );

		virtual const Mix::Matrix4x4& GetWorldMatrix( void ) const;
		virtual void SetWorldMatrix( const Mix::Matrix4x4& worldMat );

		virtual void Update( void ) const;

		virtual const Mix::Geometry::AABB& GetBounds( void ) const;

		virtual void Refresh( void ) const;

		virtual Boolean IsIllegal( void ) const;

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

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

	public:
		static const wchar_t* FAILED_CREATE;
	};

}}}
