/***************************************************************************
 *   Copyright (C) 2004 by Armando Navarro                                 *
 *   qoajnv@usc.es                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "gaussianparser.h"
#include "aimparser.h"
#include "tokenizer.h"
#include "molecule.h"

#include <vector>
#include <iostream>
#include <cmath>

GaussianParser::GaussianParser ( const char* file ) : QuantumParser ( file )
{}

GaussianParser::GaussianParser ( std::istream* stream ) : QuantumParser ( stream )
{}

GaussianParser::~GaussianParser()
{}

bool GaussianParser::ParseFile ( std::streampos pos )
{

  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  m_level=GetLevel();
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );

  GetGeometry();
  return true;
}


bool GaussianParser::ParseFrequencies ( std::streampos pos )
{
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  if ( !GetFrequencies() ) return false;
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  //Ok lets get the vectors;
  scounter=0;
  std::string line;
  CMolecule& molecule=m_molecule->back();
  molecule.AllocateVectors();
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer token ( line," " );
    if ( token.size() >=2 )
      if ( token.at ( 1 ) =="AN" )
      {
        std::cout << "about to get vectors" << std::endl;
        GetVectors();
      }
  }

  if ( !ParseArquive ( pos ) ) std::cerr << "No arquive entry found for frequency computation" << std::endl;
  return true;

}

bool GaussianParser::ParseNMR ( std::streampos pos )
{
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  CMolecule& molecule=m_molecule->back();
  std::string line;
  std::vector<CAtom>::iterator it=molecule.m_atom.begin();
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "Isotropic =" ) != std::string::npos )
    {
      StringTokenizer token ( line," \t" );
      //std::cout << "cshift is " << token.at(4) << std::endl;
      it++->SetCShift ( atof ( token.at ( 4 ).c_str() ) );

    }
    if ( line.find ( "Total nuclear spin-spin coupling J (Hz):" ) != std::string::npos )
    {
      GetCouplingConstants();
    }
  }
  return true;
}

void  GaussianParser::GetCouplingConstants()
{
  std::string line;
  std::vector < CMolecule::Coupling >& coups=m_molecule->back().GetCouplings();
  size_t nindex=0;
  size_t index1=0;
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "End of Minotr" ) != std::string::npos ) return;
    if ( line.at ( 6 ) != ' ' )
    {
      StringTokenizer tok ( line," \t\r" );
      size_t index=atoi ( tok.front().c_str() )-1;
      StringTokenizer::iterator tt=tok.begin() +1;
      index1=0;
      for ( tt=tok.begin() +1;tt!=tok.end();++tt,++index1 )
      {
        StringTokenizer mant ( *tt,"D" );
        std::cout << "(" << index << "," << nindex+index1 << ")=" << atof ( tt->c_str() ) << std::endl;
        coups.push_back ( CMolecule::Coupling ( index,nindex+index1,atof ( mant.front().c_str() ) *pow ( 10,atoi ( mant.back().c_str() ) ) ) );
      }
    }
    else
    {
      nindex+=index1;
    }
  }
}
bool GaussianParser::ParseArquive ( std::streampos pos )
{

  std::string archive;
  std::string line;
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  std::streampos arpos;
  CMolecule& molecule=m_molecule->back();
  while ( std::getline ( *m_file,line ) )
  {
    if ( ( line.find ( "1\\1\\" ) != std::string::npos ) || ( line.find ( "1|1|" ) !=  std::string::npos ) ) break;
    arpos=m_file->tellg();
  }
  //windows
  m_file->seekg ( arpos,std::ios::beg );

  while ( std::getline ( *m_file,line ) )
  {
    std::cout << line << std::endl;
    archive+=line;
  }
  //OK lets clear bakspaces
  std::string::size_type sit=0;
  while ( sit != std::string::npos )
  {
    sit=archive.find_first_of ( " \n\t\r",sit );
    if ( sit != std::string::npos )
      archive.erase ( sit,1 );
  }



  TokByString t ( archive,"\\\\" );

  if ( t.size() < 4 )
    t=TokByString ( archive,"||" );

  std::string& geometry= t.at ( 3 );
  TokByString::iterator tit;

  if ( t.size() < 4 ) return false;

  StringTokenizer g1 ( geometry,"\\|" );

  std::vector<coordinate> & iorient= molecule.InputOrientation();
  iorient.resize ( molecule.Atoms().size() );

  size_t i=0;
  StringTokenizer::iterator it=g1.begin();
  it++;
  for ( i=0;it!=g1.end();it++,i++ )
  {
    StringTokenizer g2 ( *it,"," );
    std::cerr << *it << std::endl;
//    molecule.m_atom[i].label=i+1;
    StringTokenizer::reverse_iterator it2=g2.rbegin();
    iorient[i].z= atof ( ( it2++ )->c_str() );
    iorient[i].y= atof ( ( it2++ )->c_str() );
    iorient[i].x= atof ( it2->c_str() );
  }

  //Get the forces
  //OK I have to had three more blocks to get forces and hessian, first
  // I can skip, second is hessian and third are forces
  if ( t.size() < 7 )
  {

    return false;
  }

  molecule.AllocateForces();
  molecule.AllocateHessian();

  //Lets get forces in seventh block
  IMArray<double>& forces=molecule.GetForces();
  g1=StringTokenizer ( t.at ( 6 ),"," );
  for ( it=g1.begin(),i=0;it!=g1.end();it++,i++ )
  {
    forces ( i ) =atof ( it->c_str() );
  }


  IBArray<double>& hessian=molecule.GetHessian();

  std::string kk=t.at ( 5 );
  StringTokenizer g2 ( t.at ( 5 ) );
  it=g2.begin();



  size_t j;
  for ( i=0;i< 3*molecule.m_atom.size();i++ )
  {
    for ( j=0;j <= i ;it++,j++ )
    {
      hessian ( i,j ) =atof ( it->c_str() );
      if ( i!=j ) hessian ( j,i ) =hessian ( i,j );
      //std::cerr << "d[" << i << "," << j << "]=" << hessian(i,j) << "," << hessian(j,i) << std::endl;
    }
  }

  return true;
}

bool GaussianParser::ParseUV ( std::streampos pos )
{
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  std::string line;
  CMolecule& molecule=m_molecule->back();
  std::vector<spectralline>& lines=molecule.GetSpectralLines();
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer token ( line," =\t" );
    size_t size=token.size();
    if ( size > 2 )
    {
      if ( token.at ( 0 ) =="Excited" && token.at ( 1 ) == "State" )
      {
        spectralline line;
        line.x=atof ( token.at ( size-4 ).c_str() );
        std::cout << token.at ( size-1 ).c_str() << std::endl;
        line.y0=atof ( token.at ( size-1 ).c_str() ); //oscillator strength
        lines.push_back ( line );
      }
    }

  }
  //Get Now Rotatory Strengths
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );

  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer token ( line );
    size_t size=token.size();
    if ( size == 5 )
    {
      if ( token.at ( size-1 ) =="R(length)" )
      {
        std::vector<spectralline>::iterator it;
        for ( it=lines.begin();it!=lines.end();it++ )
        {
          std::getline ( *m_file,line );
          StringTokenizer token ( line );
          std::cout << line << std::endl;
          it->y1=atof ( token.at ( size-1 ).c_str() );
          std::cout << "R length=" << it->y1 << std::endl;

        }
      }
    }
  }

  std::vector<spectralline>::iterator it;
  for ( it=lines.begin();it!=lines.end();it++ )
  {
    std::cout << "line" << " " << it->x << " " << it->y0 << " " << it->y1 << std::endl;

  }
  return true;
}

bool GaussianParser::GetGeometry()
{
  std::string line;
  std::vector<std::streampos> pos;
  bool bfound=false;
  //we should have now the header skip one line
  std::getline ( *m_file,line );
  std::streampos initpos=m_file->tellg();
  bool bscan=false;
  while ( std::getline ( *m_file,line ) )
  {
    if ( !bscan )
      if ( ( line.find ( "Scan                            !" ) != std::string::npos ) //gaussian03
              || ( line.find ( "Scan                         !" ) != std::string::npos ) ) bscan=true; //gaussian98

    if ( line.find ( "Stationary point found" ) != std::string::npos && !bscan ) break;
    StringTokenizer token ( line );
    if ( token.size() )
    {
      if ( line.find ( "Standard orientation:" ) != std::string::npos )
      {
        bfound=true;

        // pos=m_file.tellg();
        for ( int i=0;i<3;i++ )
        {
          std::getline ( *m_file,line );

        }

        pos.push_back ( m_file->tellg() );
        //pos=m_file.tellg();
        // goto lb1;
      }

    }
    if ( line.find ( '#',0 ) == 1 ) std::cout << "breaking" << std::endl;
    if ( line.find ( '#',0 ) == 1 ) break; //split different jobs

  }
  //Kein Standard Orientation, try input
  if ( pos.empty() )
  {
    m_file->clear();
    m_file->seekg ( initpos,std::ios::beg );
    while ( std::getline ( *m_file,line ) )
    {
      if ( line.find ( "Input orientation:" ) != std::string::npos )
      {
        bfound=true;

        // pos=m_file.tellg();
        for ( int i=0;i<3;i++ )
        {
          std::getline ( *m_file,line );

        }

        pos.push_back ( m_file->tellg() );
        //pos=m_file.tellg();
        // goto lb1;
      }
      if ( line.find ( '#',0 ) == 1 ) break; //split different jobs
    }

  }
  if ( pos.empty() ) return false;

  std::vector<std::streampos>::iterator pt;
  bool bthreshold=false;
  Threshold threshold;
  bool lastpoint=false;
  std::cout << "pos= " << pos.size() << std::endl;
  for ( pt=pos.begin();pt!=pos.end();pt++ )
  {
    m_file->clear();
    m_file->seekg ( *pt,std::ios::beg );
    CMolecule molecule;
    std::getline ( *m_file,line ); //skip one line
    while ( std::getline ( *m_file,line ) )
    {
      StringTokenizer token ( line," " );
      size_t size=token.size();

      if ( size >= 5 )
      {
        CAtom atom;
//        atom.label=token.at(0);
        atom.name=CMolecule::GetAtomName ( atoi ( token.at ( 1 ).c_str() ) );
        atom.c.x=std::atof ( token.at ( size-3 ).c_str() );
        atom.c.y=std::atof ( token.at ( size-2 ).c_str() );
        atom.c.z=std::atof ( token.at ( size-1 ).c_str() );
        molecule.m_atom.push_back ( atom );
      }

      else
        break;
    }

    bool bbreak=false;
    while ( std::getline ( *m_file,line ) )
    {
      if ( line.find ( "Stationary point found" ) != std::string::npos ) break;
      StringTokenizer token ( line," \t," );
      if ( token.size() >= 4 )
      {
        switch ( m_level )
        {
          case Quantum::MNDO:
            std::cout << "MNDO" << std::endl;
            if ( line.find ( "Energy=" ) != std::string::npos )
            {
              std::cout << "E=" << token.at ( 1 ) << std::endl;
              molecule.SetEnergy ( strtools::atof ( token.at ( 1 ) ),"SCF" );
            }
            break;
          case Quantum::MP2:
            if ( token.size() >= 5 )
              if ( token.at ( 3 ).find ( "MP2" ) != std::string::npos )
                molecule.SetEnergy ( strtools::atof ( token.at ( 5 ) ),"MP2" );
            break;
          case Quantum::QCISD:

            if ( token[2]=="E(CORR)=" )
            {
              molecule.SetEnergy ( strtools::atof ( token.at ( 3 ) ),"QCISD" );
            }
            break;
          case Quantum::SCRF:
            if ( line.find ( "with all non electrostatic terms" ) != std::string::npos )
              molecule.SetEnergy ( strtools::atof ( token.back() ),"SCRF" );
            if ( line.find ( "Total energy (include solvent energy)" ) != std::string::npos )
              molecule.SetEnergy ( strtools::atof ( token.back() ),"SCRF" );
            break;
          case Quantum::HF:
          default:
            if ( token.size() >= 5 )
              if ( token.at ( 0 ) =="SCF" && token.at ( 1 ) =="Done:" )
              {
                molecule.SetEnergy ( atof ( token.at ( 4 ).c_str() ),"SCF" );

              }
            break;
        }

        if ( line.find ( "before annihilation" ) !=std::string::npos )
        {
          molecule.SetS2 ( atof ( token.at ( 3 ).c_str() ) );

        }
        if ( line.find ( "Forces (Hartrees/Bohr)" ) !=std::string::npos ) GetForces ( molecule );

        if ( token.at ( 0 ) =="Maximum" && token.at ( 1 ) =="Force" )
        {
          molecule.SetMaximumForce ( atof ( token.at ( 2 ).c_str() ) );
          if ( !bthreshold )
            threshold.maxforce=atof ( token.at ( 3 ).c_str() );

        }

        if ( token.at ( 0 ) =="RMS" && token.at ( 1 ) =="Force" )
        {
          molecule.SetRMSForce ( atof ( token.at ( 2 ).c_str() ) );
          if ( !bthreshold )
            threshold.rmsforce=atof ( token.at ( 3 ).c_str() );
        }

        if ( token.at ( 0 ) =="Maximum" && token.at ( 1 ) =="Displacement" )
        {
          molecule.SetMaximumDisplacement ( atof ( token.at ( 2 ).c_str() ) );
          if ( !bthreshold )
            threshold.maxdisplacement=atof ( token.at ( 3 ).c_str() );

        }


        if ( token.at ( 0 ) =="RMS" && token.at ( 1 ) =="Displacement" )
        {
          molecule.SetRMSDisplacement ( atof ( token.at ( 2 ).c_str() ) );
          if ( !bthreshold )
            threshold.rmsdisplacement=atof ( token.at ( 3 ).c_str() );
          bthreshold=true;
          bbreak=true;

        }


      }
      if ( bbreak ) break;



    }

    molecule.SetThreshold ( threshold );
    m_molecule->push_back ( molecule );

    m_molecule->back().SetConexions();
    if ( pt+1 != pos.end() )
    {
      GetDipole ( *pt,* ( pt+1 ) );
      GetESPCharges ( *pt,* ( pt+1 ) );
    }
    else
    {
      m_file->seekg ( 0,std::ios::end );
      std::streampos end=m_file->tellg();
      GetDipole ( *pt,end );
      GetESPCharges ( *pt,end );
    }

  }

  return true;
}
bool GaussianParser::GetVectors()
{
  //m_molecule->AllocateVectors();
  int counter=0;
  std::string line;

  //OK put vectors onto last molecule
  CMolecule& molecule=m_molecule->back();
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer token ( line," " );;

    if ( token.size() <5 )
    {
      scounter+=3;
      return true;
    }
    else
    {
      int nfreq= ( token.size()-2 ) /3;

      for ( int i=0;i<nfreq;i++ )
      {
        //  if( counter < m_molecule->m_atom.size() && (nfreq+scounter) < m_molecule->m_atom[0].mode.size() )
        molecule.m_atom[counter].mode[i+scounter].x=atof ( token[2+3*i].c_str() );
        molecule.m_atom[counter].mode[i+scounter].y=atof ( token[2+3*i+1].c_str() );
        molecule.m_atom[counter].mode[i+scounter].z=atof ( token[2+3*i+2].c_str() );


      }
      counter++;
    }
  }

  return true;
}
bool GaussianParser::GetFrequencies()
{
  CMolecule& molecule=m_molecule->back();

  std::vector<frequency>& frequencies=molecule.GetFrequencies();

  std::string line;
  //rewind

  size_t counter=0;
  size_t counter1=0;
  size_t counter2=0;
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer tok ( line );
    if ( tok.size() )
    {
      int steps=0;
      if ( tok[0]=="Frequencies" )
      {

        for ( size_t j=2;j<tok.size();j++ )
        {


          //  frequencies[counter].x=atof(tok[j].c_str());
          frequencies.push_back ( frequency ( atof ( tok[j].c_str() ),0.0f ) );
          counter++;
        }

      }

      //int steps=0;
      if ( tok[0]=="IR" )
      {
        for ( size_t k=3;k<tok.size();k++ )
        {
          frequencies[counter1++].y=atof ( tok[k].c_str() );
          //std::cout << "ir[" << counter+steps << "]=" << frequencies[counter+steps].y << std::endl;
          //counter++;
          steps++;
        }
      }
      //steps=0;
      if ( tok[0]=="Rot." )
      {
        for ( size_t k=3;k<tok.size();k++ )
        {
          frequencies[counter2++].z=atof ( tok[k].c_str() );
          //std::cout << "vcd[" << counter << "]=" << frequencies[counter].z << std::endl;
          //steps++;
        }

      }

    }
  }

  return true;
}

bool GaussianParser::HasKeyword ( std::string& line )
{

  StringTokenizer token ( line," " );

  if ( token.size() ==7 )
  {
    if ( token[6]=="analyticall!" )
    {

      return true;
    }
    else
      return false;
  }
  else
    return false;
}

bool GaussianParser::GetESPCharges ( const std::streampos& begin, const std::streampos& end )
{
  m_file->clear ( );               //
  m_file->seekg ( begin, std::ios::beg );   // moves pointer to

  std::string line;
  std::streampos pos=0;
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "Charges from ESP fit" ) != std::string::npos )
      break;
  }
  pos=m_file->tellg();

  if ( pos <= 0 ) return false;
  if ( end > 0 && pos > end ) return false;

  m_molecule->back().Charges ( CMolecule::ESP )->reserve ( m_molecule->back().m_atom.size() );
  std::getline ( *m_file,line );
  std::getline ( *m_file,line );
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer tok ( line );
    if ( tok.size() >= 3 )
    {
      m_molecule->back().Charges ( CMolecule::ESP )->push_back ( std::atof ( tok.at ( 2 ).c_str() ) );
    }
    if ( line.find ( "--" ) != std::string::npos ) break;
  }
  return true;
}
bool GaussianParser::GetDipole ( const std::streampos& begin, const std::streampos& end )
{
  m_file->clear ( );               //
  m_file->seekg ( begin, std::ios::beg );   // moves pointer to

  std::string line;
  std::streampos pos=0;
  while ( std::getline ( *m_file,line ) )
  {
    StringTokenizer token ( line );
    if ( token.size() )
    {
      if ( token[0]=="Dipole" && token[1]=="moment" )
      {
        pos=m_file->tellg();
        goto lb1;
      }
    }
  }

lb1:

  if ( pos <= 0 ) return false;
  if ( end > 0 && pos > end ) return false;


  m_file->clear ( );               //

  m_file->seekg ( pos, std::ios::beg );   // moves pointer to

  std::getline ( *m_file,line );
  StringTokenizer token ( line );
  if ( token.size() < 6 ) return false; //simply return on error
  //change from physicist to chemist convention
  m_molecule->back().m_dipole.x=-atof ( token[1].c_str() );
  m_molecule->back().m_dipole.y=-atof ( token[3].c_str() );
  m_molecule->back().m_dipole.z=-atof ( token[5].c_str() );

  return true;

}

Quantum::level GaussianParser::GetLevel()
{
  std::string line, pline;


  while ( line.find ( "-----" ) == std::string::npos )
  {
    //  line.erase(line.size()-1,1);
    std::cout << "line now is " << line << std::endl;
    line+=pline;
    std::getline ( *m_file,pline );
    line.erase ( 0,1 );
    // wholeline+=line;
  }
  /* while(std::getline(*m_file,pline))
   {
     line+=pline;
     if (line.find("---")!=std::string::npos ) break;
   }*/
  StringTokenizer::toupper ( line );
  if ( ( line.find ( "MNDO",0 ) != std::string::npos ) ||
          ( line.find ( "AM1",0 ) != std::string::npos ) ||
          ( line.find ( "PM3",0 ) != std::string::npos ) )
  {
    std::cout << "MNDO calculation" << std::endl;
    return Quantum::MNDO;
  }
  if ( line.find ( "MP2",0 ) !=std::string::npos )
  {
    std::cout << "MP2 calculation" << std::endl;
    return Quantum::MP2;
  }
  if ( line.find ( "QCISD",0 ) !=std::string::npos )
  {
    std::cout << "QCISD calculation" << std::endl;
    return Quantum::QCISD;
  }
  if ( line.find ( "SCRF",0 ) !=std::string::npos )
  {
    //this is always present in frequency calculations
    if ( line.find ( "SCRF=CHECK" )  == std::string::npos )
    {
      std::cout << "SCRF calculation" << std::endl;
      return Quantum::SCRF;
    }
  }

  //Hartree-Fock by default
  std::cout << "HF/DFT calculation" << std::endl;
  return Quantum::HF;
}

