/*-------------------------------------------------------------------------------------*/
/*  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 __EVAL_POINT__
#define __EVAL_POINT__

#include "Signature.hpp"

// forward declaration of Cache_File_Point:
class Cache_File_Point;

class Eval_Point : public Point , private Uncopyable {
private:

  static int        _current_tag;         // current tag
  int               _tag;                 // unique tag

  const Signature * _signature;           // the eval point signature

  NOMAD::Double     _f;                   // f and h are explicitely computed by Evaluator and
  NOMAD::Double     _h;                   // are not saved in the cache file

  mutable bool      _in_cache;            // is this eval point is in the cache
  mutable bool      _current_run;         // true if the point has already be evaluated in the current run
                                          // (used to count the simulated bb eval stat Stats::_sim_bb_eval)

  bool              _surrogate;           // this point evaluates on surrogates

  Direction       * _direction;           // direction with which the eval point has been
                                          // constructed

  int             * _mesh_index;          // the same for the mesh index (l)

  poll_center_type  _poll_center_type;    // type of poll center (feasible or not)

  bool              _eval_ok;             // if the evaluation went well
  bool              _EB_ok;               // if all EB constraints have been satisfied

  Point             _bb_outputs;          // black-box outputs

  NOMAD::Double     _user_eval_priority;  // user evaluation priority:
                                          //   . decided by the user in his custom
                                          //     Evaluator::eval_x() function, via
                                          //     set_user_eval_priority()
                                          //   . points with higher priorities will be
                                          //     evaluated first
                                          //   . for more details, see code in
                                          //     Priority_Eval_Point.cpp

  NOMAD::Double     _rand_eval_priority;  // same idea for a random ordering of trial points

public:

  // constructor 1:
  explicit Eval_Point ( void );

  // constructor 2:
  Eval_Point ( int n , int m );

  // constructor 3:
  explicit Eval_Point ( const Cache_File_Point & x );

  // destructor:
  virtual ~Eval_Point ( void );

  // sizeof:
  virtual int size_of ( void ) const;

  // Eval_Point check:
  bool check ( int m , check_failed_type & cf ) const;

  // GET methods:
  int                   get_tag                ( void ) const { return _tag;                }
  const NOMAD::Double & get_f                  ( void ) const { return _f;                  }
  const NOMAD::Double & get_h                  ( void ) const { return _h;                  }
  const NOMAD::Double & get_user_eval_priority ( void ) const { return _user_eval_priority; }
  const NOMAD::Double & get_rand_eval_priority ( void ) const { return _rand_eval_priority; }
  const Point         & get_bb_outputs         ( void ) const { return _bb_outputs;         }
  const Signature     * get_signature          ( void ) const { return _signature;          }
  const Direction     * get_direction          ( void ) const { return _direction;          }
  const int           * get_mesh_index         ( void ) const { return _mesh_index;         }
  bool                  get_current_run        ( void ) const { return _current_run;        }
  bool                  is_in_cache            ( void ) const { return _in_cache;           }
  bool                  is_eval_ok             ( void ) const { return _eval_ok;            }
  bool                  is_EB_ok               ( void ) const { return _EB_ok;              }
  bool                  is_surrogate           ( void ) const { return _surrogate;          }
  poll_center_type      get_poll_center_type   ( void ) const { return _poll_center_type;   }
  
  // check the point's feasibility (if h <= h_min):
  bool is_feasible ( const NOMAD::Double & h_min ) const {
    return ( _h.is_defined() && _h <= h_min );
  }

  // snap to bounds:
  bool snap_to_bounds ( void );
  
  // comparison operator:
  bool operator < ( const Eval_Point & x ) const;

  // SET methods:
  void set                  ( int           n , int m         );
  void set                  ( const Point & x , int m         );
  void set_signature        ( const Signature     * s         );
  void set_f                  ( const NOMAD::Double & f       ) { _f                  = f;       }
  void set_h                  ( const NOMAD::Double & h       ) { _h                  = h;       }
  void set_user_eval_priority ( const NOMAD::Double & uep     ) { _user_eval_priority = uep;     }
  void set_rand_eval_priority ( const NOMAD::Double & rep     ) { _rand_eval_priority = rep;     }
  void set_bb_output        ( int i , const NOMAD::Double & v ) { _bb_outputs[i]      = v;       }
  void set_bb_output        ( const Point         & bbo       ) { _bb_outputs         = bbo;     }
  void set_eval_ok          ( bool                  eval_ok   ) { _eval_ok            = eval_ok; }
  void set_EB_ok            ( bool                  EB_ok     ) { _EB_ok              = EB_ok;   }
  void set_surrogate        ( bool                  sgte      ) { _surrogate          = sgte;    }
  void set_poll_center_type ( poll_center_type      pct       ) { _poll_center_type   = pct;     }
  void set_mesh_index       ( const int           * l         );
  void set_direction        ( const Direction     * dir       );

  void set_current_run      ( bool                  cr        ) const { _current_run  = cr;      }
  void set_in_cache         ( bool                  ic        ) const { _in_cache     = ic;      }

  // display:
  void display( std::ostream & out ) const;
};

// display:
inline std::ostream & operator << ( std::ostream     & out ,
				    const Eval_Point & x ) {
  x.display(out);
  return out;
}

#endif
