#include "MolParser.h"
#include "molecule.h"
#include "tokenizer.h"
#include <vector>
#include <sstream>

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

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

MolParser::~MolParser ( void )
{}

bool MolParser::ParseFile ( std::streampos pos )
{
  std::cout << "MolParser" << std::endl;
  std::string line;
  m_file->clear();
  m_file->seekg ( pos,std::ios::beg );
  bool bfirst=true;
  while ( std::getline ( *m_file,line ) )
  {

    //skip three first lines
    size_t i=0;


    //OK, gets the number of atoms and bonds
    bool brokenfile=false;
    while ( std::getline ( *m_file,line ) )
    {
      StringTokenizer token ( line," \t\r" );
      if ( !token.empty() )
      {

        if ( token.size() == 11L || token.back() == "V2000" ) goto lb1;

        //may be broken files with no V2000 or no 11 elements
        if ( token.size() >=5 )
        {
          bool bheader=true;
          for ( size_t i=0;i<5;++i )
          {
            if ( !strtools::isinteger ( token.at ( i ) ) ) bheader=false;
          }
          if ( bheader )
          {
            brokenfile=true;
            goto lb1;
          }
        }
      }
    }
  lb1:

    StringTokenizer token ( line," \t\r" );

    if ( token.empty() ) return !bfirst;
    //either there are 11 numbers or last token is "V2000"
    if ( token.size() != 11L  && token.back() !="V2000" && !brokenfile ) return !bfirst;
    bfirst=false;
    int natoms=atoi ( token[0].c_str() );
    int nbonds=atoi ( token[1].c_str() );
    if (  natoms < 1 )
      return false;
    CMolecule molecule;
    molecule.m_atom.clear();
    molecule.m_atom.resize ( natoms );

    std::vector<CAtom>::iterator at;
    for ( at=molecule.m_atom.begin(),i=1;at!=molecule.m_atom.end();at++,i++ )
    {
      std::getline ( *m_file,line );
      StringTokenizer token ( line );
      if ( token.size() < 4 )
        return false;
      at->c.x=atof ( token.at(0).c_str() );
      at->c.y=atof ( token.at(1).c_str() );
      at->c.z=atof ( token.at(2).c_str() );
      std::stringstream st;
      st << i;
//      at->label=st.str();
      at->name=token[3];

    }

    //OK,iterate through bonds
    for ( i=0;i<nbonds;i++ )
    {
      if ( std::getline ( *m_file,line ) )
      {
        StringTokenizer token ( line );
        int natom1=atoi ( token.at(0).c_str() );
        int natom2=atoi ( token.at(1).c_str() );
        int atomtype=atoi ( token.at(2).c_str() );

        bondtype bt;
        switch ( atomtype )
        {
          case 1:
            bt=eSINGLE;
            break;
          case 2:
            bt=eDOUBLE;
            break;
          case 3:
            bt=eTRIPLE;
            break;
          case 4:
            bt=eAROMATIC;
            break;
          default:
            break;
        }

        if (  ( natom1  > 0 && natom1 <= natoms ) &&  ( natom2  > 0 && natom2 <= natoms ) )

          molecule.m_atom.at(natom1-1).conexion.push_back ( bond ( natom2-1,bt ) );
      }
    }
    molecule.SetConexions();
    molecule.CalculateMassCenter();
    m_molecule->push_back ( molecule );

  }
  return true;
}

