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

#include "Point.hpp"

class Direction : public Point {

private:

#ifdef DEBUG
  static int      _cardinality;      // number of Direction's in memory.
  static int      _max_cardinality;  // max number of Direction's in memory.
#endif

  direction_type _type;   // type of direction (see defines.hpp)
  mutable int    _index;  // direction index   (only for display)

public:

#ifdef DEBUG
  static int get_cardinality     ( void ) { return Direction::_cardinality;     }
  static int get_max_cardinality ( void ) { return Direction::_max_cardinality; }
#endif

  // constructor 1:
  Direction ( void );

  // constructor 2:
  Direction ( int n , const NOMAD::Double & v , direction_type type );

  // constructor 3:
  Direction ( const Point & x , direction_type type );

  // copy constructor:
  Direction ( const Direction & d );

  // destructor:
  ~Direction ( void );

  // affectation operator:
  Direction & operator = ( const Direction & );

  // is_defined:
  bool is_defined ( void ) const { return _type != _UNDEFINED_DIRECTION_; }

  // clear:
  void clear ( void );

  // sizeof:
  virtual int size_of ( void ) const {
    return Point::size_of() + sizeof(_type) + sizeof(_index);
  }

  // negation:
  const Direction operator - ( void ) const;

  // SET methods:
  void set_index ( int i ) const { _index = i; }

  // GET methods:
  direction_type get_type  ( void ) const { return _type;                 }
  int            get_index ( void ) const { return _index;                }
  bool           is_mads   ( void ) const { return dir_is_mads ( _type ); }
  bool           is_gps    ( void ) const { return dir_is_gps  ( _type ); }

  // display:
  virtual void display ( std::ostream      & out ,
			 const std::string & sep ,
			 int                 w   ,
			 int                 lim   ) const;
};

// display:
inline std::ostream & operator << ( std::ostream & out, const Direction & d ) {
  d.display ( out , " " , 2 , Point::get_display_limit() );
  return out;
}

#endif
