#pragma once

#include "Projection.h"
#include "Manipulator.h"



namespace lib_gl
{



class CameraInterface
{
public:
	virtual void SetViewport(int width, int height)
	{
		GetProjection().SetViewport( 0 , 0 , width , height );
	}

	virtual void SetViewport(int left, int right, int width, int height)
	{
		GetProjection().SetViewport( left , right , width , height );
	}

	//! 投影行列/モデルビュー行列をセットする
	virtual void SetProjAndModelview(void)
	{
		SetGLProjection();
		SetGLModelview();
	}

//! カレントビューの投影行列を設定する
	virtual void SetGLProjection(void)
	{
		GetProjection().SetGLProjection();
	}

	//! カレントビューのモデルビュー行列を設定する
	virtual void SetGLModelview(void)
	{
		GetManipulator().SetGLModelview();
	}

	virtual void SetGLViewport(void)
	{
		GetProjection().m_Viewport.SetGLViewport();
	}

protected:
	virtual Projection& GetProjection(void) = 0;
	virtual Manipulator& GetManipulator(void) = 0;
};



class BasicCamera : public CameraInterface
{
public:
	BasicCamera(void)
	{
		m_Manip.m_EyePos.set( 3.0f , 3.0f , 3.0f );
		m_Manip.SetUpAngle( lm::vec3f( 0.0f , 1.0f , 0.0f ) );

		m_Projection.SetNearFar( 0.01f , 500.0f );
	}

	//! 設定を標準値に戻す
	virtual void Reset(void)
	{
		m_Manip.m_EyePos.set( 3.0f , 3.0f , 3.0f );
		m_Manip.SetUpAngle( lm::vec3f( 0.0f , 1.0f , 0.0f ) );

		m_Projection.SetNearFar( 0.01f , 500.0f );
	}

protected:
	Projection& GetProjection(void) { return m_Projection; }
	Manipulator& GetManipulator(void) { return m_Manip; }


public:
	PersProjection     m_Projection;
	CameraManipulator  m_Manip;
};



class BasicOrthoCamera : public CameraInterface
{
public:
	BasicOrthoCamera(void)
	{
		m_Manip.m_EyePos.set( 3.0f , 3.0f , 3.0f );
		m_Manip.SetUpAngle( lm::vec3f( 0.0f , 1.0f , 0.0f ) );

		m_Projection.SetNearFar( 0.01f , 500.0f );
	}

	//! 設定を標準値に戻す
	virtual void Reset(void)
	{
		m_Manip.m_EyePos.set( 3.0f , 3.0f , 3.0f );
		m_Manip.SetUpAngle( lm::vec3f( 0.0f , 1.0f , 0.0f ) );

		m_Projection.SetNearFar( 0.01f , 500.0f );
	}

protected:
	Projection& GetProjection(void) { return m_Projection; }
	Manipulator& GetManipulator(void) { return m_Manip; }


public:
	OrthoProjection    m_Projection;
	CameraManipulator  m_Manip;
};



}
