#include "OBJmodel.h"

void initModel(ObjReader<ModelGroupStorage> &reader, ModelGroupStorage &model_storage)
{
	do
	{
		model_storage.finish_group();
		model_storage.newGroup();
	}
	while (reader.readNextGroup(model_storage));
}


void readObjModel(const string &path, ModelGroupStorage& dstObjData)
{
	ObjReader<ModelGroupStorage> reader(path);
	initModel(reader,dstObjData);
}

void constructVboArrays(ModelGroupStorage& srcObjData, vcoord_buffer &dst_vcoord_buffer,tcoord_buffer& dst_tcoord_buffer, ncoord_buffer& dst_ncoord_buffer, funion_coord_buffer&  dst_union_face_buffer )
{
	convertCoordsToUnionIndices( srcObjData.getFVcoordBuffer(), srcObjData.getVcoordBuffer(), 
	srcObjData.getFNcoordBuffer(),  srcObjData.getNcoordBuffer(), 
	srcObjData.getFTcoordBuffer(),  srcObjData.getTcoordBuffer(),
	dst_vcoord_buffer,dst_ncoord_buffer, dst_tcoord_buffer, dst_union_face_buffer);
}

void constructTriangleFacesArray(vector<Group>& srcGroups, funion_coord_buffer&  srcPolygonFacesArray, funion_coord_buffer&  dstTriangleFacesArray, vector<Range>& dstMeshesRange )
{
	Range range;

	range.from=0;
	range.to=0;
 	for (int i=0; i<srcGroups.size(); ++i)
	{
		range.from=range.to;
			convertPolygonsToTriangles(srcPolygonFacesArray, srcGroups[i].group_info.from_fv_coord_index,srcGroups[i].group_info.to_fv_coord_index,dstTriangleFacesArray);
		range.to=dstTriangleFacesArray.size();

		dstMeshesRange.push_back(range);
	}
}

void uploadToGPU(const string &vbo_name, VBOmanager& vbo_manager,  vcoord_buffer &src_vcoord_buffer, vector<tcoord_buffer> &src_tcoord_multi_buffer, ncoord_buffer& src_ncoord_buffer, funion_coord_buffer &src_face_array, VBOids &dst_vbo_id) 
{
	vector<int> face_array;
	convertIndicesToArray1D(src_face_array, face_array);

	vbo_manager.createNewVBO(vbo_name, src_vcoord_buffer, src_ncoord_buffer, src_tcoord_multi_buffer, face_array);

	bool vboFound = vbo_manager.getVBOdata(vbo_name, dst_vbo_id);
	
	if (! vboFound )
	{
		throw exception( (string("Vbo with name: ") + vbo_name + string(" was not found")).c_str() );
	}
}

void constructMeshes( vector<Range>& meshes_range, vector<MeshObject> &dst_meshes)
{
	for (int i=0; i<meshes_range.size(); ++i)
	{
		MeshObject mesh;

		//indexy do VBO buffery na geometry zatim nenastavim
		mesh.vbo_data.fcoord_id=0;
		mesh.vbo_data.vcoord_id=0;
		mesh.vbo_data.ncoord_id=0;
		mesh.vbo_data.tcoord_id.clear();

		mesh.vbo_data.from_index=meshes_range[i].from;
		mesh.vbo_data.to_index=meshes_range[i].to;
	
		dst_meshes.push_back(mesh);
	}
}


void appendGeometryToMeshes(vector<Group>& groups,VBOids& vboID, vector<MeshObject> &src_dst_meshes)
{
	for (int i=0; i<groups.size(); ++i)
	{
		src_dst_meshes[i].vbo_data.fcoord_id=vboID.fcoord_id;
		src_dst_meshes[i].vbo_data.ncoord_id=vboID.ncoord_id;
		src_dst_meshes[i].vbo_data.tcoord_id=vboID.tcoord_id;
		src_dst_meshes[i].vbo_data.vcoord_id=vboID.vcoord_id;
	}
}

void appendTexturesToMeshes(vector<Group>& groups, TextureManager& textures, const string& texturesPrefix, vector<MeshObject> &src_dst_meshes)
{
	for (int i=0; i<groups.size(); ++i)
	{
		GL_ID texID=0;

		if (!groups[i].material_name.empty())
		{
			texID=textures.getTexture( texturesPrefix+groups[i].material_name); //podle nazvu materialu dohledam texturu (je ulozena pod stejnym nazvem jako vlastni material + prefix)
		}

		if (texID!=0)
		{
			src_dst_meshes[i].textures.push_back(texID);
		}
	}
}
