#include <iostream>
#include <fstream>
using namespace std;

#include <point.h>
#include <d4tess.h>

#include <aclock.h>

#include <d4meshpointreader.h>

typedef unsigned int uint;


d4meshpointreader::d4meshpointreader
(
  bool & res,
  d4tess & _tess, 
  string const & filename
)
  : tess(_tess)
{
  res=false;

  uint columns(0);
  if (isfilegood(columns,filename)==false)
    return;

  ifstream targ(filename.c_str());

  tess.reset();

  if (columns==4)
    readfourcolumns(targ);

  if (columns==3)
    readthreecolumns(targ);

  res=true;
}


d4meshpointreader::d4meshpointreader
(
  bool & res,
  d4tess & _tess, 
  vector< pt4 > const & vbox,
  string const & filename
)
  : tess(_tess)
{
  res=false;

  uint columns(0);
  if (isfilegood(columns,filename)==false)
    return;

  ifstream targ(filename.c_str());

  tess.reset();

  for (uint i=0; i<vbox.size(); ++i)
    tess.pt.push_back(vbox[i]);

  if (columns==4)
    readfourcolumns(targ);

  if (columns==3)
    readthreecolumns(targ);

  res=true;
}

void d4meshpointreader::eval()
{
  tess.initialize();

  uint sz=tess.pt.size();
  for (uint i=5; i<sz; ++i)
  {
//cout << "Inserting point " << i << endl;
    tess.addpoint(i);
  }
}


void d4meshpointreader::eval(ostream & os)
{
  aclock c;
  c.measure();
  eval();
  c.measure();

  os << tess.pt.size()-1 << " " << c.diff_s() << endl;
}


bool const d4meshpointreader::isfilegood
(
  uint & columns,
  string const & filename
) const
{
  ifstream targ(filename.c_str());

  if (targ.good()==false)
  {
    cout << "error:  targ.good() failed" << endl;
    cout << "        can not open file: " << filename << endl;

    return false;
  }

  if (targ.eof()==true)
  {
    cout << "error:  empty file: " << filename << endl;
    return false;
  }
    
  string s;
  getline(targ,s);

  uint sz=s.size();
  if (sz<=1)
  {
    cout << "error:  can not read first line of file: " << filename << endl;
    return false;
  }

  char const space(' ');

  // Iterate along the string.  The current position is either pointing to
  //   an element that is a space or not.  This is used to count the number
  //   of arguments or columns in the line.
  bool statespace=true;
   
  uint counter(0);

  if (s[0]!=space)
  {
    statespace=false;
    counter=1;
  }
   
  for (uint i=1; i<sz; ++i)
  {
    if (statespace)
    {
      if (s[i]!=space)
      {
        statespace=false;
        ++counter;
      }

      continue;
    }

    if (s[i]==space)
      statespace=true;
  }

  columns=counter;

  return true;
}


void d4meshpointreader::readthreecolumns(ifstream & targ)
{
  pt4 x;

  for ( ; targ.eof()==false; )
  {
    targ >> x.x;
    if (targ.eof()==true)
      continue;
    targ >> x.y;
    if (targ.eof()==true)
      continue;
    targ >> x.z;

    tess.pt.push_back(x);
  }

}

void d4meshpointreader::readfourcolumns(ifstream & targ)
{
  pt4 x;

  for ( ; targ.eof()==false; )
  {
    targ >> x.x;
    if (targ.eof()==true)
      continue;
    targ >> x.y;
    if (targ.eof()==true)
      continue;
    targ >> x.z;
    if (targ.eof()==true)
      continue;
    targ >> x.a;

    tess.pt.push_back(x);
  }

}



