/**********************************************************************
smartsfilters.cpp - Some descriptors which analyse molecule using SMARTS
 
Copyright (C) 2007 by Chris Morley
 
This file is part of the Open Babel project.
For more information, see <http://openbabel.sourceforge.net/>
 
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 version 2 of the License.
 
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.
***********************************************************************/

#include <openbabel/babelconfig.h>
#include <openbabel/oberror.h>
#include <openbabel/mol.h>
#include <openbabel/descriptor.h>
#include <openbabel/parsmart.h>

using namespace std;
namespace OpenBabel
{
//**************************************************************
class SmartsDescriptor : public OBDescriptor
{
public:
  //! constructor. Each instance provides an ID, a SMARTS pattern and a description.
  SmartsDescriptor(const char* ID, const char* smarts, const char* descr)
    : OBDescriptor(ID, false), _smarts(smarts), _descr(descr){}

  virtual const char* Description()
  {
    //Adds the SMARTS string to the description
    static string txt;
    txt =  _descr;
    txt += "\n\t SMARTS: ";
    txt += _smarts;
    txt += "\nSmartsDescriptor is definable";
    return txt.c_str();
  }

  double Predict(OBBase* pOb)
  {
    OBMol* pmol = dynamic_cast<OBMol*> (pOb);
    if(!pmol)
      return 0;
      
    OBSmartsPattern sp;
    sp.Init(_smarts);
    sp.Match(*pmol);
      return sp.GetUMapList().size();
  
  }
   virtual SmartsDescriptor* MakeInstance(const std::vector<std::string>& textlines)
   {
     return new SmartsDescriptor(textlines[1].c_str(),textlines[2].c_str(),textlines[3].c_str());
   }

private:
  const char* _smarts;
  const char* _descr;
};

//Make global instances

  SmartsDescriptor theHBD("HBD", "[!#6;!H0]","Number of Hydrogen Bond Donors (JoelLib)");
  SmartsDescriptor theHBA1("HBA1", "[$([!#6;+0]);!$([F,Cl,Br,I]);!$([o,s,nX3]);!$([Nv5,Pv5,Sv4,Sv6])]",
    "Number of Hydrogen Bond Acceptors 1 (JoelLib)\n"
    "\t Identification of Biological Activity Profiles Using Substructural\n"
    "\t Analysis and Genetic Algorithms -- Gillet, Willett and Bradshaw,\n"
    "\t U. of Sheffield and Glaxo Wellcome.\n"
    "\t Presented at Random & Rational: Drug Discovery via Rational Design\n"
    "\t and Combinitorial Chemistry, Strategic Research Institute, Princeton\n"
    "\t NJ, Sept. 1995" );
  SmartsDescriptor theHBA2("HBA2", "[$([$([#8,#16]);!$(*=N~O);!$(*~N=O);X1,X2]),$([#7;v3;!$([nH]);!$(*(-a)-a)])]",
    "Number of Hydrogen Bond Acceptors 2 (JoelLib)");
  SmartsDescriptor thenF("nF", "F","Number of Fluorine Atoms");

}//namespace

