#pragma once

#include "Mqo.h"


namespace lib_geo
{


class GlMqoDrawer
{
public:
	void DrawObjects ( const MqoObjects& i_mqo_objects );
	void DrawObject  ( const MqoObject& i_mqo );
	void DrawMqoMesh ( const MqoMesh& i_mesh );
	void DrawMqoFace ( const MqoMesh& i_mesh , const MqoFace& i_face );

	void GlActivateMqoMaterial( const MqoMaterial& i_material );
};


inline
void GlMqoDrawer::DrawObjects( const MqoObjects& i_mqo_objects )
{
	for( size_t i = 0 ; i < i_mqo_objects.size() ; ++i )
		DrawObject( i_mqo_objects[i] );
}

inline
void GlMqoDrawer::DrawObject( const MqoObject& i_mqo )
{
	for( size_t i = 0 ; i < i_mqo.m_Meshs.size() ; ++i )
	{
		const MqoMesh& m = i_mqo.m_Meshs[i];

		// 手抜きマテリアル設定. 1メッシュ==1マテリアルの場合限定
		if( m.m_Faces.empty() == false )
		{
			int mat_idx = m.m_Faces.front().m_MaterialIdx;
			if( 0 <= mat_idx && mat_idx < (int)i_mqo.m_Materials.size() )
			{
				GlActivateMqoMaterial( i_mqo.m_Materials[mat_idx] );
			}
		}

		DrawMqoMesh( i_mqo.m_Meshs[i] );
	}
}

inline
void GlMqoDrawer::DrawMqoMesh( const MqoMesh& i_mesh )
{
	for( size_t i = 0 ; i < i_mesh.m_Faces.size() ; ++i )
	{
		DrawMqoFace( i_mesh , i_mesh.m_Faces[i] );
	}
}

inline
void GlMqoDrawer::DrawMqoFace( const MqoMesh& i_mesh , const MqoFace& i_face )
{
	glBegin(GL_POLYGON);
	for( size_t i = 0 ; i < i_face.NumVertices() ; ++i )
	{
		const MqoVector& v  = i_mesh.m_Vertices[ i_face.m_VertexIdx[i] ];
		const MqoVector& n  = i_mesh.m_Normals[ i_face.m_VertexIdx[i] ];
		const MqoUV&     uv = i_face.m_UV[i];

		glTexCoord2f( uv.x , uv.y );
		glNormal3f( n.x , n.y , n.z );
		glVertex3f( v.x , v.y , v.z );
	}
	glEnd();
}

inline
void GlMqoDrawer::GlActivateMqoMaterial( const MqoMaterial& i_material )
{
	// メタセコイアの反射モデルが不明なので、間違えている可能性あり. 

	lib_cg::color4f mat_emission = i_material.m_BaseColor;
	mat_emission *= i_material.m_Emission;
	mat_emission.a() = i_material.m_BaseColor.a();

	lib_cg::color4f mat_ambient( 1.0f , 1.0f , 1.0f , 1.0f );
	mat_ambient *= i_material.m_Ambient;
	mat_ambient.a() = i_material.m_BaseColor.a();

	lib_cg::color4f mat_diffuse = i_material.m_BaseColor;
	mat_diffuse *= i_material.m_Diffuse;
	mat_diffuse.a() = i_material.m_BaseColor.a();

	lib_cg::color4f mat_specular( 1.0f , 1.0f , 1.0f , 1.0f );
	mat_specular *= i_material.m_Specular;
	mat_specular.a() = i_material.m_BaseColor.a();

	glMaterialfv( GL_FRONT_AND_BACK , GL_EMISSION  , mat_emission.v() );
	glMaterialfv( GL_FRONT_AND_BACK , GL_AMBIENT   , mat_ambient.v()  );
	glMaterialfv( GL_FRONT_AND_BACK , GL_DIFFUSE   , mat_diffuse.v()  );
	glMaterialfv( GL_FRONT_AND_BACK , GL_SPECULAR  , mat_specular.v() );
	glMaterialfv( GL_FRONT_AND_BACK , GL_SHININESS , &i_material.m_Shininess );
}


}
