/*-------------------------------------------------------------------------------------*/
/*  NOMAD - Nonsmooth Optimization by Mesh Adaptive Direct search - version 3.0.0      */
/*                                                                                     */
/*  Copyright (C) 2001-2008  Mark Abramson        - the Boeing Company, Seattle        */
/*                           Charles Audet        - Ecole Polytechnique, Montreal      */
/*                           Gilles Couture       - Ecole Polytechnique, Montreal      */
/*                           John Dennis          - Rice University, Houston           */
/*                           Sebastien Le Digabel - Ecole Polytechnique, Montreal      */
/*                                                                                     */
/*  funded in part by AFOSR and Exxon Mobil                                            */
/*                                                                                     */
/*  Author: Sebastien Le Digabel                                                       */
/*                                                                                     */
/*  Contact information:                                                               */
/*    Ecole Polytechnique de Montreal - GERAD                                          */
/*    C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada                  */
/*    e-mail: Sebastien.Le.Digabel@gerad.ca                                            */
/*    phone : 1-514-340-6053 #6673                                                     */
/*    fax   : 1-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, either version 3 of the License, or (at your option) any later         */
/*  version.                                                                           */
/*                                                                                     */
/*  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, see <http://www.gnu.org/licenses/>.                               */
/*                                                                                     */
/*  You can find information on the NOMAD software at www.gerad.ca/nomad               */
/*-------------------------------------------------------------------------------------*/
#ifndef __EVALUATOR_CONTROL__
#define __EVALUATOR_CONTROL__

#include "Phase_One_Evaluator.hpp"
#include "Barrier.hpp"
#include "Stats.hpp"
#include "Priority_Eval_Point.hpp"

class Evaluator_Control : private Uncopyable {

private:

  static bool        _force_quit;    // forces NOMAD to terminate if ctrl-c is pressed

  const Parameters & _p;             // parameters

  Evaluator        * _ev;            // the evaluator
  bool               _delete_ev;     // flag if the dtor has to delete _ev

  Cache              _cache;         // cache
  Cache              _sgte_cache;    // cache for surrogates

  Stats            & _stats;         // algo. stats

  std::ostream     & _out;           // display

  // process an already evaluated Eval_Point:
  success_type process_eval_point ( const Eval_Point & x ,
				    Barrier          & b   ) const;

  // save the solution file or update the history file:
  void write_sol_or_his_file ( const string     & file_name      ,
			       const Eval_Point & x              ,
			       int                display_degree ,
			       bool               is_sol           ) const;

  // display evaluation result:
  void display_eval_result ( const Eval_Point & x                ,
			     int                display_degree   ,
			     search_type        search           ,
			     success_type       one_eval_success ,
			     success_type       success            ) const;

  // check the opportunistic strategy stopping criteria:
  bool check_opportunistic_criteria ( int                   display_degree   ,
				      success_type          one_eval_success ,
				      int                   init_nb_eval     ,
				      const NOMAD::Double & f0               ,
				      const Barrier       * barrier          ,
				      int                 & nb_success       ,
				      bool                & one_for_luck       );

  // count the output stats (STAT_SUM and STAT_AVG):
  void count_output_stats ( const Eval_Point & x );

public:

  // constructor:
  Evaluator_Control ( const Parameters & p     ,
		      Stats            & stats ,
		      Evaluator        * ev    , // can be NULL
		      std::ostream     & out     );

  // destructor:
  ~Evaluator_Control ( void );

  // force quit (called by pressing ctrl-c):
  static void force_quit ( void ) { Evaluator_Control::_force_quit = true; }

  // file displays for parameter STATS_FILE:
  void stats_file ( const string        & file_name ,
		    const NOMAD::Double & f         ,
		    const NOMAD::Double & h         ,
		    const Point         * sol       ,
		    const Point         * bbo         ) const;

  // display stats during Mads::run() for minimal and normal display:
  void display_stats ( bool                            header ,
		       ostream                       & out    ,
		       const std::list<std::string>  & stats  ,
		       const NOMAD::Double           & f      ,          // can be undefined
		       const NOMAD::Double           & h      ,          // can be undefined
		       const Point                   * sol    ,          // can be NULL
		       const Point                   * bbo      ) const; // can be NULL

  // display a point with DISPLAY_STATS:
  void display_stats_point ( ostream                      & out           ,
			     const list<string>           & display_stats ,
			     list<string>::const_iterator & it            ,
			     const Point                  * x               ) const;

  // save the caches:
  bool save_caches ( bool overwrite );

  // GET methods:
  Cache       & get_cache     ( void )       { return _cache; }
  const Cache & get_cache     ( void ) const { return _cache; }
  Evaluator   * get_evaluator ( void ) const { return _ev;    }
  
  // SET methods:
  void set_evaluator ( Evaluator * ev ) { _ev = ev; }

  // eval_list_of_points (eval_lop):
  // -------------------------------
  //   . evaluate a list of points
  //   . the list 'points' corresponds to dynamically allocated Points
  //   . these points will be deleted inside 'eval_list_of_points' or by the cache
  //     (do not delete them elsewhere !)
  //   . the methods clears the list of points
  void eval_list_of_points
  ( search_type                     search         ,     // IN     : search type
    std::set<Priority_Eval_Point> & points         ,     // IN/OUT : the list of points
    Barrier                       * barrier        ,     // IN/OUT : the barrier (can be NULL)
    bool                          & stop           ,     // IN/OUT : stopping criteria
    stop_type                     & stop_reason    ,     // OUT    : stopping reason
    const Eval_Point             *& new_feas_inc   ,     // OUT    : new feasible incumbent
    const Eval_Point             *& new_infeas_inc ,     // OUT    : new infeasible incumbent
    success_type                  & success        ,     // OUT    : type of success
    list<const Eval_Point *>      & evaluated_pts    );  // OUT    : list of processed points

};

#endif
