/*
 * 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 .
 */
/** \file element.cpp
 * 
 * Function implementations for the class element.
 * 
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include "CodePatterns/MemDebug.hpp"
#include 
#include 
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Log.hpp"
#include "element.hpp"
using namespace std;
/************************************* Functions for class element **********************************/
/** Constructor of class element.
 */
element::element() :
  mass(0),
  CovalentRadius(0),
  Electronegativity(0.),
  VanDerWaalsRadius(0),
	Z(0),
	period(""),
	group(""),
	block(""),
	Valence(0),
	NoValenceOrbitals(0),
	name(""),
	symbol("")
{
  for (size_t i =0; i<3;++i)
    color[i] = (unsigned char)0;
  for (size_t i =0; i<3;++i)
    HBondDistance[i] = -1.;
  for (size_t i =0; i<3;++i)
    HBondAngle[i] = -1.;
};
element::element(const element &src) :
  mass(src.mass),
  CovalentRadius(src.CovalentRadius),
  Electronegativity(src.Electronegativity),
  VanDerWaalsRadius(src.VanDerWaalsRadius),
  Z(src.Z),
  period(src.period),
  group(src.group),
  block(src.block),
  Valence(src.Valence),
  NoValenceOrbitals(src.NoValenceOrbitals),
  name(src.name),
  symbol(src.symbol)
{
  for (size_t i =0; i<3;++i)
    color[i] = src.color[i];
  for (size_t i =0; i<3;++i)
    HBondDistance[i] = src.HBondDistance[i];
  for (size_t i =0; i<3;++i)
    HBondAngle[i] = src.HBondAngle[i];
}
/** Destructor of class element.
 */
element::~element() {};
element &element::operator=(const element &src){
  if(this!=&src){
    mass=src.mass;
    CovalentRadius=src.CovalentRadius;
    Electronegativity=src.Electronegativity;
    VanDerWaalsRadius=src.VanDerWaalsRadius;
    Z=src.Z;
    period = src.period;
    group = src.group;
    block = src.block;
    Valence=src.Valence;
    NoValenceOrbitals=src.NoValenceOrbitals;
    for (size_t i =0; i<3;++i)
      color[i] = src.color[i];
    for (size_t i =0; i<3;++i)
      HBondDistance[i] = src.HBondDistance[i];
    for (size_t i =0; i<3;++i)
      HBondAngle[i] = src.HBondAngle[i];
    name=src.name;
    symbol=src.symbol;
  }
  return *this;
}
double element::getMass() const
{
  return mass;
}
double element::getCovalentRadius() const
{
  return CovalentRadius;
}
const unsigned char * element::getColor() const
{
  return color;
}
double element::getElectronegativity() const
{
  return Electronegativity;
}
double element::getVanDerWaalsRadius() const
{
  return VanDerWaalsRadius;
}
atomicNumber_t element::getAtomicNumber() const
{
  return Z;
}
double element::getValence() const
{
  return Valence;
}
int element::getNoValenceOrbitals() const
{
  return NoValenceOrbitals;
}
double element::getHBondDistance(const size_t i) const
{
  ASSERT((i<3), "Access to element::HBondDistance out of bounds.");
  return HBondDistance[i];
}
double element::getHBondAngle(const size_t i) const
{
  ASSERT((i<3), "Access to element::HBondAngle out of bounds.");
  return HBondAngle[i];
}
const string &element::getSymbol() const{
  return symbol;
}
void element::setSymbol(const std::string &temp)
{
  symbol = temp;
}
const std::string &element::getName() const{
  return name;
}
void element::setName(const std::string &temp)
{
  name = temp;
}
/** Comparison operator for stub of Element.
 *
 * @param other other instance to compare to
 * @return true if all member variables have the same contents.
 */
bool element::operator==(const element &other) const
{
  if (mass != other.mass) return false;
  if (CovalentRadius != other.CovalentRadius) return false;
  if (Electronegativity != other.Electronegativity) return false;
  if (VanDerWaalsRadius != other.VanDerWaalsRadius) return false;
  if (Z != other.Z) return false;
  if (period != other.period) return false;
  if (group != other.group) return false;
  if (block != other.block) return false;
  if (Valence != other.Valence) return false;
  if (NoValenceOrbitals != other.NoValenceOrbitals) return false;
  for (size_t i = 0; i < 3; ++i)
    if (HBondDistance[i] != other.HBondDistance[i]) return false;
  for (size_t i = 0; i < 3; ++i)
    if (HBondAngle[i] != other.HBondAngle[i]) return false;
  for (size_t i = 0; i < 3; ++i)
    if (color[i] != other.color[i]) return false;
  if (name != other.name) return false;
  if (symbol != other.symbol) return false;
  return true;
}
std::ostream &operator<<(std::ostream &ost,const element &elem){
  ost << elem.getName() << "(" << elem.getAtomicNumber() << ")";
  return ost;
}