#pragma once

//! @file Mix/Scene/IWaterPool.h
//! @brief ウォータープールインターフェースインクルードファイル

#include "Mix/Scene/IRendererObject.h"
#include "Mix/Geometry/AABB.h"

namespace Mix{ namespace Scene{

	//! @class IWaterPoolContext
	//! @brief ウォータープールコンテキストインターフェース
	class IWaterPoolContext : public Mix::Reference
	{
	protected:
		//! @brief デストラクタ
		virtual ~IWaterPoolContext( void ) {}

	public:
		//! @brief 更新します
		//! @param[in] worldMat 更新に使用するワールド行列を表す Mix::Matrix4x4 クラス
		//! @note GetBounds で取得する境界を更新する必要があります。
		virtual void Update( const Mix::Matrix4x4& worldMat ) = 0;

		//! @brief 境界を取得します
		//! @return 境界を表す Mix::Geometry::AABB クラスを返します
		virtual const Mix::Geometry::AABB& GetBounds( void ) const = 0;

		//! @brief 位置関係について問い合わせます
		//! @param[in] pos 位置を表す Mix::Vector3 クラス
		//! @return 水面との距離を返します( 水面より上 > 0 >= 水面より下 )
		//! @note このメソッドは GetBounds にて取得された境界で簡易判定を行った後に呼び出されます。
		virtual Float32 Contains( const Mix::Vector3& pos ) const = 0;
		//! @brief 位置関係ついて問い合わせます
		//! @param[in] bounds 境界を表す Mix::Geometry::AABB クラス
		//! @return 位置関係を表す Mix::Scene::WATER_CONTAINS_RESULT 列挙定数を返します
		//! @note このメソッドは GetBounds にて取得された境界で簡易判定を行った後に呼び出されます。
		virtual Mix::Scene::WATER_CONTAINS_RESULT Contains( const Mix::Geometry::AABB& bounds ) const = 0;
		//! @brief 位置関係ついて問い合わせます
		//! @param[in] bounds 境界を表す Mix::Geometry::Sphere クラス
		//! @return 位置関係を表す Mix::Scene::WATER_CONTAINS_RESULT 列挙定数を返します
		//! @note このメソッドは GetBounds にて取得された境界で簡易判定を行った後に呼び出されます。
		virtual Mix::Scene::WATER_CONTAINS_RESULT Contains( const Mix::Geometry::Sphere& bounds ) const = 0;
	};

	//! @class IWaterPool
	//! @brief ウォータープールインターフェース
	class IWaterPool : public Mix::Scene::IRendererObject
	{
	public:
		//! @struct VISUAL_PARAM
		//! @brief 表示パラメータ構造体
		struct VISUAL_PARAM
		{
			Mix::Vector4 color;	//!< 色
			Float32 density;	//!< 手前から奥に向かっての水の不透明度
			Float32 intensity;	//!< 全体的な不透明度
			Float32 depth;		//!< 最大深度
		};

	protected:
		//! @brief デストラクタ
		virtual ~IWaterPool( void ) {}

	public:
		//! @brief 屈折効果の判定対象とされているかどうかを確認します
		//! @return 判定対象とされている場合は True を返します
		virtual Boolean IsRefraction( void ) const = 0;
		//! @brief 屈折効果の判定対象とするかどうかを設定します
		//! @param[in] state 判定対象とする場合は True
		//! @note
		//! True として設定した場合、実際に屈折効果が行われるのではなく、<br>
		//! 屈折させるかどうかを境界を使用して判定することを意味します。
		virtual void SetRefraction( Boolean state ) = 0;

		//! @brief 表示パラメータを取得します
		//! @return パラメータを表す Mix::Scene::IWaterPool::VISUAL_PARAM 構造体を返します
		virtual const Mix::Scene::IWaterPool::VISUAL_PARAM& GetVisualParam( void ) const = 0;
		//! @brief 表示パラメータを設定します
		//! @param[in] param パラメータを表す Mix::Scene::IWaterPool::VISUAL_PARAM 構造体
		virtual void SetVisualParam( const Mix::Scene::IWaterPool::VISUAL_PARAM& param ) = 0;

		//! @brief ワールド行列を取得します
		//! @return 行列を表す Mix::Matrix4x4 クラスを返します
		virtual const Mix::Matrix4x4& GetWorldMatrix( void ) const = 0;
		//! @brief ワールド行列を設定します
		//! @param[in] worldMat 行列を表す Mix::Matrix4x4 クラス
		virtual void SetWorldMatrix( const Mix::Matrix4x4& worldMat ) = 0;

		//! @brief 更新します
		//! @note Mix::Scene::IWaterPoolContext::Update メソッドを呼び出します。
		virtual void Update( void ) const = 0;

		//! @brief 境界を取得します
		//! @return 境界を表す Mix::Geometry::AABB クラスを返します
		//! @note Mix::Scene::IWaterPoolContext::GetBounds メソッドを呼び出します。
		virtual const Mix::Geometry::AABB& GetBounds( void ) const = 0;

		//! @brief リフレッシュします
		//! @note シーンの内部にある八分木に再配置します。
		virtual void Refresh( void ) const = 0;

		//! @brief イリーガルかどうかを確認します
		//! @return イリーガルな場合は True を返します
		//! @note イリーガルとは、シーン内部の八分木の範囲を超えていることを意味します。
		virtual Boolean IsIllegal( void ) const = 0;
	};

}}
