/***************************************************************************
 *   Copyright (C) 2004 by Armando Navarro-Vazquez                         *
 *   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 "quantumfile.h"
#include <iostream>
#include "tokenizer.h"

QuantumFile::qfiletype QuantumFile::GetFileType()
{

  std::cout << "Getting the file type..." << std::endl;
  std::string line;
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "Standard orientation",0 ) != std::string::npos ||  line.find ( "Input orientation",0 ) != std::string::npos )
      return Gaussian;
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );

  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "Northwest Computational Chemistry Package" ) != std::string::npos )
    {
      std::cout << "NwChem file" << std::endl;
      return NwChem;
    }
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  std::getline ( *m_file,line );
  if ( line.find ( "PROGRAM CPMD STARTED AT" ) != std::string::npos )
  {
    std::cout << "CPMD file" << std::endl;
    return CPMD;
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "ACES2: Advanced Concepts in Electronic Structure II" ) != std::string::npos || line.find("CFOUR Coupled-Cluster techniques for Computational Chemistry") != std::string::npos )
    {
      std::cout << "ACESII/CFOUR file" << std::endl;
      return Aces;
    }
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "GAMESS VERSION" ) != std::string::npos )
      return Gamess;
  }


  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "s_m_m2io_version" ) != std::string::npos )
    {
      std::cout << "MacroModel Maestro format" << std::endl;
      return MacroModelMaestro;
    }

  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  while ( std::getline ( *m_file,line ) )
  {
    if ( ( line.find ( "HETATM" ) != std::string::npos ) || line.find ( "ATOM" ) != std::string::npos )
    {
      std::cout << "PDB file" << std::endl;
      return PDB;
    }
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  std::getline ( *m_file,line );
  if ( ( line.find ( "1\\1\\" ) != std::string::npos ) || ( line.find ( "1|1|" ) != std::string::npos ) ) return GaussianArchive;

  //MOL
  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  {
    for ( int i=0;i < 4; i++ )
    {
      std::getline ( *m_file,line );
    }
    std::cout << line << std::endl;

    StringTokenizer token ( line," \t\r" );
    if ( !token.empty() )
    {
      if ( token.back() =="V2000"  || token.size() == 11L )
      {
        std::cout << "MDL Mol file" << std::endl;
        return Mol;
      }
      std::string line1;
      std::getline ( *m_file,line1 );
      StringTokenizer tok ( line1," \t\r" );
      if ( tok.size() > 3 )
      {
        if ( strtools::isnum ( tok.at ( 0 ) ) && strtools::isnum ( tok.at ( 1 ) )
                && strtools::isnum ( tok.at ( 2 ) ) && !strtools::isnum ( tok.at ( 3 ) ) )
        {
          std::cout << "MDL Mol file" << std::endl;
          return Mol;
        }
      }

    }
  }

  //Tinker
  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  //first line should have "molden generated"
  std::getline ( *m_file,line );
  if ( line.find ( "tinker" ) != std::string::npos )
  {
    std::cout << "Tinker File" << std::endl;
    return Tinker;
  }

  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  while ( std::getline ( *m_file,line ) )
  {
    if ( line.find ( "WELCOME" ) != std::string::npos )
    {
      std::getline ( *m_file,line );
      if ( line.find ( "PSI" ) != std::string::npos ) return Psi3;
    }
  }


  //MacroModel dynamics
  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  std::getline ( *m_file,line );
  std::getline ( *m_file,line );
  {
    StringTokenizer token ( line," \t\r" );
    if ( token.size() > 13 )
    {
      for ( int i=0;i<13;i++ )
      {
        if ( !strtools::isinteger ( token.at ( i ) ) ) goto lb;
      }
      std::cout << "MacroModel dynamics" << std::endl;
      return MacroModelDyn;
    }
  }

lb:
  m_file->clear();
  m_file->seekg ( 0,std::ios::beg );
  std::getline ( *m_file,line );
  StringTokenizer token ( line );
  if ( token.size() == 1 )
    if ( strtools::isinteger ( token.at ( 0 ) ) )
    {
      std::cout << "XYZ file" << std::endl;
      return XYZ;
    }


  return None;

}



