#ifndef TOKENIZER_H
#define TOKENIZER_H
/*
* HydroPlus is source code and models developed and managed by Theodore Endreny and his students at SUNY ESF, te@esf.edu
* The US Forest Service and Davey Tree have provided strategic software development support through funding and personnel
* Attribution for use of software and code is requested. Please see Executive.cpp for documentation.
* Author: Professor Jim Fawcett, CST 4-187, Syracuse University, jfawcett@twcny.rr.com
*/
/*
  Module Operations: 
  ==================
  Its reads words from an attached file or string. Word boundaries occur when a character sequence read from the file or string:
  - changes between any of the character types: alphanumeric, punctuator, or white space.
  - certain characters are treated as single character tokens, e.g., "(", ")", "{", "}", "[". "]", ";", ".", and "\n".
    You can change the selection with Toker::setMode(Toker::code) or Toker::setMode(Toker::xml), or Toker::setSingleCharTokens(somestring);
*/

#include <string>
#include <iostream>
#include <vector>

//using namespace std allows for use of standard namespace without the preface 
using namespace std;

class Toker
{
public:
  enum mode { code, xml, custom };
  Toker(const string& src = "", bool isFile = true);
  ~Toker();
  void setMode(mode md);
  void setSingleCharTokens(string tokChars);
  bool attach(const string& filename, bool isFile = true);
  string getTok();
  void returnComments(bool doReturn = true);
  int& lines();
  int  braceLevel();
  bool isFileEnd();
  int  peek();           // peek at next char (not token)
  void putback(int ch);  // put back char on stream (not token)
  enum state { default_state, comment_state, quote_state };

private:
  istream* pIn;
  char prevprevChar, prevChar, currChar, nextChar;
  string scTok;
  vector<char> putbacks;
  int numLines;
  int braceCount;
  bool doReturnComments;
  bool aCppComment;
  enum state _state;
  mode _mode;

  // private helper functions
  int  get();
  bool getChar();
  bool isSingleCharTok(char ch);
  bool isTokEnd();
  void stripWhiteSpace();
  bool isIdentifierChar(char ch);
  bool isBeginComment();
  bool isEndComment();
  string eatComment();
  bool aSingleQuote;
  bool isBeginQuote();
  bool isEndQuote();
  string eatQuote();

  // prohibit copying and assignment
  Toker(const Toker &tkr);
  Toker& operator=(const Toker&);
};

inline void Toker::returnComments(bool doReturn)
{
  doReturnComments = doReturn;
}

inline bool Toker::isFileEnd() { return (nextChar == -1); }

inline int& Toker::lines() { return numLines; }

inline int Toker::braceLevel() { return braceCount; }

#endif
