// src/backend/policy_parameters.cc - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This 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.
//
// SGPEMv2 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 SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#include <sgpemv2/policy_parameters.hh>
#include <sgpemv2/templates/parameter.tcc>

using namespace std;
using namespace sgpem;
using Glib::ustring;


// instantiate Parameter template for use outside this DSO
namespace sgpem {
    template class SG_DLLEXPORT PolicyParameters::Parameter<int>;
    template class SG_DLLEXPORT PolicyParameters::Parameter<float>;
    template class SG_DLLEXPORT PolicyParameters::Parameter<Glib::ustring>;
}


/**
 Register a new parameter of type integer.
 If there is a parameter with the same name and type it will be overwritten.
*/
void
PolicyParameters::register_int(Glib::ustring name, const int& lower_bound, const int& upper_bound, const bool& required, const int& default_value)
{
  //there is a parameter with the same name!!
  map<ustring, Parameter<int> >::iterator i = int_map.find(name);
  if (i != int_map.end())
    int_map.erase(i);

  map<ustring, Parameter<int> >::value_type v(name, Parameter<int>(name, default_value, lower_bound, upper_bound, required, default_value));
  int_map.insert(v);

}

/**
 Register a new parameter of type float.
 If there is a parameter with the same name and type it will be overwritten.
 */
void
PolicyParameters::register_float(Glib::ustring name, const float& lower_bound, const float& upper_bound, const bool& required, const float& default_value)
{
  //there is a parameter with the same name!!
  map<ustring, Parameter<float> >::iterator i = float_map.find(name);
  if (i != float_map.end())
    float_map.erase(i);

  map<ustring, Parameter<float> >::value_type v(name, Parameter<float>(name, default_value, lower_bound, upper_bound, required, default_value));
  float_map.insert(v);
}

/**
 Register a new parameter of type string.
 If there is a parameter with the same name and type it will be overwritten.
 */
void
PolicyParameters::register_string(Glib::ustring name, const bool& required, const Glib::ustring& default_value)
{
  //there is a parameter with the same name!!
  map<ustring, Parameter<Glib::ustring> >::iterator i = string_map.find(name);
  if (i != string_map.end())
    string_map.erase(i);

  map<ustring, Parameter<Glib::ustring> >::value_type v(name, Parameter<Glib::ustring>(name, default_value, "", "", required, default_value));
  string_map.insert(v);
}

/**
 Deletes all registred parameters.
*/

void
PolicyParameters::clear()
{
  int_map.clear();
  float_map.clear();
  string_map.clear();
}

/**
 Retruns a copy of the map containing all registered integer parameters.
*/
map<ustring, PolicyParameters::Parameter<int> >
PolicyParameters::get_registered_int_parameters() const
{
  return int_map;
}

/**
 Retruns a copy of the map containing all registered float parameters.
 */
map<ustring, PolicyParameters::Parameter<float> >
PolicyParameters::get_registered_float_parameters() const
{
  return float_map;
}

/**
 Retruns a copy of the map containing all registered string parameters.
 */
map<ustring, PolicyParameters::Parameter<ustring> >
PolicyParameters::get_registered_string_parameters() const
{
  return string_map;
}

/**
 Tries to set the value to the parameter named "name".
 \returns TRUE if the parameter named "name" has been previously registered and the value
 stays in the range permitted by the parameter.
 \returns FALSE in the other cases.
*/
bool
PolicyParameters::set_int(ustring name, const int& value)
{
  map<ustring, Parameter<int> >::iterator i = int_map.find(name);
  if (i == int_map.end())
    //the parameter doesn't exist!!
    return false;

  if (value < i->second.get_lower_bound() || value > i->second.get_upper_bound())
    return false;

  i->second.set_value(value);
  return true;
}


/**
 Tries to set the value to the parameter named "name".
 \returns TRUE if the parameter named "name" has been previously registered and the value
 stays in the range permitted by the parameter.
 \returns FALSE in the other cases.
 */
bool
PolicyParameters::set_float(ustring name, const float& value)
{
  map<ustring, Parameter<float> >::iterator i = float_map.find(name);
  if (i == float_map.end())
    //the parameter doesn't exist!!
    return false;

  if (value < i->second.get_lower_bound() || value > i->second.get_upper_bound())
    return false;

  i->second.set_value(value);
  return true;
}

/**
 Tries to set the value to the parameter named "name". For the type "string" there are
 no upper/lower bound limitations.
 \returns TRUE if the parameter named "name" has been previously registered.
 \returns FALSE in the other case.
 */
bool
PolicyParameters::set_string(ustring name, const ustring& value)
{
  map<ustring, Parameter<ustring> >::iterator i = string_map.find(name);
  if (i == string_map.end())
    //the parameter doesn't exist!!
    return false;

  i->second.set_value(value);
  return true;
}

/**
 Looks for a parameter of integer type named "name".
 \returns The value of the parameter
 \throws A PolicyParametersException if the parameter has not been found.
 */
int
PolicyParameters::get_int(ustring name) const
{
  map<ustring, Parameter<int> >::const_iterator i = int_map.find(name);
  if (i == int_map.end())
    throw PolicyParametersException("Unregistred parameter");
  else
    return i->second.get_value();
}


/**
 Looks for a parameter of float type named "name".
 \returns The value of the parameter
 \throws A PolicyParametersException if the parameter has not been found.
 */
float
PolicyParameters::get_float(ustring name) const
{
  map<ustring, Parameter<float> >::const_iterator i = float_map.find(name);
  if (i == float_map.end())
    throw PolicyParametersException("Unregistred parameter");
  else
    return i->second.get_value();
}


/**
 Looks for a parameter of string type named "name".
 \returns The value of the parameter
 \throws A PolicyParametersException if the parameter has not been found.
 */
ustring
PolicyParameters::get_string(ustring name) const
{
  map<ustring, Parameter<ustring> >::const_iterator i = string_map.find(name);
  if (i == string_map.end())
    throw PolicyParametersException("Unregistred parameter");
  else
    return i->second.get_value();
}

