/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#ifndef INCLUDED_Dictionary_h
#define INCLUDED_Dictionary_h

#include "Config.h"

#include <map>
#include <string.h>

struct ltstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return strcmp(s1, s2) < 0;
  }
};

/*------------------------------------------------------------------
CLASS
  Dictionary

DESCRIPTION
  A table from keys to values.
------------------------------------------------------------------*/
class Dictionary {
public:
  Dictionary();

  ~Dictionary();

  void read(const char *filename);

  //. ----------------------------------------------------------------
  // Gets a value of the requested type.
  // INPUT
  //   key - the key to lookup the value of
  // OUTPUT
  //   value - the value assigned to the key
  // RETURNS
  //   true on success
  // -----------------------------------------------------------------
  bool getValueInt   (const char *key,int         &value);
  bool getValueDouble(const char *key,double      &value);
  bool getValueString(const char *key,const char *&value);

  /*
  bool getValueInt   (const char *key,int         &value, int         default_value)
    {value = default_value; return(getValueInt(key,value));}
  bool getValueDouble(const char *key,double      &value, double      default_value)
    {value = default_value; return(getValueDouble(key,value));}
  bool getValueString(const char *key,const char *&value, const char *defualt_value)
    {value = default_value; return(getValueString(key,value));}
  */

protected:
private: // methods
  //. ----------------------------------------------------------------
  // Reads a value assignment into the map.
  // RETURNS
  //   success - true if succeeded, false on end of file
  // -----------------------------------------------------------------
  bool readValueAssignment();

  //. ----------------------------------------------------------------
  // Reads a string until one of the stop chars was found.  The stop
  // character will be the last character of the returned string.
  // INPUT
  //   stop_chars - the characters to stop reading because of
  // OUTPUT
  //   val - the string read including the stop character
  // RETURNS
  //   success - true on success, false on end of file
  // -----------------------------------------------------------------
  bool readStringUntil(const char *stop_chars,char *&val);

  //. ----------------------------------------------------------------
  // Trims off whitespace characters from the string.
  // INPUT
  //   str - the string to trim
  // OUTPUT
  //   str - the trimmed string
  // -----------------------------------------------------------------
  void trimString(char *&str);

  //. ----------------------------------------------------------------
  // Finds the next delimeter that is not in a comment.
  // INPUT
  //   str - the string to search in
  //   num_chars - the number of characters in the string
  //   stop_chars - the set of deliminating chars
  // OUTPUT
  //   num_chars_used - the number of characters in the source string used
  // RETURNS
  //   num_chars - the number of non comment characters up to and including
  //               the first delimeter
  // -----------------------------------------------------------------
  int findNextDelimeter(const char *str,int num_chars, const char *stop_chars, int &num_chars_used);

  //. ----------------------------------------------------------------
  // Copy the specified number of characters ignoring comments.
  // INPUT
  //   dst - the destination string
  //   src - the source string
  //   num_chars - the num of characters to copy
  // OUTPUT
  //   dst - the resulting destination string
  // RETURNS
  //   dst - the resulting destination string
  // -----------------------------------------------------------------
  char *strNCpyNonComment(char *dst,const char *src,int num_chars);

private: // data
  typedef std::map<const char *,const char *,ltstr> DictionaryMap;
  DictionaryMap dict_map;

  int fd;

  static const int BufSize=1024;
  char buf[BufSize];
  int numCharsInBuf;
};

#endif
