/******************************************************************************
* NOMAD -  Nonlinear Optimization for Mixed vAriables and Derivatives.        *
* Copyright (C) 2001-2004  Gilles Couture - Ecole Polytechnique,              *
*                          Charles Audet - Ecole Polytechnique,               *
*		           John Dennis - Rice University.                     *
*                                                                             *
* Author: Gilles Couture                                                      *
* École Polytechnique de Montréal - GERAD                                     *
* C.P. 6079, Succ. Centre-ville, Montréal (Québec) H3C 3A7 Canada             *
* Tel:  (514) 340-6053 x6928                                                  *
* Email: Gilles.Couture@gerad.ca                                              *
* Fax: (514) 340-5665                                                         *
*                                                                             *
* This program 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. You can find the              *
* GNU General Public License at:                                              *
*             http://www.gnu.org/copyleft/gpl.html                            *
*                                                                             *
* This program 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 this program; if not, write to the Free Software                 *
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *
*                                                                             *
* You can find information on the NOMAD software at:                          *
*             http://www.gerad.ca/NOMAD/                                      *
******************************************************************************/

// parameterwindow.cpp -- class methods for ParameterWindow.

#include <fstream>
#include <iostream>
#include <QCheckBox>
#include <QComboBox>
#include <QFileDialog>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMessageBox>
#include <QValidator>
using namespace std;
#include "parameters.h"
#include "parameterwindow.h"

// Private methods:
// ----------------

// This method checks that the parameters window is properly displayed.
void ParameterWindow::checkDisplay(const bool surr_use, const int gen_cons_nb)
{
  // This method 
  bool gen_cons_use = (gen_cons_nb > 0) ? true : false;
  progressive_barrier_box->setChecked(gen_cons_use);
  progressiveBarrierBoxEvent(gen_cons_use);
  initialChanged(initial->currentIndex());
  iterativeChanged(iterative->currentIndex());
  pollDirsChanged(poll_dirs->currentIndex());
  surrogate_box->setChecked(surr_use);
  surrogateBoxEvent(surr_use);
}

// Public methods:
// ---------------

