/**
 *\file		TriangleMesh.cpp
 *
 *\brief	
 *
 *\author	Xianming Chen
 *
 *\date		11 Jul 2004
 */


#include "TriangleMesh.h"
#include "xcplusplus.h"

#include <fstream>
#include <iostream>
#include <cassert>
#include <string>
#include <GL/glut.h>
#include <cfloat>


using namespace std;


TriangleMesh :: TriangleMesh(const string obj_fname) : texture(0)
{
  ifstream is(obj_fname.c_str());

  if(is)
  {
    bool no_normal = true;
    bool no_tex = true;

    float 
      minx = FLT_MAX, maxx = FLT_MIN,
      miny = FLT_MAX, maxy = FLT_MIN,
      minz = FLT_MAX, maxz = FLT_MIN;
    
    while( skip_comment_lines(is, '#') ) 
    {
      string ele_id;
      float x, y, z;    

      if( ! (is >> ele_id) ) break;

      if(ele_id == "v")
      {
	is >> x >> y >> z;
	V.push_back( Point(x, y, z) );

	if(x < minx) minx = x;
	else if(x > maxx) maxx = x;

	if(y < miny) miny = y;
	else if(y > maxy) maxy = y;

	if(z < minz) minz = z;
	else if(z > maxz) maxz = z;
      }
      else if(ele_id == "vt")
      {
	no_tex = false;
	is >> x >> y >> z;
	is.clear();                           // is z(i.e. w) is not available, have to clear error flag.
	T.push_back( RGB(x, y, z) );
      }
      else if(ele_id == "vn")
      {
	no_normal = false;
	is >> x >> y >> z;
	if(! is.good())                      // in case it is -1#IND00
	{
	  x = y = z = 0.0;
	  is.clear();
	  skip_line(is);
	}
	N.push_back( Vector(x, y, z) );
      }
      else if(ele_id == "f")
      {
	int vi[10];                               // vertex indices.
	int ni[10] = { -1, -1, -1, -1, };         // normal indices.
	int ti[10] = { -1, -1, -1, -1, };         // tex indices.
	int i = 0;
	for(char c; i<10; ++i)
	{
	  if(no_tex && no_normal) is >> vi[i];
	  else if(no_tex)         is >> vi[i] >> c >> c >> ni[i];
	  else if(no_normal)      is >> vi[i] >> c >> ti[i];
	  else                    is >> vi[i] >> c >> ti[i] >> c >>  ni[i];

	  if( ! is.good() )	    break;
	}
	for(int k=0; k<=i-3; k++)
	{
	  F.push_back( TriangleFace(vi[0]-1, vi[k+1]-1, vi[k+2]-1, ti[0]-1, ti[k+1]-1, ti[k+2]-1, ni[0]-1, ni[k+1]-1, ni[k+2]-1) );
	}
	is.clear();
      }
      else 
	skip_line(is);
    }
    is.close();

    Point 
      min(minx, miny, minz),
      max(maxx, maxy, maxz),
      center( (min + max) / 2 );

    for(vector<Point> :: iterator itr = V.begin(); itr != V.end(); ++itr)
    {
      *itr -= center;
    }

    has_normal = N.size();
    has_texture = T.size();
    total_triangles = F.size();

    cout << "total vertices " << V.size() << endl;
    cout << "total normals " << N.size() << endl;
    cout << "total texture coordinates " << T.size() << endl;
    cout << "total triangles " << F.size() << endl;
    cout << "min pnt is " << min << endl;
    cout << "max pnt is " << max << endl;
  }
  else 
    cerr << "Can't open input file " << obj_fname << endl;
}
  


