/*
 * 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 .
 */
/*
 * GeometryRegistry.cpp
 *
 *  Created on: Mar 25, 2017
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "GeometryRegistry.hpp"
#include 
#include 
#include "CodePatterns/Singleton_impl.hpp"
#include "CodePatterns/Registry_impl.hpp"
#include "CodePatterns/Observer/Channels.hpp"
using namespace boost::assign;
GeometryRegistry::GeometryRegistry() :
  Observable::Observable("GeometryRegistry")
{
  Channels *OurChannel = new Channels;
  Observable::insertNotificationChannel( std::make_pair(static_cast(this), OurChannel) );
  // add instance for each notification type
  for (size_t type = 0; type < NotificationType_MAX; ++type)
    OurChannel->addChannel(type);
  _lastchanged = NULL;
  fillRegistry();
}
GeometryRegistry::~GeometryRegistry()
{
  cleanup();
}
void GeometryRegistry::fillRegistry()
{
  const GeometryObject zeroVector(zeroVec, std::string("zeroVector"));
  addGeometry(zeroVector);
  const GeometryObject unitVectorX(unitVec[0], std::string("unitVectorX"));
  addGeometry(unitVectorX);
  const GeometryObject unitVectorY(unitVec[1], std::string("unitVectorY"));
  addGeometry(unitVectorY);
  const GeometryObject unitVectorZ(unitVec[2], std::string("unitVectorZ"));
  addGeometry(unitVectorZ);
}
void GeometryRegistry::addGeometry(const GeometryObject &_v)
{
  OBSERVE;
  GeometryObject *instance = new GeometryObject(_v);
  registerInstance(instance);
  _lastchanged = instance;
  NOTIFY(GeometryInserted);
}
void GeometryRegistry::removeGeometry(const std::string &name)
{
  GeometryObject *instance = getByName(name);
  {
    OBSERVE;
    _lastchanged = instance;
    NOTIFY(GeometryRemoved);
  }
  unregisterInstance(instance);
  delete(instance);
}
static std::vector setProtectedNames()
{
  std::vector names;
  names += std::string("zeroVector"),
      std::string("unitVectorX"),
      std::string("unitVectorY"),
      std::string("unitVectorZ");
  return names;
}
bool GeometryRegistry::isProtectedName(const std::string &_name) const
{
  static std::vector protected_names = setProtectedNames();
  if (std::count(protected_names.begin(), protected_names.end(), _name) != 0)
    return true;
  return false;
}
CONSTRUCT_SINGLETON(GeometryRegistry)
CONSTRUCT_REGISTRY(GeometryObject)