// Class constructor.
ParameterWindow::ParameterWindow(QWidget * parent, const bool surr_use,
				 const int gen_cons_nb, const char * file)
  : QWidget(parent)
{
  // A 1x1 grid is created. Its parent is "this" object (ParametersWindow).
  QGridLayout * grid = new QGridLayout(this);

  /*******************/
  /* Mesh parameters */
  /*******************/

  QGroupBox * mesh_box = new QGroupBox("Mesh parameters", this);
  // mesh_box->setPaletteBackgroundColor(Qt::gray);
  mesh_box->setBackgroundRole(QPalette::Background);
  mesh_box->setAlignment(Qt::AlignHCenter);
  mesh_box->setFlat(true);
  mesh_box->setMinimumHeight(20);
  mesh_box->setMaximumHeight(20);
  // grid->addMultiCellWidget(mesh_box, 0, 0, 0, 3);
  grid->addWidget(mesh_box, 0, 0, 1, 4);

  // We put some objects on the grid: Second row.
  grid->addWidget(new QLabel("Initial poll\nsize", this), 1, 0);
  poll_size = new QLineEdit("1.0", this);
  poll_size->setValidator(new QDoubleValidator(0.0, 1000.0, 16, poll_size));
  grid->addWidget(poll_size, 1, 1);
  grid->addWidget(new QLabel("Coarsening\nexponent", this), 1, 2);
  coarsen = new QLineEdit("1", this);
  coarsen->setValidator(new QIntValidator(1, 10, coarsen));
  grid->addWidget(coarsen, 1, 3);

  // Third row.
  grid->addWidget(new QLabel("Poll size\nbasis", this), 2, 0);
  poll_basis = new QLineEdit("2.0", this);
  poll_basis->setValidator(new QDoubleValidator(1.0, 100.0, 16, poll_basis));
  grid->addWidget(poll_basis, 2, 1);
  grid->addWidget(new QLabel("Refining\nexponent", this), 2, 2);
  refine = new QLineEdit("-1", this);
  refine->setValidator(new QIntValidator(-10, -1, refine));
  grid->addWidget(refine, 2, 3);

  // Fourth row.
  grid->addWidget(new QLabel("Maximum poll\nsize", this), 3, 0);
  max_poll_size = new QLineEdit("100000", this);
  grid->addWidget(max_poll_size, 3, 1);
	grid->addWidget(new QLabel("Random seed:", this), 3, 2);
  random_seed = new QLineEdit("1", this);
  random_seed->setValidator(new QIntValidator(0, 1000, random_seed));
  grid->addWidget(random_seed, 3, 3);

  /*******************/
  /* Poll parameters */
  /*******************/

  QGroupBox * poll_box = new QGroupBox("Poll parameters", this);
  // poll_box->setPaletteBackgroundColor(Qt::gray);
  poll_box->setBackgroundRole(QPalette::Background);
  poll_box->setAlignment(Qt::AlignHCenter);
  poll_box->setFlat(true);
  poll_box->setMinimumHeight(20);
  poll_box->setMaximumHeight(20);
  // grid->addMultiCellWidget(poll_box, 4, 4, 0, 3);
  grid->addWidget(poll_box, 4, 0, 1, 4);

  // 6th row.
  grid->addWidget(new QLabel("Order", this), 5, 0);
  poll_order = new QComboBox(this);
  poll_order->addItem("Dynamic");
  poll_order->addItem("Fixed");
  grid->addWidget(poll_order, 5, 1);
  grid->addWidget(new QLabel("Type", this), 5, 2);
  poll_type = new QComboBox(this);
  poll_type->addItem("Opportunistic");
  poll_type->addItem("Complete");
  grid->addWidget(poll_type, 5, 3);

  // 7th row.
  grid->addWidget(new QLabel("Primay\ndirections", this), 6, 0);
  poll_dirs = new QComboBox(this);
  poll_dirs->addItem("GPS - 2*n");
  poll_dirs->addItem("GPS - n+1");
  poll_dirs->addItem("GPS - uniform");
  poll_dirs->addItem("MADS - 2*n");
  poll_dirs->addItem("MADS - n+1");
  grid->addWidget(poll_dirs, 6, 1);
  grid->addWidget(new QLabel("Secondary\ndirections", this), 6, 2);
  sec_poll_dirs = new QComboBox(this);
  sec_poll_dirs->addItem("0");
  sec_poll_dirs->addItem("1");
  sec_poll_dirs->addItem("2");
  grid->addWidget(sec_poll_dirs, 6, 3);

  /*********************/
  /* Search parameters */
  /*********************/

  QGroupBox * search_box = new QGroupBox("Search parameters", this);
  // search_box->setPaletteBackgroundColor(Qt::gray);
  search_box->setBackgroundRole(QPalette::Background);
  search_box->setAlignment(Qt::AlignHCenter);
  search_box->setFlat(true);
  search_box->setMinimumHeight(20);
  search_box->setMaximumHeight(20);
  // grid->addMultiCellWidget(search_box, 7, 7, 0, 3);
  grid->addWidget(search_box, 7, 0, 1, 4);

  // 9th row.
  grid->addWidget(new QLabel("Initial search", this), 8, 0);
  initial = new QComboBox(this);
  initial->addItem("No search");
  initial->addItem("Random");
  initial->addItem("Latin hypercube");
  grid->addWidget(initial, 8, 1);
  // The 'initial' combo box is connected to the 'initialChanged(...)' slot.
  connect(initial, SIGNAL(activated(int)), this, SLOT(initialChanged(int)));
  grid->addWidget(new QLabel("Iterative search", this), 8, 2);
  iterative = new QComboBox(this);
  iterative->addItem("No search");
  iterative->addItem("Random");
  iterative->addItem("Latin hypercube");
  grid->addWidget(iterative, 8, 3);
  // The 'iterative' combo box is connected to the 'iterativeChanged(...)'
  // slot.
  connect(iterative, SIGNAL(activated(int)),
	  this, SLOT(iterativeChanged(int)));

  // 10th row.
  grid->addWidget(new QLabel("Initial type", this), 9, 0);
  init_complete = new QComboBox(this);
  init_complete->addItem("Opportunistic");
  init_complete->addItem("Complete");
  grid->addWidget(init_complete, 9, 1);
  grid->addWidget(new QLabel("Iterative type", this), 9, 2);
  iter_complete = new QComboBox(this);
  iter_complete->addItem("Opportunistic");
  iter_complete->addItem("Complete");
  grid->addWidget(iter_complete, 9, 3);

  // 11th row.
  grid->addWidget(new QLabel("Initial points", this), 10, 0);
  initial_pts = new QLineEdit("0", this);
  initial_pts->setValidator(new QIntValidator(initial_pts));
  grid->addWidget(initial_pts, 10, 1);
  grid->addWidget(new QLabel("Iterative points", this), 10, 2);
  iterative_pts = new QLineEdit("0", this);
  iterative_pts->setValidator(new QIntValidator(0, 1000, iterative_pts));
  grid->addWidget(iterative_pts, 10, 3);

  // 12th row.
  speculative_label = new QLabel("Speculative search", this);
  grid->addWidget(speculative_label, 11, 2);
  // This checkbox holds the boolean variable for MADS dynamic search.
  speculative = new QCheckBox("(MADS)", this);
  grid->addWidget(speculative, 11, 3);
  // This method is called whenever the 'poll_dirs' combo box is modified.
  connect(poll_dirs, SIGNAL(activated(int)), this, SLOT(pollDirsChanged(int)));

  /**************************/
  /* Termination parameters */
  /**************************/

  QGroupBox * terminator_box = new QGroupBox("Termination parameters", this);
  // terminator_box->setPaletteBackgroundColor(Qt::gray);
  terminator_box->setBackgroundRole(QPalette::Background);
  terminator_box->setAlignment(Qt::AlignHCenter);
  terminator_box->setFlat(true);
  terminator_box->setMinimumHeight(20);
  terminator_box->setMaximumHeight(20);
  // grid->addMultiCellWidget(terminator_box, 12, 12, 0, 3);
  grid->addWidget(terminator_box, 12, 0, 1, 4);

  // 14th row.
  grid->addWidget(new QLabel("Poll size", this), 13, 0);
  ps_term = new QLineEdit("0", this);
  ps_term->setValidator(new QDoubleValidator(-1.0, 1000.0, 16, ps_term));
  grid->addWidget(ps_term, 13, 1);
  grid->addWidget(new QLabel("Iteration\nnumber", this), 13, 2);
  iter_term = new QLineEdit("0", this);
  iter_term->setValidator(new QIntValidator(-1, 1000000, iter_term));
  grid->addWidget(iter_term, 13, 3);

  // 15th row.
  grid->addWidget(new QLabel("Truth\nevaluations", this), 14, 0);
  te_term = new QLineEdit("50", this);
  te_term->setValidator(new QIntValidator(-1, 1000000, te_term));
  grid->addWidget(te_term, 14, 1);
  grid->addWidget(new QLabel("New truth\nevaluations", this), 14, 2);
  nt_term = new QLineEdit("0", this);
  nt_term->setValidator(new QIntValidator(-1, 1000000, nt_term));
  grid->addWidget(nt_term, 14, 3);

  // 16th row.
  grid->addWidget(new QLabel("Consecutive\nfailures", this), 15, 0);
  li_term = new QLineEdit("0", this);
  li_term->setValidator(new QIntValidator(-1, 10000, li_term));
  grid->addWidget(li_term, 15, 1);

  /**********************************/
  /* Progressive barrier parameters */
  /**********************************/

  progressive_barrier_box = new QGroupBox("Progressive Barrier", this);
  // progressive_barrier_box->setPaletteBackgroundColor(Qt::gray);
  progressive_barrier_box->setBackgroundRole(QPalette::Background);
  progressive_barrier_box->setAlignment(Qt::AlignHCenter);
  progressive_barrier_box->setFlat(true);
  progressive_barrier_box->setMinimumHeight(20);
  progressive_barrier_box->setMaximumHeight(20);
  progressive_barrier_box->setCheckable(true);
  // grid->addMultiCellWidget(progressive_barrier_box, 16, 16, 0, 3);
  grid->addWidget(progressive_barrier_box, 16, 0, 1, 4);
  // The check box is connected to 'progressiveBarrierBoxEvent()'.
  connect(progressive_barrier_box, SIGNAL(toggled(bool)), this, SLOT(progressiveBarrierBoxEvent(bool)));

  // 18th row.
  grid->addWidget(new QLabel("h max", this), 17, 0);
  hmax_relative = new QComboBox(this);
  hmax_relative->addItem("Fixed");
  hmax_relative->addItem("Relative");
  grid->addWidget(hmax_relative, 17, 1);
  grid->addWidget(new QLabel("h max value", this), 17, 2);
  hmax = new QLineEdit("100.0", this);
  hmax->setValidator(new QDoubleValidator(0.0, 1000000.0, 16, hmax));
  grid->addWidget(hmax, 17, 3);

  // 19th row.
  grid->addWidget(new QLabel("h norm", this), 18, 0);
  filter_norm = new QComboBox(this);
  filter_norm->addItem("L-Infinity");
  filter_norm->addItem("L-1");
  filter_norm->addItem("L-2 squared");
  filter_norm->setCurrentIndex(2);
  grid->addWidget(filter_norm, 18, 1);
  grid->addWidget(new QLabel("h min", this), 18, 2);
  hmin = new QLineEdit("0.0001", this);
  hmin->setValidator(new QDoubleValidator(0.000001, 0.1, 16, hmin));
  grid->addWidget(hmin, 18, 3);
	
  // 20th row.
  grid->addWidget(new QLabel("Frame center\ntrigger", this), 19, 0);
  fs_trigger = new QLineEdit("0.1", this);
  fs_trigger->setValidator(new QDoubleValidator(0.0, 1000000.0, 16, fs_trigger));
  grid->addWidget(fs_trigger, 19, 1);

  /************************/
  /* Surrogate parameters */
  /************************/

  surrogate_box = new QGroupBox("Surrogate parameters", this);
  // surrogate_box->setPaletteBackgroundColor(Qt::gray);
  surrogate_box->setBackgroundRole(QPalette::Background);
  surrogate_box->setAlignment(Qt::AlignHCenter);
  surrogate_box->setFlat(true);
  surrogate_box->setMinimumHeight(20);
  surrogate_box->setMaximumHeight(20);
  surrogate_box->setCheckable(true);
  // grid->addMultiCellWidget(surrogate_box, 19, 19, 0, 3);
  grid->addWidget(surrogate_box, 20, 0, 1, 4);
  // The check box is connected to 'surrogateBoxEvent()'.
  connect(surrogate_box, SIGNAL(toggled(bool)),
	  this, SLOT(surrogateBoxEvent(bool)));

  // 22nd row.
  grid->addWidget(new QLabel("Surrogate\ntolerance", this), 21, 0);
  surr_tol = new QLineEdit("5.0", this);
  surr_tol->setValidator(new QDoubleValidator(1.0, 1000.0, 16, surr_tol));
  grid->addWidget(surr_tol, 21, 1);

  // The Parameters object is created.
  parameters = new Parameters(file);
  if (file != NULL)
    // If the file is defined the parameters are loaded.
    load(surr_use, gen_cons_nb);
  else
    // This method will make sure that the window is displayed properly.
    checkDisplay(surr_use, gen_cons_nb);

  // We tell the application to resize itself.
  resize(minimumSizeHint());
}

