#include "loadOBJ.h"

bool loadOBJ(const char* path, std::vector <glm::vec3>& out_vertices, std::vector <glm::vec2>& out_uvs, std::vector <glm::vec3>& out_normals){

	std::vector <unsigned int> vertexIndices, uvIndices, normalIndices;
	std::vector <glm::vec3> temp_vertices;
	std::vector <glm::vec2> temp_uvs;
	std::vector <glm::vec3> temp_normals;

	printf("(loadOBJ.cpp) Ladowanie pliku ze sciezki: %s...\n", path);

	FILE* file = fopen(path, "r");
	if (file == NULL) {
		printf("(loadOBJ.cpp) Nie udalo sie odtworzyc pliku. Czy na pewno jest on we wskazanym katalogu?\n");
		return false;
	}

	unsigned int line = 0;
	unsigned int vs = 0;
	unsigned int vts = 0;
	unsigned int vns = 0;
	unsigned int fs = 0;
	char lineHeader[128];

	while (1) {

		// read the first word of the line
		int res = fscanf(file, "%s", lineHeader);
		if (res == EOF) break; // EOF = End Of File. Quit the loop.

		// else: parse lineHeader
		if (strcmp(lineHeader, "v") == 0) {

			glm::vec3 vertex;
			fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
			temp_vertices.push_back(vertex);
			vs++;

		} else if (strcmp(lineHeader, "vt") == 0) {

			glm::vec2 uv;
			fscanf(file, "%f %f\n", &uv.x, &uv.y);
			temp_uvs.push_back(uv);
			vts++;

		} else if (strcmp(lineHeader, "vn") == 0) {

			glm::vec3 normal;
			fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
			temp_normals.push_back(normal);
			vns++;

		} else if (strcmp(lineHeader, "f") == 0) {

			unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
			int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]);
			fs++;

			if (matches != 9){
				printf("File can't be read by our simple parser. Try exporting with other options (%d matches on line %d)\n", matches, line);
				return false;
			}

			vertexIndices.push_back(vertexIndex[0]);
			vertexIndices.push_back(vertexIndex[1]);
			vertexIndices.push_back(vertexIndex[2]);
			uvIndices    .push_back(uvIndex[0]);
			uvIndices    .push_back(uvIndex[1]);
			uvIndices    .push_back(uvIndex[2]);
			normalIndices.push_back(normalIndex[0]);
			normalIndices.push_back(normalIndex[1]);
			normalIndices.push_back(normalIndex[2]);
		}

		line++;
	}

	// For each vertex of each triangle
	for (unsigned int i = 0; i < vertexIndices.size(); i++) {
		unsigned int vertexIndex = vertexIndices[i];
		unsigned int uvIndex = uvIndices[i];
		unsigned int normalIndex = normalIndices[i];

		glm::vec3 vertex1 = temp_vertices[vertexIndex - 1];
		glm::vec2 vertex2 = temp_uvs[uvIndex - 1];
		glm::vec3 vertex3 = temp_normals[normalIndex - 1];

		out_vertices.push_back(vertex1);
		out_uvs.push_back(vertex2);
		out_normals.push_back(vertex3);
	}

	fclose(file);

	printf("(loadOBJ.cpp) Loaded file with %d v, %d vt, %d vn, %d f. %d lines total.\n", vs, vts, vns, fs, line);

	return true;
}