/***************************************************************************
 *   Copyright (C) 2004 by Armando Navarro Vázquez                         *
 *   armando@rmntec                                                        *
 *                                                                         *
 *   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 <sstream>

#include "archiveparser.h"
#include "tokenizer.h"
#include "molecule.h"
#include "iarrays.h"

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

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


ArchiveParser::~ArchiveParser()
{}

bool ArchiveParser::HasHessian()
{
  std::string archive;
  std::string line;
  m_file->seekg(0,std::ios::beg);

  while(std::getline(*m_file,line) )
  {
    archive+=line;
  }
  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,"\\\\");

  return ( t.size() >= 7);


}
bool ArchiveParser::ParseFile(std::streampos pos)
{
  std::string archive;
  std::string line;
  m_file->clear();
  m_file->seekg(0,std::ios::beg);

  while(std::getline(*m_file,line) )
  {
    archive+=line;
  }
  //OK lets clear bakspaces
  std::string::size_type sit=0;
  CMolecule molecule;
  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,"\\\\");
  std::string& geometry= t[3];
  TokByString::iterator tit;
  for(tit=t.begin();tit!=t.end();tit++)
  {
    std::cerr << *tit << "......." << std::endl;
  }


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


  std::cerr << geometry << std::endl;

  StringTokenizer g1(geometry,"\\");

  molecule.m_atom.clear();
  molecule.m_atom.resize(g1.size()-1);

  size_t i;
  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;
    molecule.m_atom[i].name= g2[0];
    StringTokenizer::reverse_iterator it2=g2.rbegin();
    molecule.m_atom[i].c.z= atof((it2++)->c_str());
    molecule.m_atom[i].c.y= atof((it2++)->c_str());
    molecule.m_atom[i].c.x= atof(it2->c_str());
  }

  molecule.SetConexions();

  //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)
  {
    m_molecule->push_back(molecule);
    return true;
  }

  molecule.AllocateForces();
  molecule.AllocateHessian();
  
   //Lets get forces in seventh block
  IMArray<double>& forces=molecule.GetForces();
  g1=StringTokenizer(t[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[5];
  StringTokenizer g2(t[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;
    }
  }
  
  //and dipole derivatives are in fith block after 
  g1=StringTokenizer(t[4],"\\");
  for(it=g1.begin();it!=g1.end();it++)
  {
     if ( it->find("DipoleDeriv=") != std::string::npos ) break;
  }
  if(it!=g1.end())
  {
    IBArray<double>& dipolederiv=molecule.GetDipoleDerivatives();
    std::string& dipolematrix =(*it);
    dipolematrix.erase(0,12);
    StringTokenizer g2(dipolematrix);
    StringTokenizer::iterator it2=g2.begin();
    for(j=0;j<3;j++)
    {
      for(i=0;i< 3*molecule.m_atom.size() ;i++)
        dipolederiv(i,j)=atof(it2->c_str());
    }
    
  }
  

  molecule.CalculateFrequencies();
  m_molecule->push_back(molecule);
  return true;

}
