#include <iostream>
#include <openbabel/mol.h>
#include <openbabel/obconversion.h>

using namespace OpenBabel;
using namespace std;

int main(int argc,char **argv) {

  OBMol mymol;
  OBAtom *atom;
  OBConversion conv;
  OBFormat *inFormat;
  OBFormat *outFormat;
  OBSmartsPattern smarts;

  string infilename;
  string outfilename;
  string smpat;
  vector< vector <int> > maplist;
  vector< vector <int> >::iterator matches;
  vector<OBAtom*>::iterator iter;

  int nat;
  bool notatend;

  mymol.Clear();
  infilename = argv[1];
  smpat = argv[2];
  outfilename = argv[3];

  smarts.Init(smpat);

  inFormat = conv.FormatFromExt(infilename.c_str());
  outFormat = conv.FormatFromExt(outfilename.c_str());
  conv.SetInFormat(inFormat);
  conv.SetOutFormat(outFormat);
  conv.OpenInAndOutFiles(infilename,outfilename);

  notatend = conv.ReadFile(&mymol, infilename);
  conv.WriteFile(NULL, outfilename);

  while (notatend) {

    cout << "Processing molecule " << mymol.GetTitle() << endl;

    if (smarts.Match(mymol)) {

      if(smarts.NumMatches() > 1) {
        cout << "molecule " << mymol.GetTitle() << " has more than one (" 
             << smarts.NumMatches() << ") unique matches" << endl;
        cout << "aborting" << endl;
        exit(1);
      } else {
        cout << "found one match of " << smpat << " in " << mymol.GetTitle() << endl;
      }

      maplist = smarts.GetUMapList();

      vector<OBAtom*> atomsToDelete;

      for (matches = maplist.begin(); matches != maplist.end(); matches++) {

        for(nat=0;nat<smarts.NumAtoms();nat++) {
          atom = mymol.GetAtom((*matches)[nat]);
          atomsToDelete.push_back(atom);
        }

        for (iter = atomsToDelete.begin(); iter != atomsToDelete.end(); ++iter) {
          mymol.DeleteAtom(*iter);
	}
      }
    }

    //    mymol.DeleteHydrogens();

    cout << "...... added " << mymol.AddHydrogens(false,true,7.4) << "Hs" << endl;

    //mymol.NewPerceiveKekuleBonds();
    //mymol.PerceiveBondOrders();

    conv.Write(&mymol);

    mymol.Clear();
    notatend = conv.Read(&mymol);
  }
}
