/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2010-2012 University of Bonn. 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 .
 */
/*
 * FillerUnitTest.cpp
 *
 *  Created on: Jan 19, 2012
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include 
#include 
#include 
#include "CodePatterns/Assert.hpp"
#include "Atom/atom.hpp"
#include "Atom/CopyAtoms/CopyAtoms_Simple.hpp"
#include "Descriptors/AtomIdDescriptor.hpp"
#include "Element/periodentafel.hpp"
#include "Filling/Cluster.hpp"
#include "Filling/Filler.hpp"
#include "Filling/Inserter/Inserter.hpp"
#include "Filling/Inserter/SimpleInserter.hpp"
#include "Filling/Mesh/Mesh.hpp"
#include "Filling/Predicates/FillPredicate.hpp"
#include "LinearAlgebra/Vector.hpp"
#include "molecule.hpp"
#include "Shapes/BaseShapes.hpp"
#include "Shapes/Shape.hpp"
#include "World.hpp"
#include "WorldTime.hpp"
#include "FillerUnitTest.hpp"
#ifdef HAVE_TESTRUNNER
#include "UnitTestMain.hpp"
#endif /*HAVE_TESTRUNNER*/
/********************************************** Test classes **************************************/
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( FillerTest );
class MeshStub : public Mesh
{
  public:
  MeshStub() {
    nodes.reserve(5);
    for (double i=1; i<6.; ++i)
      nodes.push_back(Vector(i,0.,0.));
  }
  virtual ~MeshStub()
  {}
};
void FillerTest::setUp()
{
  // failing asserts should be thrown
  ASSERT_DO(Assert::Throw);
  predicate = new FillPredicate(AlwaysFillPredicate());
  mesh = new MeshStub();
  inserter = new Inserter(Inserter::impl_ptr(new SimpleInserter()));
  CPPUNIT_ASSERT_EQUAL( (size_t)5, mesh->getNodes().size() );
  filler = new Filler(*mesh, *predicate, *inserter);
  s = new Shape(Sphere( Vector(0.,0.,0.05), 0.1));
  Cluster::atomIdSet atoms;
  // create an atom
  hydrogen = World::getInstance().getPeriode()->FindElement(1);
  CPPUNIT_ASSERT(hydrogen != NULL);
  _atom = World::getInstance().createAtom();
  _atom->setType(hydrogen);
  _atom->setPosition( zeroVec );
  atoms.insert(_atom->getId());
  _atom = World::getInstance().createAtom();
  _atom->setType(hydrogen);
  _atom->setPosition( Vector(0.,0.,0.1) );
  atoms.insert(_atom->getId());
  CPPUNIT_ASSERT( s->isInside(_atom->getPosition()) );
  cluster = new ClusterInterface::Cluster_impl(new Cluster(atoms, *s));
}
void FillerTest::tearDown()
{
  hydrogen = NULL;
  delete cluster;
  delete filler;
  delete mesh;
  delete predicate;
  delete inserter;
  World::purgeInstance();
  WorldTime::purgeInstance();
}
/** Test whether operator() works
 *
 */
void FillerTest::operatorTest()
{
  CopyAtoms_Simple copyMethod;
  Filler::ClusterVector_t ClonedClusters;
  (*filler)(copyMethod, *cluster, ClonedClusters);
  // one atom at 5 nodes added
  CPPUNIT_ASSERT_EQUAL( mesh->getNodes().size(), ClonedClusters.size() );
  CPPUNIT_ASSERT_EQUAL(
      mesh->getNodes().size()*2,
      const_cast(World::getInstance()).getAllAtoms().size() );
}