/***************************************************************************
 *   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 "aimparser.h"
#include "tokenizer.h"
#include "molecule.h"

const double bohrtoangs=0.529189379;

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

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

AIMParser::~AIMParser()
{}

bool AIMParser::ParseFile(std::streampos pos)
{
  m_file->clear();
  m_file->seekg(pos);
  std::string line;
  while(std::getline(*m_file,line))
  {
    int kk=5;
    if( line.find("Properties of atoms in molecules") != std::string::npos)
    {
      GetAttractors();
      GetBondPoints();
      GetRingPoints();
      GetCagePoints();
      GetAttractorsCharges();
      return true;
    }
  }
  return false;
}

bool AIMParser::GetAttractors()
{
  std::string line;
  while(std::getline(*m_file,line))
  {
    if (line.find("Attr.") != std::string::npos)
      //skip two lines
    {
      std::getline(*m_file,line);
      std::getline(*m_file,line);

      while(std::getline(*m_file,line))
      {
        if( line.find("--") != std::string::npos || line.find("WARNING") != std::string::npos ) return true;;
        StringTokenizer token(line);
        float x=bohrtoangs*atof(token.at(1).c_str());
        float y=bohrtoangs*atof(token.at(2).c_str());
        float z=bohrtoangs*atof(token.at(3).c_str());
        coordinate c(x,y,z);
        std::vector<AIM::Attractor>& attractors=m_molecule->back().GetAttractors();
        attractors.push_back(AIM::Attractor(coordinate(x,y,z),0));

      }
    }
  }

  return false;
}

bool AIMParser::GetBondPoints()
{
  std::string line;
  while(std::getline(*m_file,line))
  {     /* std::cout << "line now is" << std::endl;
      std::cout << line << std::endl;*/
    if(line.find("ATTRACTOR INTERACTION LINES")!= std::string::npos)
    {
      //skip five lines
      for(int i=0;i<5;i++)
        std::getline(*m_file,line);

      while(std::getline(*m_file,line))
      {
        if( line.find("--") != std::string::npos) return true;
        StringTokenizer token(line);
        float x=bohrtoangs*atof(token.at(3).c_str());
        float y=bohrtoangs*atof(token.at(4).c_str());
        float z=bohrtoangs*atof(token.at(5).c_str());
        coordinate c(x,y,z);
        std::vector<AIM::CriticalPoint>& bpt=m_molecule->back().GetBondPoints();
        bpt.push_back(AIM::CriticalPoint(coordinate(x,y,z)));
        bpt.back().attractors.push_back(atoi(token.at(1).c_str())-1);
        bpt.back().attractors.push_back(atoi(token.at(2).c_str())-1);
      }
    }
  }

}

bool AIMParser::GetAttractorsCharges()
{
  std::string line;
  while(std::getline(*m_file,line))
  {
    if( line.find("Number of electrons") != std::string::npos )
    {
      std::getline(*m_file,line);
      std::getline(*m_file,line);
      std::vector<AIM::Attractor>::iterator it=m_molecule->back().GetAttractors().begin();
      while(std::getline(*m_file,line))
      {
        if( line.find("--") != std::string::npos) return true;
        StringTokenizer token(line);

        it++->q=atof(token.back().c_str());

      }

    }

  }
}

bool AIMParser::GetRingPoints()
{
    std::string line;
  while(std::getline(*m_file,line))
  {     /* std::cout << "line now is" << std::endl;
      std::cout << line << std::endl;*/
    if(line.find("RING POINTS")!= std::string::npos)
    {
      //skip five lines
      for(int i=0;i<5;i++)
        std::getline(*m_file,line);


      while(std::getline(*m_file,line))
      {

        if( line.find("--") != std::string::npos) return true;
        StringTokenizer token(line," \t(");
        if (token.size() < 5 )
        {
          std::cout << "problem while getting ring points" << std::endl;
          return false;
        }
        float x=bohrtoangs*atof(token.at(2).c_str());
        float y=bohrtoangs*atof(token.at(3).c_str());
        float z=bohrtoangs*atof(token.at(4).c_str());
        coordinate c(x,y,z);
        std::vector<AIM::CriticalPoint>& rpt=m_molecule->back().GetRingPoints();
        rpt.push_back(AIM::CriticalPoint(coordinate(x,y,z)));
        StringTokenizer::iterator it;
        for(it=token.begin()+5;it!=token.end();it++)
        {
            rpt.back().attractors.push_back(atoi(it->c_str()));
        }
      }
    }
  }
}

bool AIMParser::GetCagePoints()
{}

