#pragma once

//! @file Mix/Geometry/Frustum.h
//! @brief フラスタムクラスインクルードファイル

#include "Mix/Geometry/AABB.h"
#include "Mix/Geometry/Plane.h"
#include "Mix/Geometry/Sphere.h"

namespace Mix{ namespace Geometry{

	//! @class Frustum
	//! @brief フラスタムクラス
	class Frustum
	{
	public:
		//! @enum PLANE_TYPE
		//! @brief プレーンタイプ列挙定数
		enum PLANE_TYPE
		{
			PLANE_NEAR		= 0,	//!< 手前
			PLANE_FAR		= 1,	//!< 奥
			PLANE_TOP		= 2,	//!< 上
			PLANE_BOTTOM	= 3,	//!< 下
			PLANE_LEFT		= 4,	//!< 左
			PLANE_RIGHT		= 5,	//!< 右
		};

	private:
		Mix::Matrix4x4 m_ViewProjMat;
		Mix::Geometry::Plane m_Planes[6];

	public:
		//! @brief コンストラクタ
		Frustum( void );
		//! @brief コンストラクタ
		//! @param[in] viewProjMat 透視変換行列を表す Mix::Matrix4x4 クラス
		Frustum( const Mix::Matrix4x4& viewProjMat );

		//! @brief 更新を行います
		void Update( const Mix::Matrix4x4& viewProjMat );

		//! @brief 透視変換行列を取得します
		//! @return 透視変換行列を表す Mix::Matrix4x4 クラスを返します
		const Mix::Matrix4x4& GetViewProjectionMatrix( void ) const;

		//! @brief フラスタムを構成する平面を取得します
		//! @param[in] type Mix::Geometry::Frustum::PLANE_TYPE 列挙定数
		//! @return 平面を表す Mix::Geometry::Plane クラスを返します
		const Mix::Geometry::Plane& GetPlane( Mix::Geometry::Frustum::PLANE_TYPE type ) const;

		//! @brief 点がフラスタム内に入っているかどうかを判定します
		//! @param[in] point 点を表す Mix::Vector3 クラス
		//! @return 点がフラスタム内に入っている場合は True を返します
		Boolean Contains( const Mix::Vector3& point ) const;
		//! @brief 球がフラスタム内に入っているかどうかを判定します
		//! @param[in] sphere 球を表す Mix::Geometry::Sphere クラス
		//! @return 球がフラスタム内に入っている場合は True を返します
		Boolean Contains( const Mix::Geometry::Sphere& sphere ) const;
		//! @brief 球がフラスタム内に入っているかどうかを判定します( Top Bottom Left Right )
		//! @param[in] sphere 球を表す Mix::Geometry::Sphere クラス
		//! @return 球がフラスタム内に入っている場合は True を返します
		Boolean ContainsTBLR( const Mix::Geometry::Sphere& sphere ) const;
		//! @brief AABBがフラスタム内に入っているかどうかを判定します
		//! @param[in] aabb AABBを表す Mix::Geometry::AABB クラス
		//! @return AABBがフラスタム内に入っている場合は True を返します
		//! @note 事前に Mix::Geometry::AABB::ComputePoints を実行しておく必要があります
		Boolean Contains( const Mix::Geometry::AABB& aabb ) const;
		//! @brief AABBがフラスタム内に入っているかどうかを判定します( Top Bottom Left Right )
		//! @param[in] aabb AABBを表す Mix::Geometry::AABB クラス
		//! @return AABBがフラスタム内に入っている場合は True を返します
		//! @note 事前に Mix::Geometry::AABB::ComputePoints を実行しておく必要があります
		Boolean ContainsTBLR( const Mix::Geometry::AABB& aabb ) const;
	};

}}