// Destructor.
ParameterWindow::~ParameterWindow()
{
  // The Parameters object is destroyed.
  delete parameters;
}

// This method returns 'true' if no text editor is empty. The 'Save' and
// 'Save as' items in the menu bar (of the 'MainApplication' object) will be
// enabled or disabled accordingly.
bool ParameterWindow::enable()
{
  // 'True' is returned if no text editor is empty.
  if (!coarsen->text().isEmpty() &&
      !max_poll_size->text().isEmpty() &&
      !poll_basis->text().isEmpty() &&
      !poll_size->text().isEmpty() &&
      !refine->text().isEmpty() &&
      !random_seed->text().isEmpty() &&
      !initial_pts->text().isEmpty() &&
      !iterative_pts->text().isEmpty() &&
      !iter_term->text().isEmpty() &&
      !li_term->text().isEmpty() &&
      !nt_term->text().isEmpty() &&
      !ps_term->text().isEmpty() &&
      !te_term->text().isEmpty() &&
      !hmax->text().isEmpty() &&
      !hmin->text().isEmpty() &&
			!fs_trigger->text().isEmpty() &&
      !surr_tol->text().isEmpty())
    return true;
  else
    return false;
}

// This method relays the 'readyToSolve()' call to Parameters.
bool ParameterWindow::readyToSolve()
{
  return parameters->readyToSolve();
}

