/*===========================================================================*
 * This file is part of a solver for the Vehicle Routing Problem             *
 * developed using the BiCePS Linear Integer Solver (BLIS).                  *
 *                                                                           *
 * This solver is distributed under the Eclipse Public License as part of    * 
 * the COIN-OR repository (http://www.coin-or.org).                          *
 *                                                                           *
 * Authors: Yan Xu, Lehigh University                                        *
 *          Ted Ralphs, Lehigh University                                    *
 *                                                                           *
 * Copyright (C) 2007 Yan Xu and Ted Ralphs.                                 *
 * All Rights Reserved.                                                      *
 *===========================================================================*/

#ifndef VrpParams_h
#define VrpParams_h

#include "AlpsKnowledge.h"
#include "AlpsParameterBase.h"

//#############################################################################

//** Parameters used in Vrp. */
class VrpParams : public AlpsParameterSet {
 public:
  /** Character parameters. All of these variable are used as booleans
      (true = 1, false = 0). */
  enum boolParams{
     doGreedy,
     doExtraInRoot,
     tspProb,
     endOfBoolParams
  };
  
  /** Integer paramters. */
  enum intParams{
     numRoutes,
     verbosity,
     greedyNumTrials,
     whichConnectedRoutine,
     maxNumCutsInShrink,
     whichTspCuts,
     endOfIntParams
  };

  /** Double parameters. */
  enum dblParams{
      ///
      endOfDblParams
  };

  /** String parameters. */
  enum strParams{
      strDummy,
      //
      endOfStrParams
  };

  /** There are no string array parameters. */
  enum strArrayParams{
      strArrayDummy,
      ///
      endOfStrArrayParams
  };

 public:
  /**@name Constructors. */
  /*@{*/
  /** The default constructor creates a parameter set with from the template
      argument structure. The keyword list is created and the defaults are
      set. */
  VrpParams() :
    AlpsParameterSet(
		     static_cast<int>(endOfBoolParams),
		     static_cast<int>(endOfIntParams),
		     static_cast<int>(endOfDblParams),
		     static_cast<int>(endOfStrParams),
		     static_cast<int>(endOfStrArrayParams)
		     )
    {
      createKeywordList();
      setDefaultEntries();
    }
  /*@}*/

  /** Method for creating the list of keyword looked for in the parameter
      file. */
  virtual void createKeywordList();
  /** Method for setting the default values for the parameters. */
  virtual void setDefaultEntries();
  /*@}*/


 public:
  //===========================================================================
  /** For user application: 
   *   Following code are do NOT need to change. 
   *   The reason can not put following functions in base class 
   *   <CODE> AlpsParameterSet </CODE> is that <CODE> boolParams </CODE>
   *   and <CODE> endOfboolParams </CODE> etc., are NOT the same as those
   *   declared in base class.
   */
  //===========================================================================

  
  /**@name Query methods 
      
     The members of the parameter set can be queried for using the overloaded
     entry() method. Using the example in the class
     documentation the user can get a parameter with the
     "<code>param.entry(USER_par::parameter_name)</code>" expression.
  */
  /*@{*/
  ///
  inline bool entry(const boolParams key) const { return bpar_[key]; }
  ///
  inline int entry(const intParams key) const { return ipar_[key]; }
  ///
  inline double  entry(const dblParams key) const { return dpar_[key]; }
  ///
  inline const std::string&
    entry(const strParams key) const { return spar_[key]; }
  ///
  inline const std::vector<std::string>&
    entry(const strArrayParams key) const { return sapar_[key]; }
  /*@}*/

  //---------------------------------------------------------------------------
  /// char* is true(1) or false(0), not used
  void setEntry(const boolParams key, const char * val) {
	  bpar_[key] = atoi(val) ? true : false; }
  /// char is true(1) or false(0), not used
  void setEntry(const boolParams key, const char val) {
	  bpar_[key] = val ? true : false; }
  /// This method is the one that ever been used.
  void setEntry(const boolParams key, const bool val) {
    bpar_[key] = val; }
  ///
  void setEntry(const intParams key, const char * val) {
    ipar_[key] = atoi(val); }
  ///
  void setEntry(const intParams key, const int val) {
    ipar_[key] = val; }
  ///
  void setEntry(const dblParams key, const char * val) {
    dpar_[key] = atof(val); }
  ///
  void setEntry(const dblParams key, const double val) {
    dpar_[key] = val; }
  ///
  void setEntry(const strParams key, const char * val) {
    spar_[key] = val; }
  ///
  void setEntry(const strArrayParams key, const char *val) {
    sapar_[key].push_back(val); }

  //---------------------------------------------------------------------------

  /**@name Packing/unpacking methods */
  /*@{*/
  /** Pack the parameter set into the buffer (AlpsEncoded is used 
      as buffer Here). */
  void pack(AlpsEncoded& buf) {
    buf.writeRep(bpar_, endOfBoolParams)
      .writeRep(ipar_, endOfIntParams)
      .writeRep(dpar_, endOfDblParams);
    for (int i = 0; i < endOfStrParams; ++i)
      buf.writeRep(spar_[i]);
    for (int i = 0; i < endOfStrArrayParams; ++i) {
      buf.writeRep(sapar_[i].size());
      for (size_t j = 0; j < sapar_[i].size(); ++j)
	buf.writeRep(sapar_[i][j]);
    }
  }
  /** Unpack the parameter set from the buffer. */
  void unpack(AlpsEncoded& buf) {
    int dummy;
    // No need to allocate the arrays, they are of fixed length
    dummy = static_cast<int>(endOfBoolParams);
    buf.readRep(bpar_, dummy, false);
    dummy = static_cast<int>(endOfIntParams);
    buf.readRep(ipar_, dummy, false);
    dummy = static_cast<int>(endOfDblParams);
    buf.readRep(dpar_, dummy, false);
    for (int i = 0; i < endOfStrParams; ++i)
      buf.readRep(spar_[i]);
    for (int i = 0; i < endOfStrArrayParams; ++i) {
      size_t str_size;
      buf.readRep(str_size);
      sapar_[i].reserve(str_size);
      for (size_t j = 0; j < str_size; ++j){
	//	sapar_[i].unchecked_push_back(std::string());
	sapar_[i].push_back(std::string());
	buf.readRep(sapar_[i].back());
      }
    }
  }
  /*@}*/

};

#endif
