#ifndef STRINGTAGPARSER_H
#define STRINGTAGPARSER_H

#include <string>
using namespace std;

#include <stringconvert.h>

/*!
\brief Primitive xml reading parser. 

For a parser with reading, writing and scope see tokenizerlocal.h .

Taking a subset of XML where tagged hierarchical data can be extracted.

No space in tags.  < maze> should be <maze>.

Not concerned with efficiency as reading and writing
 done infrequently.

The data need not strictly be xml/tagged.  For example
 the client interprets the data, so the parser just
 extracts a string that was wrapped in tags.  This data
 could be order dependent and interpreted by the class.

 e.g. "1 2 .02" could serialize a particular class/object.
 Order dependent data is easier to code.

 Or the data may not be order independent.
 So could "start=1 end=2 changex=.02".

By restricting the data to be only tagged from the 
 stringtagparser's perspective we get a full parser.
 The work is now up to the client classes to organize
 the data for simple parsing.  

For example properties <mytag val="25"> in the tags are
 not supported, 
 non-unique tag lists are not supported (see stringtagiter class below). 
 <funkyobj><obj>23,12,9</obj><obj>12,-3,-1</obj></funkyobj>
 representation could become

\verbatim
  <funkyobj><obj>
    <n>2</n>
    <1>23,12,9</1>
    <2>12,-3,-1</2>
  </funkyobj>
  or keep tag which I recommend
  <funkyobj>
    <n>2</n>
    <1><obj>13,12,9</obj></1>
    <2><obj>13,12,9</obj></2>
  </funkyobj>
 and the non-unique data is made unique.
\endverbatim

An alternative to above example is order dependent data.
  <funkyobj><obj>2 23,12,9 12,-3,-1</obj></funkyobj>
  <funkyobj><obj><n>2</n> <array>23,12,9 12,-3,-1</array></obj></funkyobj>

I like wrapping a non-unique object in a unique tags.  This lets the data
 structures serialization be written independently (when reading extract the
 tagged data), it then is up to the client to first extract the unique data
 out.

*/
class stringtagparser
{
  stringtagparser() {}
public:

  /** Argument string for parsing. */
  stringtagparser(stringc & arg_);

  /** The string being parsed. */
  string arg;

  /** State set to true when data(tag1...) finds 
      the matching tags. */
  bool tagfound;

  /** Hierarchical one level deep. */
  stringc data( stringc& tag1 );
  /** Hierarchical two levels deep. */
  stringc data( stringc& tag1, stringc& tag2 );
  /** Hierarchical three levels deep. */
  stringc data( stringc& tag1, stringc& tag2, stringc& tag3 );
  /** Hierarchical four levels deep. */
  stringc data( stringc& tag1, stringc& tag2, stringc& tag3, stringc& tag4 );
  /** Hierarchical five levels deep. */
  stringc data( stringc& tag1, stringc& tag2, stringc& tag3, stringc& tag4, stringc& tag5 );
  /** Hierarchical six levels deep. */
  stringc data( stringc& tag1, stringc& tag2, stringc& tag3, stringc& tag4, stringc& tag5, stringc& tag6 );

  /** Another function could interpret hence the tags need to be 
      extracted with the data. */
  stringc data_with_tags( stringc & tag1 ) const;
};




/*!
\brief Iterate over non-unique xml tags extracting the text. 
*/
class stringtagiter : public stringtagparser 
{
  /** Beginning tag. */
  string tagbeg;
  /** End tag. */
  string tagend;
  /** What is extracted. */
  string data;
  /** What is left that has not been looked at. */
  string dataunprocessed;
  /** Result of looking for tags. */
  bool res;

  /** New string to be searched. */
  void extractbetweentag( stringc str);
public:

  /** The tag generally not unique. */
  string tag;

  /** Pass text to parse and tag.*/
  stringtagiter(stringc & arg_, stringc & tag_);

  /** arg or tag can be changed. */
  void reset();

  /** Look for the next */
  void operator ++();

  /** Is the iterator valid? */
  boolc operator ! () 
    { return res; }
  /** Extract text between tags. */
  stringc operator () ()
    { return data; }

};


#endif


