#include "stdafx.h"

#include "Scene.hxx"
#include "EyeLightShader.hxx"

//////////////////////////////////////////////////////////////////////////
//TASK: Extend scene.cxx to handle normals and texture coordinates
//////////////////////////////////////////////////////////////////////////

Vec3f vec3fFromStream(std::istream &aStream)
{
	float x, y, z;
	aStream >> x >> y >> z;
	return Vec3f(x, y, z);
}

struct FaceIdcs 
{
	int v[3];
	int t[3];
	int n[3];

	FaceIdcs()
	{
		memset(this, -1, sizeof(*this));
	}

	FaceIdcs(std::istream &aStream)
	{ 
		memset(this, -1, sizeof(*this));
		char c;

		for(int i = 0; i < 3; i++)
		{
			aStream >> v[i] >> c;

			t[i] = 0;
			aStream >> t[i] >> c;

			n[i] = 0;
			aStream >> n[i] >> std::ws;
		}

		std::string s;
		aStream >> s >> std::ws; //Read any other crap...
	}
};


void Scene::ParseOBJ(char *fileName, PrimitiveFactory *aFactory)
{
	cout << "Parsing OBJFile : " << fileName << endl;

	std::ifstream ifile(fileName);

	std::vector<FaceIdcs> faces;
	std::vector<Vec3f>    vert;
	std::vector<Vec3f>    vertn;
	std::vector<Vec3f>    vertt;

	while(!ifile.eof())
	{
		std::string curLine;
		std::getline(ifile, curLine);

		std::istringstream issLine(curLine);
		std::string lineType;
		issLine >> std::ws >> lineType;

		if(lineType == "v")
			vert.push_back(vec3fFromStream(issLine));
		else if (lineType == "f")
			faces.push_back(issLine);
		else if (lineType == "vn")
			vertn.push_back(vec3fFromStream(issLine));
		else if (lineType == "vt")
			vertt.push_back(vec3fFromStream(issLine));
	}

	for(std::vector<FaceIdcs>::iterator itFace = faces.begin(); itFace != faces.end(); itFace++)
	{
		Vec3f v[3], vn[3], vt[3];
		for(int i = 0; i < 3; i++)
		{
			v[i]  = vert[itFace->v[i] - 1];

			if (itFace->n[i] != 0)
				vn[i] = vertn[itFace->n[i] - 1];

			if (itFace->t[i] != 0)
				vt[i] = vertt[itFace->t[i] - 1];
		}

		primitive.push_back(aFactory->createPrimitive(
			v[0], v[1], v[2], vn[0], vn[1], vn[2], vt[0], vt[1], vt[2]
		));
	}

	cout << "Number of Vertices: "  << vert.size()      << endl;
	cout << "Number of Triangles: " << primitive.size() << endl;

	cout << "Finished Parsing" << endl;
}