// This method returns a pointer to 'Parameters'.
Parameters * ParameterWindow::getParametersPtr()
{
  return parameters->getPtr();
}

// This method shows the parameters on the window.
void ParameterWindow::load(const bool surr_use, const int gen_cons_nb,
			   const char * file)
{
  // The user might want to load a new parameters file.
  if (file != 0)
    parameters->load(file);
  QString temp;
  // The mesh parameters are loaded.
  temp = temp.setNum(parameters->getCoarsen());
  coarsen->setText(temp);
  temp = temp.setNum(parameters->getPollBasis());
  poll_basis->setText(temp);
  temp = temp.setNum(parameters->getPollSize());
  poll_size->setText(temp);
  temp = temp.setNum(parameters->getMaxPollSize());
  max_poll_size->setText(temp);
  temp = temp.setNum(parameters->getRefine());
  refine->setText(temp);
  // The poll parameters are loaded.
  poll_dirs->setCurrentIndex(parameters->getPollDirs());
  poll_order->setCurrentIndex(parameters->getPollOrder());
  poll_type->setCurrentIndex(parameters->getPollType());
	sec_poll_dirs->setCurrentIndex(parameters->getSecondaryPollDirs());
  // The random seed is loaded.
  temp = temp.setNum(parameters->getSeed());
  random_seed->setText(temp);
  // The search parameters are loaded.
  initial->setCurrentIndex(parameters->getInitialSearch());
  init_complete->setCurrentIndex(parameters->getInitialComplete());
  iterative->setCurrentIndex(parameters->getIterativeSearch());
  iter_complete->setCurrentIndex(parameters->getIterativeComplete());
  temp = temp.setNum(parameters->getInitialPoints());
  initial_pts->setText(temp);
  temp = temp.setNum(parameters->getIterativePoints());
  iterative_pts->setText(temp);
  speculative->setChecked(parameters->getSpeculativeSearch());
  // The termination parameters are loaded.
  temp = temp.setNum(parameters->getTruthEvals());
  te_term->setText(temp);
  temp = temp.setNum(parameters->getMaxIterations());
  iter_term->setText(temp);
  temp = temp.setNum(parameters->getConsecutiveFails());
  li_term->setText(temp);
  temp = temp.setNum(parameters->getPollSizeTerm());
  ps_term->setText(temp);
  temp = temp.setNum(parameters->getNewTruthEvals());
  nt_term->setText(temp);
  // The progressive barrier parameters are loaded.
  filter_norm->setCurrentIndex(parameters->getFilterNorm());
  hmax_relative->setCurrentIndex(parameters->getFilterRelative());
  temp = temp.setNum(parameters->getHmax());
  hmax->setText(temp);
  temp = temp.setNum(parameters->getHmin());
  hmin->setText(temp);
	temp = temp.setNum(parameters->getFrameCenterTrigger());
	fs_trigger->setText(temp);
  // The surrogate parameters are loaded.
  temp = temp.setNum(parameters->getSurrogateTolerance());
  surr_tol->setText(temp);

  // This method will make sure that the window is displayed properly.
  checkDisplay(surr_use, gen_cons_nb);
}

