#include <allegro.h>
#include <alleggl.h>
#include <stdio.h>
#include <GL/gl.h>

#include "geometry.h"
#include "trig.h"

CGeometry::CGeometry(void)
{
	vertices = 0;
	tvertices = 0;
	triangles = 0;
	vertex = new CVertex[vertices];
	tvertex = new CTvertex[tvertices];
	triangle = new CTriangle[triangles];
	
	calc_normals();
}

CGeometry::CGeometry(unsigned int v, unsigned int tv, unsigned int t)
{
	vertices = v;
	tvertices= tv;
	triangles = t;
	vertex = new CVertex[vertices];
	tvertex = new CTvertex[tvertices];
	triangle = new CTriangle[triangles];

	calc_normals();
}

CGeometry::CGeometry(const char* f)
{
	FILE *file;
	unsigned int i;
	float data;
		
	file = fopen(f, "r");
	fscanf(file, "%u", &vertices);
	fscanf(file, "%u", &tvertices);
	fscanf(file, "%u", &triangles);
	
	vertex = new CVertex[vertices];
	tvertex = new CTvertex[tvertices];
	triangle = new CTriangle[triangles];
	
	for(i=0; i<vertices; i++)
	{
		fscanf(file, "%f", &data);
		vertex[i].x = data;
		fscanf(file, "%f", &data);
		vertex[i].y = data;
		fscanf(file, "%f", &data);
		vertex[i].z = data;
	}
	for(i=0; i<tvertices; i++)
	{
		fscanf(file, "%f", &data);
		tvertex[i].u = data;
		fscanf(file, "%f", &data);
		tvertex[i].v = data;
		//
		//fscanf(file, "%f", &data);
		//
	}
	for(i=0; i<triangles; i++)
	{
		fscanf(file, "%u", &triangle[i].v[0]);
		fscanf(file, "%u", &triangle[i].v[1]);
		fscanf(file, "%u", &triangle[i].v[2]);
	}
	if(tvertices>0)
	        for(i=0; i<triangles; i++)
		{
		        fscanf(file, "%u", &triangle[i].tv[0]);
			fscanf(file, "%u", &triangle[i].tv[1]);
			fscanf(file, "%u", &triangle[i].tv[2]);
		}
	calc_normals();
	fclose(file);
}

CGeometry::~CGeometry(void)
{
	delete [] vertex;
	delete [] tvertex;
	delete [] triangle;
}

void CGeometry::draw(void)
{
	unsigned int i;
	//glColor3f(1, 1, 1);
	glBegin(GL_TRIANGLES);
	for(i=0; i<triangles; i++)
	{
//glNormal3f(triangle[i].normal.x, triangle[i].normal.y, triangle[i].normal.z);
		glNormal3f(vertex[triangle[i].v[0]].normal.x, vertex[triangle[i].v[0]].normal.y, vertex[triangle[i].v[0]].normal.z);
		if(tvertices>0) glTexCoord2f(tvertex[triangle[i].tv[0]].u, tvertex[triangle[i].tv[0]].v);
		glVertex3f(vertex[triangle[i].v[0]].x, vertex[triangle[i].v[0]].y, vertex[triangle[i].v[0]].z);
		glNormal3f(vertex[triangle[i].v[1]].normal.x, vertex[triangle[i].v[1]].normal.y, vertex[triangle[i].v[1]].normal.z);
		if(tvertices>0) glTexCoord2f(tvertex[triangle[i].tv[1]].u, tvertex[triangle[i].tv[1]].v);
		glVertex3f(vertex[triangle[i].v[1]].x, vertex[triangle[i].v[1]].y, vertex[triangle[i].v[1]].z);
		glNormal3f(vertex[triangle[i].v[2]].normal.x, vertex[triangle[i].v[2]].normal.y, vertex[triangle[i].v[2]].normal.z);
		if(tvertices>0) glTexCoord2f(tvertex[triangle[i].tv[2]].u, tvertex[triangle[i].tv[2]].v);
		glVertex3f(vertex[triangle[i].v[2]].x, vertex[triangle[i].v[2]].y, vertex[triangle[i].v[2]].z);
	}
	glEnd();
/*	glDisable(GL_TEXTURE_2D);
	glBegin(GL_LINES);
	for(i=0; i<vertices; i++)
	{
		glColor3f(0, 1, 0);
		glNormal3f(vertex[i].normal.x, vertex[i].normal.y, vertex[i].normal.z);
		glVertex3f(vertex[i].x, vertex[i].y, vertex[i].z);
		glVertex3f(vertex[i].x+vertex[i].normal.x, vertex[i].y+vertex[i].normal.y, vertex[i].z+vertex[i].normal.z);
	}
	glEnd();*/
}

void CGeometry::calc_normals(void)
{
	unsigned int i, j;
	CVector a, b;
	for(i=0; i<triangles; i++)
	{
		a=vertex[triangle[i].v[2]]-vertex[triangle[i].v[1]];
		b=vertex[triangle[i].v[0]]-vertex[triangle[i].v[1]];
		triangle[i].normal=(a%b).unit();
	}
	for(i=0; i<vertices; i++)
	{
		a.x=0;
		a.y=0;
		a.z=0;
		for(j=0; j<triangles; j++)
		{
			if(triangle[j].v[0]==i || triangle[j].v[1]==i || triangle[j].v[2]==i)
				a=a+triangle[j].normal;
		}
		vertex[i].normal=a.unit();		
	}
}

void CGeometry::scale(double s)
{
	int i;
	for(i=0; i<vertices; i++)
	{
		vertex[i].x*=s;
		vertex[i].y*=s;
		vertex[i].z*=s;
	}
}
