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

#include "Parameters.hpp"

class Signature : private Uncopyable {

private:

  const Parameters         & _p;                // parameters
  Point                      _lb;               // lower bounds
  Point                      _ub;               // upper bounds
  Point                      _fixed_variables;  // fixed variables
  std::vector<bb_input_type> _input_types;      // input types

  std::list<Variable_Group*> _var_groups;       // variable groups (include the directions)

  Mesh                     * _mesh;             // mesh associated with this signature

  std::ostream             & _out;              // display

  // initializations:
  void init ( const Point                             & lb                ,
	      const Point                             & ub                ,
	      const Point                             & fixed_variables   ,
	      const std::vector<bb_input_type>        & input_types       ,
	      const std::set<Variable_Group*,VG_Comp> & var_groups        ,
	      const Point                             & initial_mesh_size ,
	      const Point                             & min_mesh_size     ,
	      const Point                             & min_poll_size       );
public:

  // constructor 1:
  explicit Signature ( const Parameters & p , std::ostream & out );

  // constructor 2:
  Signature ( const Parameters                        & p                 ,
	      const Point                             & lb                ,
	      const Point                             & ub                ,
	      const Point                             & fixed_variables   ,
	      const std::vector<bb_input_type>        & input_types       ,
	      const std::set<Variable_Group*,VG_Comp> & var_groups        ,
	      const Point                             & initial_mesh_size ,
	      const Point                             & min_mesh_size     ,
	      const Point                             & min_poll_size     ,
	      std::ostream                            & out                 );

  // destructor:
  ~Signature ( void );

  // resets:
  void reset            ( const Parameters & p );
  void reset_var_groups ( void );

  // snap to bounds:
  bool snap_to_bounds ( Point & x , Direction * direction ) const;

  // check the stopping conditions on the minimal poll and mesh sizes:
  void check_min_mesh_sizes ( const Parameters & p           ,
			      int                mesh_index  ,
			      bool             & stop        ,
			      stop_type        & stop_reason   );

  // GET methods:
  const Point & get_lb              ( void ) const { return _lb;                   }
  const Point & get_ub              ( void ) const { return _ub;                   }
  const Point & get_fixed_variables ( void ) const { return _fixed_variables;      }
  int           get_n  ( void ) const { return static_cast<int>(_input_types.size()  ); }

  const std::vector<bb_input_type> & get_input_types ( void ) const { return _input_types; }

  // check the compatibility of a point:
  bool is_compatible ( const Point & x ) const;

  // get the directions (the computed directions already include delta^k_m):
  void get_directions ( std::list<Direction> & dirs       ,
			poll_type              poll       ,
			int                    mesh_index   ) const;

  // get delta_m (mesh size parameter), of size n:
  void get_delta_m ( Point & delta_m , int mesh_index ) const {
    _mesh->get_delta_m ( delta_m , mesh_index );
  }
  
  // get delta_p (poll size parameter), of size n:
  void get_delta_p ( Point & delta_p , int mesh_index ) const {
    _mesh->get_delta_p ( delta_p , mesh_index );
  }

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

};

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

#endif