// This method resets all parameters to default values.
void ParameterWindow::reset()
{
  // The mesh parameters are reset.
  coarsen->setText("1");
  max_poll_size->setText("100000");
  poll_basis->setText("2");
  poll_size->setText("1");
  refine->setText("-1");

  // The poll parameters are reset
  poll_order->setCurrentIndex(0);
  poll_type->setCurrentIndex(0);
  poll_dirs->setCurrentIndex(0);
	sec_poll_dirs->setCurrentIndex(0);

  // The search parameters are reset.
  initial->setCurrentIndex(0);
  iterative->setCurrentIndex(0);
  // These signals will take care of the other search variables.
  initialChanged(0);
  iterativeChanged(0);
  pollDirsChanged(0);

  // The termination parameters are reset.
  te_term->setText("50");
  iter_term->setText("0");
  li_term->setText("0");
  ps_term->setText("1e-4");
  nt_term->setText("0");

  // The progressive barrier parameters are reset if necessary.
  if (progressive_barrier_box->isChecked())
    {
      hmax_relative->setCurrentIndex(0);
      filter_norm->setCurrentIndex(2);
      hmax->setText("5.0");
      hmin->setText("0.0001");
			fs_trigger->setText("0.1");
    }

  // The surrogate parameters are reset if necessary.
  if (surrogate_box->isChecked())
    surr_tol->setText("5.0");
}

