/*
 * 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 .
 */
/*
 * ShapeFactory.cpp
 *
 *  Created on: Sep 5, 2012
 *      Author: ankele
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include "CodePatterns/MemDebug.hpp"
#include "ShapeFactory.hpp"
#include "BaseShapes.hpp"
#include "ShapeOps.hpp"
#include "CodePatterns/Singleton_impl.hpp"
#include "LinearAlgebra/Vector.hpp"
#include "LinearAlgebra/RealSpaceMatrix.hpp"
const char *ShapeFactory::shapeNames[MAX_ShapeType] = {"nowhere", "everywhere", "sphere", "cube", "polygon", "combined", "cylinder"};
ShapeFactory::ShapeFactory()
{
  // Create map (type -> name).
  for (int i=0; i((ShapeType)i, shapeNames[i]));
  // Create inverse map.
  for (int i=0; i(shapeNames[i], (ShapeType)i));
  // Init state.
  type = SphereType;
  translation.Zero();
  stretch = Vector(1.,1.,1.);
  for (int i=0; isecond;
}
std::string ShapeFactory::getShapeName(ShapeType type)
{
  ShapeNameMap::iterator iter = shapeNameMap.find(type);
  ASSERT(iter != shapeNameMap.end(),
      "ShapeFactory::getShapeName() - unknown type: "+toString(type)+".");
  return iter->second;
}
bool ShapeFactory::isValidShapeName(const std::string& name)
{
  NameShapeMap::iterator iter = nameShapeMap.find(name);
  return (iter != nameShapeMap.end());
}
ShapeFactory::~ShapeFactory()
{
}
void ShapeFactory::setType(ShapeType type)
{
  ShapeNameMap::iterator iter = shapeNameMap.find(type);
  ASSERT(iter != shapeNameMap.end(),
      "ShapeFactory::setType() - unknown type: "+toString(type)+".");
  this->type = type;
}
void ShapeFactory::setStretch(const Vector &stretch)
{
  for (int i=0; i 0,
      "ShapeFactory::setStretch() - non positive component.");
  }
  this->stretch = stretch;
}
Shape ShapeFactory::produce() const
{
  // Create the basic shape.
  Shape s = Nowhere();
  if (type == NowhereType){
    s = Nowhere();
  }else if (type == EverywhereType){
    s = Everywhere();
  }else if (type == CuboidType){
    s = Cuboid();
  }else if (type == SphereType){
    s = Sphere();
  }else if (type == CylinderType){
    s = Cylinder();
  }else{
    ASSERT(false,
        "ShapeFactory::produce - unhandled shape type: "+toString(type)+".");
  }
  // Transform (if necessary).
  if (stretch != Vector(1., 1., 1.))
    s = ::stretch(s, stretch);
  for (int i=0; i