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

#include "Directions.hpp"

class Variable_Group {

private:

  std::set<int> _var_indexes;  // the variable indexes
  Directions    _directions;   // the directions

  // a group can be composed of integer / continous / binary variables
  // OR only categorical variables

  // private affectation operator:
  Variable_Group & operator = ( const Variable_Group & );
  
public:

  // constructor:
  Variable_Group ( const std::set<int>              & vi          ,
		   const std::set<direction_type>   & poll_dt     ,
		   const std::set<direction_type>   & sec_poll_dt ,
		   int                                halton_seed ,
		   std::ostream                     & out           ) :
    _var_indexes        (vi                            ) ,
    _directions         (static_cast<int>(vi.size()) ,
			 poll_dt                     ,
			 sec_poll_dt                 ,
			 halton_seed                 ,
			 out                           ) {}
  
  // copy constructor:
  Variable_Group ( const Variable_Group & vg ) :
    _var_indexes        (vg._var_indexes       ) ,
    _directions         (vg._directions        )   {}

  // destructor:
  ~Variable_Group ( void ) {}

  // comparison operator:
  bool operator < ( const Variable_Group & vg ) const;

  // checks:
  bool check ( const Point                      & fixed_vars         ,
	       const std::vector<bb_input_type> & bbit               ,
	       const std::set<direction_type>   * dir_types          ,    // can be NULL
	       const std::set<direction_type>   * sec_poll_dir_types ,    // can be NULL
	       const bb_output_type             * barrier_type       ,    // can be NULL
	       std::vector<bool>                * in_group             ); // can be NULL

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

  // GET methods:
  bool is_orthomads    ( void ) const { return _directions.is_orthomads();    }
  int  get_halton_seed ( void ) const { return _directions.get_halton_seed(); }

  const std::set<int> & get_var_indexes ( void ) const { return _var_indexes; }

  // get the directions:
  void get_directions  ( std::list<Direction> & dirs       ,
			 poll_type              poll       ,
			 int                    mesh_index   ) {
    _directions.compute ( dirs , poll , mesh_index , -1 );
  }
  
  // SET methods:
  void set_halton_seed ( int hs ) { _directions.ortho_mads_init(hs); }

};

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

// to allow the comparisons between two Variable_Group pointers
// (used with set<Variable_Group*,VG_Comp> in class Parameters):
struct VG_Comp {
  bool operator() ( const Variable_Group * vg1 , const Variable_Group * vg2 ) const {
    return (*vg1 < *vg2);
  }
};

#endif
