#ifndef BABBLEMUD_REGEXP_H
#define BABBLEMUD_REGEXP_H

#include "pcre.h"
#include "strings.h"

#include <string>
#include <vector>
#include <sstream>

using namespace std;

#define MAX_PCRE_WILDCARDS 1000

// compiled regular expression type

class Regexp 
  {

  private:

  // pairs of offsets from match
  vector<int> offsets_;
  // count of matches
  int count_;
  // the regular expression
  string regexp_;
  // the string we match on (to extract wildcards from)
  string target_;
  // the program itself
  pcre * program_;	    
  // offset of compile error
  int erroroffset_;
  // compile count
  int compileCount_;
  // execute count
  int executeCount_;

  // extra stuff for speed
  pcre_extra * extra_;

  public:

  //  construct and compile (default constructor)
  Regexp (const string & regexp = "", const int options = 0);
    
  // copy constructor
  Regexp (const Regexp & rhs); 

  // operator=  (assign one regexp to another)
  const Regexp & operator= (const Regexp & rhs);

  ~Regexp ();

  // returns a numbered wildcard
  const string GetWildcard (const int iNumber) const;

  // returns a named wildcard
  const string GetWildcard (const string & sName) const;

  // compile-time options can be one or more of:


  // PCRE_CASELESS | PCRE_EXTENDED | PCRE_ANCHORED | PCRE_MULTILINE | 
  // PCRE_DOTALL | PCRE_DOLLAR_ENDONLY | PCRE_EXTRA | PCRE_UNGREEDY | PCRE_UTF8 | 
  // PCRE_NO_AUTO_CAPTURE

  // compile regular expression, throws exception if problem
  void Compile (const string & regexp,       // the expression
                const int options = 0);    // compile-time options, see above

  // execution options can be one or more of:

  // PCRE_ANCHORED | PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY

  // execute regular expression, return true if match, false if not
  // throw exception if major problem
  bool Execute (const string & target,     // what to match
                const int offset = 0,    // where to start in the string
                const int options = 0);  // run-time options, see above

  // turn results into a map of data/value pairs
  void BuildResultMap (StringMap & results);

  // returns error offset
  int GetErrorOffset () const { return erroroffset_; };
  // returns count of matches
  int GetCount () const { return count_; };
  // get the text of the regular expression
  string GetRegexp () const { return regexp_; };
  // get the most recent target
  string GetTarget () const { return target_; };
  // returns true if compiled OK
  bool OK () const { return program_ != NULL; };

  };  // end of class Regexp


Regexp * regcomp(const char *exp, const int options = 0);
int regexec (Regexp *prog,
            const char *string,
            const int start_offset = 0);

bool CheckRegularExpression (const string strRegexp, const int iOptions);


#endif  // BABBLEMUD_REGEXP_H