// This method gathers the parameters from the GUI, and sends them to the
// Parameters object.
void ParameterWindow::save()
{
  // The 'Parameters' object gives us the path of the parameters file.
  char * parameters_file = parameters->getFile();
  // If the string is null, we don't know where to save the parameters: we call
  // 'saveAs()'.
  if (parameters_file == NULL)
    {
      saveAs();
      return;
    }
  // The window's contents are sent to Parameters.
  sendParameters();
  // The parameters are saved: they're written to file.
  parameters->write();
}

// This method lets the user choose a file where the parameters will be saved.
void ParameterWindow::saveAs()
{
  // The path is chosen in this file dialog.
  QString fn = QFileDialog::getSaveFileName(this);
  // If the user chose a file...
  if (!fn.isEmpty())
    {
      const char * parameters_file = fn.toLatin1();
      setWindowTitle(parameters_file);
      // ... it is sent to 'Parameters'.
      parameters->setFile(parameters_file);
      // This function saves the data.
      save();
    }
}

// The text editor's data is gathered and sent to 'Parameters'.
void ParameterWindow::sendParameters()
{
  parameters->enterProgressiveBarrier(hmax_relative->currentIndex(),
	     hmax->text().toDouble(), hmin->text().toDouble(),
			 fs_trigger->text().toDouble(), filter_norm->currentIndex());
  parameters->enterMesh(poll_size->text().toDouble(),
			poll_basis->text().toDouble(),
			max_poll_size->text().toDouble(),
			coarsen->text().toInt(), refine->text().toInt());
  parameters->enterPoll(poll_order->currentIndex(), poll_type->currentIndex(),
			poll_dirs->currentIndex(), sec_poll_dirs->currentIndex());
  parameters->enterRandomSeed(random_seed->text().toInt());
  parameters->enterSearch(initial->currentIndex(),
			  init_complete->currentIndex(),
			  initial_pts->text().toInt(),
			  iterative->currentIndex(),
			  iter_complete->currentIndex(),
			  iterative_pts->text().toInt(),
			  speculative->isChecked());
  parameters->enterSurrogate(surr_tol->text().toDouble());
  parameters->enterTerminationCriteria(ps_term->text().toDouble(),
				       li_term->text().toInt(),
				       te_term->text().toInt(),
				       iter_term->text().toInt(),
				       nt_term->text().toInt());
}

