#include "stdafx.h"
#include "ObjLoader.h"

#include <LibQtGeoViewerCore/SceneMain.h>

#include "../FileUtil.h"

#include <LibGeo/Mesh/OBJ/ObjMesh.h>

#include <QFileInfo>

#include <LibTest/DbgTimer.h>



bool ObjLoader::Load(SceneMain& scene, const std::string& filename)
{
	lib_geo::ObjMesh obj_mesh;
	if (!obj_mesh.Load(filename))
		return false;

	bool split_obj = false;
	bool split_group = false;
	std::vector<lib_geo::BaseMesh> mesh_ary;
	if (scene.m_IOConfig.ObjSplit)
	{
		if (!obj_mesh.m_Objects.empty())
		{
			split_obj = true;
			obj_mesh.ConvertToBaseMeshEachObject(mesh_ary);

			if (mesh_ary.empty())
				return true;
		}
		else if (!obj_mesh.m_Groups.empty())
		{
			split_group = true;
			obj_mesh.ConvertToBaseMeshEachGroup(mesh_ary);

			if (mesh_ary.empty())
				return true;
		}
	}

	GeomObject* geom = scene.CreateNewGeometry();

	if (!mesh_ary.empty())
	{
		for (size_t i = 0; i < mesh_ary.size(); ++i)
		{
			MeshBuf* mbuf = geom->CreateNewMeshBuf();

			mbuf->m_Mesh.CopySwap(mesh_ary[i]);

			OnPostLoadObj(scene, *mbuf, obj_mesh);

			std::string object_name;
			if (split_obj)
				object_name = obj_mesh.m_Objects[i].m_Name;
			else if (split_group)
				object_name = obj_mesh.m_Groups[i].m_Name;

			if (object_name.empty())
				mbuf->m_Name = FileUtil::GetFileTitle(filename);
			else
				mbuf->m_Name = object_name;
		}
	}
	else
	{
		MeshBuf* mbuf = geom->CreateNewMeshBuf();

		obj_mesh.ConvertToBaseMesh(mbuf->m_Mesh);

		OnPostLoadObj(scene, *mbuf, obj_mesh);
	}

	scene.RefreshObjectIndex();

	geom->m_Name       = FileUtil::GetFileTitle(filename);
	geom->m_FileFormat = GeomFileFormat::Obj;
	geom->m_FilePath   = filename;

	geom->InitializeBufferCommon();

	scene.UpdateTransform();

	scene.ReportDoneEditGeometry();

	return true;
}

void ObjLoader::OnPostLoadObj(SceneMain& scene, geom::MeshBuf& mbuf, const lib_geo::ObjMesh& obj_mesh)
{
	lib_geo::BaseMesh& mesh_dst = mbuf.m_Mesh;

	if (!mesh_dst.HasNormal())
	{
		mesh_dst.CreateNormalsEachVerts();
		mesh_dst.UpdateNormal();
	}

	InitTextureFromObjMeshBuf(scene, mbuf, obj_mesh);
}

void ObjLoader::InitTextureFromObjMeshBuf(SceneMain& scene, geom::MeshBuf& mbuf, const lib_geo::ObjMesh& obj_mesh)
{
	// テクスチャの設定
	if (obj_mesh.m_MaterialGroups.empty())
		return;

	// 複数 material group には未対応
	const lib_geo::ObjMaterialGroup& mat_grp = obj_mesh.m_MaterialGroups[0];

	mbuf.CreateTextureBuf(mat_grp.m_Materials.size());
	for (size_t i = 0; i < mat_grp.m_Materials.size() ; ++i)
	{
		const lib_geo::ObjMaterial& mat_source = mat_grp.m_Materials[i];

		const std::string tex_col = mat_source.GetTextureFilePath();
		const std::string name_col = GetTextureNameFromFilePath(tex_col);
		mbuf.InitColorTexture(i, tex_col, name_col, scene.m_TexConfig);

		const std::string tex_n = mat_source.GetNormalMapFilePath();
		const std::string name_norm = GetTextureNameFromFilePath(tex_n);
		mbuf.InitNormalTexture(i, tex_n, name_norm, scene.m_TexConfig);
	}
}

std::string ObjLoader::GetTextureNameFromFilePath(const std::string& filepath) const
{
	QString path_qs = QString::fromLocal8Bit(filepath.c_str());
	QString name_qs = QFileInfo(path_qs).fileName();
	return name_qs.toLocal8Bit().data();
}
