/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2017 Frederik Heber. All rights reserved.
 *
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder 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.
 *
 *    MoleCuilder 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 MoleCuilder.  If not, see .
 */
/*
 * BoostGraphCreator.cpp
 *
 *  Created on: May 17, 2017
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "BoostGraphCreator.hpp"
#include 
#include "CodePatterns/Assert.hpp"
#include "Atom/atom.hpp"
#include "molecule.hpp"
void BoostGraphCreator::createFromMolecule(
    const molecule &_mol,
    const predicate_t &_pred)
{
  createFromRange(_mol.begin(), _mol.end(), _mol.getAtomCount(), _pred);
}
static bool predicateAnd(
    const BoostGraphCreator::predicate_t &_pred1,
    const BoostGraphCreator::predicate_t &_pred2,
    const bond &_bond)
{ return (_pred1(_bond) && _pred2(_bond)); }
static atomId_t getAtomId(
    const atom *_atom
    )
{ return _atom->getId(); }
static bool inSetPredicate(
  const std::vector &_atomids,
  const bond &_bond)
{
  const atomId_t leftid = _bond.leftatom->getId();
  const atomId_t rightid = _bond.rightatom->getId();
  return std::binary_search(_atomids.begin(), _atomids.end(), leftid)
      && std::binary_search(_atomids.begin(), _atomids.end(), rightid);
}
void BoostGraphCreator::createFromAtoms(
    const std::vector &_atoms,
    const predicate_t &_pred)
{
  // sort makes binary_search possible
  std::vector atomids;
  std::transform(_atoms.begin(), _atoms.end(),
      std::back_inserter(atomids), getAtomId);
  ASSERT( _atoms.size() == atomids.size(),
      "BoostGraphCreator::createFromAtom() - atomids "
      +toString(atomids.size())+" and atoms "+toString(_atoms.size())
      +" differ in size?");
  std::sort(atomids.begin(), atomids.end());
  const predicate_t predicate = boost::bind(inSetPredicate, boost::ref(atomids), _1);
  createFromRange::const_iterator>(
      const_cast &>(_atoms).begin(),
      const_cast &>(_atoms).end(),
      _atoms.size(),
      boost::bind(predicateAnd, _pred, predicate, _1));
}
BoostGraphCreator::nodeId_t BoostGraphCreator::getNodeId(
    const atomId_t &_atomid) const
{
  atomids_nodeids_t::const_iterator iter =
      atomids_nodeids.find(_atomid);
  return (iter == atomids_nodeids.end()) ? (nodeId_t)-1 : iter->second;
}