// The message is forwarded to 'Parameters'.
void ParameterWindow::showParameters(ostream & fout)
{
  parameters->show(fout, progressive_barrier_box->isChecked(), surrogate_box->isChecked());
}

// Private slots.
// --------------

// This method is called whenever the user changes the 'initial' combo box.
void ParameterWindow::initialChanged(int index)
{
  // If 'index' is equal to zero there's no initial search.
  bool initial_search = (index == 0) ? false : true;
  // If there's no initial search, these parameters are reset.
  if (initial_search == false)
    {
      init_complete->setCurrentIndex(0);
      initial_pts->setText("0");
    }
  // These widgets are enabled if there's an initial serach, disabled
  // otherwise.
  init_complete->setEnabled(initial_search);
  initial_pts->setEnabled(initial_search);
}

// This method is called whenever the user changes the 'iterative' combo box.
void ParameterWindow::iterativeChanged(int index)
{
  // If 'index' is equal to zero there's no iterative search.
  bool iterative_search = (index == 0) ? false : true;
  // If there's no iterative search, these parameters are reset.
  if (iterative_search == false)
    {
      iter_complete->setCurrentIndex(0);
      iterative_pts->setText("0");
    }
  // These widgets are enabled if there's an iterative serach, disabled
  // otherwise.
  iter_complete->setEnabled(iterative_search);
  iterative_pts->setEnabled(iterative_search);
}

// This method is called whenever the user makes a change to the poll
// directions' combo box.
void ParameterWindow::pollDirsChanged(int index)
{
  // If 'index' is greater than two, the user chose MADS poll directions: the
  // speculative search is enabled. If it's not greater than two, the user
  // chose GPS poll directions and the speculative search is disabled.
  bool mads_directions = (index > 2) ? true : false;
  speculative_label->setEnabled(mads_directions);
  speculative->setEnabled(mads_directions);
  // If we have GPS directions this makes sure that the speculative search
  // option is unchecked.
  if (mads_directions == false)
    speculative->setChecked(false);
}

// This method enables or disables widgets related to the Progressive Barrier group box,
// according to 'checked'.
void ParameterWindow::progressiveBarrierBoxEvent(bool checked)
{
  hmax_relative->setEnabled(checked);
  filter_norm->setEnabled(checked);
  // If the progressibe barrier is used, the default values are restored.
  if (checked == true)
    {
      if (hmin->text().toDouble() == 0.0)
	hmin->setText("0.0001");
      if (hmax->text().toDouble() == 0.0)
	hmax->setText("100.0");
      if (sec_poll_dirs->currentIndex() == 0)
	sec_poll_dirs->setCurrentIndex(1);
    }
  else   // These variables are set to zero to show that they're not used.
    {
      hmin->setText("0");
      hmax->setText("0");
      sec_poll_dirs->setCurrentIndex(0);
    }
  hmin->setEnabled(checked);
  hmax->setEnabled(checked);
  fs_trigger->setEnabled(checked);
  // Secondary directions are only used with the progressive barrier.
  sec_poll_dirs->setEnabled(checked);
}

// This method enables or disables widgets related to the Surrogate group box,
// according to 'checked'.
void ParameterWindow::surrogateBoxEvent(bool checked)
{
  surr_tol->setEnabled(checked);
}
