#pragma once

//! @file Mix/Graphics/Utility/IPerspectiveRenderer.h
//! @brief パースペクティブレンダラーインターフェースインクルードファイル

#include "Mix/Reference.h"
#include "Mix/Geometry/Sphere.h"
#include "Mix/Geometry/AABB.h"
#include "Mix/Geometry/OBB.h"
#include "Mix/Geometry/Frustum.h"

namespace Mix{ namespace Graphics{ namespace Utility{

	//! @class IPerspectiveRenderer
	//! @brief パースペクティブレンダラーインターフェース
	class IPerspectiveRenderer : public Mix::Reference
	{
	protected:
		//! @brief デストラクタ
		virtual ~IPerspectiveRenderer( void ){}

	public:
		//! @brief 色を設定します
		//! @param[in] color 色を表す Mix::Vector4 クラス
		virtual void SetColor( const Mix::Vector4& color ) = 0;
		//! @brief 色を取得します
		//! return 色を表す Mix::Vector4 クラスを返します
		virtual const Mix::Vector4& GetColor( void ) const = 0;

		//! @brief 変換行列を設定します
		//! @param[in] mat 変換行列を表す Mix::Matrix4x4 クラス
		virtual void SetMatrix( const Mix::Matrix4x4& mat ) = 0;
		//! @brief 変換行列を取得します
		//! @return 変換行列を表す Mix::Matrix4x4 クラスを返します
		virtual const Mix::Matrix4x4& GetMatrix( void ) const = 0;

		//! @brief ラインを追加します
		//! @param[in] p0 一つ目のポイントを表す Mix::Vector3 クラス
		//! @param[in] p1 二つ目のポイントを表す Mix::Vector3 クラス
		virtual void AddLine( const Mix::Vector3& p0, const Mix::Vector3& p1 ) = 0;
		//! @brief ラインを追加します
		//! @param[in] points ポイントテーブルを表す Mix::Vector3 クラスのポインタ
		//! @param[in] pointNum ポイントの数( 2の倍数である必要があります )
		virtual void AddLines( const Mix::Vector3* points, UInt32 pointNum ) = 0;

		//! @brief 軸を追加します
		//! @param[in] scale スケール
		virtual void AddAxis( Float32 scale = 1.0f ) = 0;

		//! @brief ボックスを追加します
		//! @param[in] halfExtents ボックスの半分のサイズを表す Mix::Vector3 クラス
		virtual void AddBox( const Mix::Vector3& halfExtents ) = 0;
		//! @brief ボックスを追加します
		//! @param[in] obb ボックスを表す Mix::Geometry::OBB クラス
		virtual void AddBox( const Mix::Geometry::OBB& obb ) = 0;
		//! @brief ボックスを追加します
		//! @param[in] aabb ボックスを表す Mix::Geometry::AABB クラス
		virtual void AddBox( const Mix::Geometry::AABB& aabb ) = 0;

		//! @brief シリンダーを追加します
		//! @param[in] axis 軸( 0:X 1:Y 2:Z )
		//! @param[in] length 半球の部分を含む軸の長さ
		//! @param[in] radius 半径
		virtual void AddCylinder( UInt32 axis, Float32 length, Float32 radius ) = 0;

		//! @brief カプセルを追加します
		//! @param[in] axis 軸( 0:X 1:Y 2:Z )
		//! @param[in] length 半球の部分を含む軸の長さ
		//! @param[in] radius 半径
		virtual void AddCapsule( UInt32 axis, Float32 length, Float32 radius ) = 0;

		//! @brief フラスタムを追加します
		//! @param[in] frustum フラスタムを表す Mix::Geometry::Frustum クラス
		virtual void AddFrustum( const Mix::Geometry::Frustum& frustum ) = 0;

		//! @brief スフィアを追加します
		//! @param[in] radius 半径
		virtual void AddSphere( Float32 radius ) = 0;
		//! @brief スフィアを追加します
		//! @param[in] radius XYZの半径を表す Mix::Vector3 クラス
		virtual void AddSphere( const Mix::Vector3& radius ) = 0;
		//! @brief スフィアを追加します
		//! @param[in] center 中心座標を表す Mix::Vector3 クラス
		//! @param[in] radius 半径
		virtual void AddSphere( const Mix::Vector3& center, Float32 radius ) = 0;
		//! @brief スフィアを追加します
		//! @param[in] center 中心座標を表す Mix::Vector3 クラス
		//! @param[in] radius XYZの半径を表す Mix::Vector3 クラス
		virtual void AddSphere( const Mix::Vector3& center, const Mix::Vector3& radius ) = 0;
		//! @brief スフィアを追加します
		//! @param[in] sphere スフィアを表す Mix::Geometry::Sphere クラス
		virtual void AddSphere( const Mix::Geometry::Sphere& sphere ) = 0;

		//! @brief コーン( 円錐 )を追加します
		//! @param[in] pos コーンの頂点を表す Mix::Vector3 クラス
		//! @param[in] vec コーンの頂点から底面の中心へのベクトルを表す Mix::Vector3 クラス
		//! @param[in] angle コーンの外角( ラジアン単位 )
		//! @param[in] divCount 分割数( 4〜36 )
		virtual void AddCone( const Mix::Vector3& pos, const Mix::Vector3& vec, Float32 angle, UInt32 divCount ) = 0;

		//! @brief ディスク(円盤)を追加します
		//! @param[in] axis ディスクの軸を表す Mix::Vector3 クラス
		//! @param[in] radius ディスクの半径
		virtual void AddDisc( const Mix::Vector3& axis, Float32 radius ) = 0;

		//! @brief 多角形を追加します
		//! @param[in] points 多角形の点を表す Mix::Vector3 クラスの配列
		//! @param[in] pointNum 点の数
		virtual void AddPolygon( const Mix::Vector3* points, UInt32 pointNum ) = 0;

		//! @brief 更新を行います
		virtual void Update( void ) = 0;

		//! @brief 描画を行います
		//! @param[in] viewProjMat 透視変換行列を表す Mix::Matrix4x4 クラス
		virtual void Draw( const Mix::Matrix4x4& viewProjMat ) = 0;
	};

}}}