std::vector<Quantum::jobheader>& GaussianParser::GetJobs()
{
  //lets get the lines beginning with a #
  std::string line;
  std::streampos pos=m_file->tellg();
  std::getline ( *m_file,line );
  do
  {
    //it could be that by chance a # line is inside the arquive entry, so do this little hack
    // to avoid this
    if ( line.find ( "1\\1\\",0 ) == 1 || line.find ( "1|1|",0 ) == 1 )
    {
      std::getline ( *m_file,line );
      std::getline ( *m_file,line );
      std::getline ( *m_file,line );
    }
    if ( line.find ( '#',0 ) == 1 ) //should be the second character
    {
      Quantum::jobtype tjob=Quantum::dens;
      bool bfound=false;

      std::string wholeline;//(line);//=line;
      //std::getline(*m_file,line);
      while ( line.find ( "-----" ) == std::string::npos )
      {
        //  line.erase(line.size()-1,1);
        std::cout << "line now is " << line << std::endl;
        wholeline+=line;
        std::getline ( *m_file,line );
        line.erase ( 0,1 );
        // wholeline+=line;
      }
      std::cout << "hole line is " << wholeline << std::endl;
      line=wholeline;
      //take into account that route can be splitted into several lines
      do
      {
        StringTokenizer::toupper ( line );
        if ( line.find ( "OPT",0 ) != std::string::npos )
        {
          tjob=Quantum::opt;
          bfound=true;
        }
        else
          if ( line.find ( "FREQ",0 ) != std::string::npos )
          {
            tjob=Quantum::freq;
            bfound=true;
          }
        if ( line.find ( "TD",0 ) != std::string::npos )
        {
          tjob=Quantum::uv;
          bfound=true;
        }
        if ( line.find ( "NMR",0 ) != std::string::npos )
        {
          tjob=Quantum::nmr;
          bfound=true;
        }
        if ( bfound ) break;
        //pos=m_file->tellg();
        std::getline ( *m_file,line );
      }
      while ( line.find ( "-----" ) == std::string::npos );
      std::cout << "pos is " << pos << std::endl;
      m_jobpos.push_back ( Quantum::jobheader ( tjob,pos ) );
    }
    pos=m_file->tellg();
  }
  while ( std::getline ( *m_file,line ) );

  return m_jobpos;


}

bool GaussianParser::ParseAIM ( std::streampos pos )
{
  m_file->clear();
  m_file->seekg ( pos );
  AIMParser aimp ( m_file );
  aimp.SetMolecule ( m_molecule );
  return aimp.ParseFile ( pos );
  //search for header
}

void GaussianParser::GetForces ( CMolecule& molecule )
{
  std::string line;
  for ( int i=0;i<2;i++ ) std::getline ( *m_file,line );
  std::vector<CAtom>::iterator it=molecule.m_atom.begin();
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "---" ) !=std::string::npos ) return;
    StringTokenizer token ( line," \t\r" );
    it->Gradient().x=atof ( token.at ( 2 ).c_str() );
    it->Gradient().y=atof ( token.at ( 3 ).c_str() );
    it->Gradient().z=atof ( token.at ( 3 ).c_str() );
    ++it;
  }

}
