/*
 * 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 .
 */
/*
 * Parameter_vector.cpp
 *
 *  Created on: Mar 31, 2017
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "Parameters/Specifics/Parameter_vector.hpp"
#include "Parameters/ParameterExceptions.hpp"
Parameter::Parameter(const Parameter &instance) :
  ParameterInterface(instance.getName()),
  value(instance.value.getValidator())
{
  value.setAsString(instance.value.getAsStringUnvalidated());
}
/** Constructor for class Parameter.
 *
 */
Parameter::Parameter() :
  ParameterInterface("__no_name__"),
  value()
{};
/** Constructor for class Parameter.
 *
 */
Parameter::Parameter(const std::string &_name) :
  ParameterInterface(_name),
  value()
{};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _value initial value to set
 */
Parameter::Parameter(const std::string &_name, const Vector &_value) :
  ParameterInterface(_name),
  value()
{
  value.set(_value);
};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 */
Parameter::Parameter(const std::string &_name, const Validator &_Validator) :
  ParameterInterface(_name),
  value(_Validator)
{};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 * @param _value initial value to set
 */
Parameter::Parameter(const std::string &_name, const Validator &_Validator, const Vector &_value) :
  ParameterInterface(_name),
  value(_Validator)
{
  value.set(_value);
};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 */
Parameter::Parameter(const std::string &_name, const std::vector &_ValidValues) :
  ParameterInterface(_name),
  value(_ValidValues)
{};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 * @param _value initial value to set
 */
Parameter::Parameter(const std::string &_name, const std::vector &_ValidValues, const Vector &_value) :
  ParameterInterface(_name),
  value(_ValidValues)
{
  value.set(_value);
};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 */
Parameter::Parameter(const std::string &_name, const range &_ValidRange) :
  ParameterInterface(_name),
  value(_ValidRange)
{};
/** Constructor for class Parameter.
 *
 * @param _name name of this parameter
 * @param _ValidRange valid range for this ContinuousValue
 * @param _value initial value to set
 */
Parameter::Parameter(const std::string &_name, const range &_ValidRange, const Vector &_value) :
  ParameterInterface(_name),
  value(_ValidRange)
{
  value.set(_value);
};
/** Destructor for class Parameter.
 *
 */
Parameter::~Parameter()
{};
/** Catch call to value.isValidAsString() to add exception information.
 *
 * @param _value value to set to
 */
bool Parameter::isValidAsString(const std::string &_value) const throw(ParameterValidatorException)
{
  try {
    return value.isValidAsString(_value);
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.getAsString() to add exception information.
 *
 * @return parameter value as string
 */
const std::string Parameter::getAsString() const throw(ParameterValueException)
{
  try {
    return value.getAsString();
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.getAsStringUnvalidated() to add exception information.
 *
 * @return parameter value as string
 */
const std::string Parameter::getAsStringUnvalidated() const throw(ParameterValueException)
{
  try {
    return value.getAsStringUnvalidated();
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.isValid() to add exception information.
 *
 * @return parameter value as string
 */
bool Parameter::isValid(const Vector &_value) const throw(ParameterValidatorException)
{
  try {
    return value.isValid(_value);
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.getUnvalidated() to add exception information.
 *
 * @return parameter value as string
 */
const Vector & Parameter::getUnvalidated() const throw(ParameterValueException)
{
  try {
    return value.getUnvalidated();
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.get() to add exception information.
 *
 * @return parameter value as string
 */
const Vector & Parameter::get() const throw(ParameterValueException)
{
  try {
    return value.get();
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.set() to add exception information.
 *
 * @param _value value to set to
 */
void Parameter::set(const Vector & _value) throw(ParameterValueException)
{
  try {
    value.set(_value);
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Catch call to value.set() to add exception information.
 *
 * @param _value value to set to
 */
void Parameter::setAsString(const std::string &_value) throw(ParameterValueException)
{
  try {
    value.setAsString(_value);
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
}
/** Compares this continuous value against another \a _instance.
 *
 * @param _instance other value to compare to
 * @return true - if contained ContinuousValue and name are the same, false - else
 */
bool Parameter::operator==(const Parameter &_instance) const throw(ParameterException)
{
  bool status = true;
  try {
    status = status &&
        (getUnvalidated() == _instance.getUnvalidated());
    status = status && (ParameterInterface::getName() == _instance.ParameterInterface::getName());
  } catch(ParameterException &e) {
    e << ParameterName(ParameterInterface::getName());
    throw;
  }
  return status;
}
/** Creates a clone of this Parameter instance.
 *
 * @return cloned instance
 */
ParameterInterface* Parameter::clone() const
{
  Parameter *instance = new Parameter(ParameterInterface::getName(), value.getValidator());
  // do not use get, we do not check for validity here
  if (value.isSet())
    instance->setAsString(value.getAsStringUnvalidated());
  return instance;
}