// 
// Super-simple Stream-string XML Parser
//
// File:   SSXMLParser.h
// Author: chmelarp
//
// Created on 2. duben 2008, 22:32
//

#ifndef _SSXMLPARSER_H
#define _SSXMLPARSER_H

// Include
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>

// Using
using namespace std;

// define some special characters
#define isspace(ch)			((unsigned int)(ch) < 33)
// define some normal characters
#define isnumber(ch)		(((unsigned int)(ch) > 47) && ((unsigned int)(ch) < 58))
#define issmallletter(ch)	(((unsigned int)(ch) > 96) && ((unsigned int)(ch) < 123))
#define isbigletter(ch)		(((unsigned int)(ch) > 64) && ((unsigned int)(ch) < 91))
#define isletter(ch)		(issmallletter(ch) || isbigletter(ch))
#define isAZ09(ch)			(isletter(ch) || isnumber(ch))
// define higher character
#define isName(ch)			(isAZ09(ch) || ((ch) == '.') || ((ch) == '-') || ((ch) == '_') || ((ch) == ':')  || ((ch) == '?') || ((ch) == '!'))

//
// Super-simple Stream-string XML Parser
//
class SSXMLParser
{
public:             // too simple to be protected
	string input;   // string 2B parsed
	string root;    // rootElement
	// todo: add last name?

public:
	// Constructor
	SSXMLParser(const string& inp)
	{
		input = inp;
		toLower(input);
		root = "";
	};

	// Returns XML document without header
	// not implemented!
	string getRootElement();

	// Returns next tag or empty string (if it doesn't exit)
	// deletes from input!
	string getElement();

	// Returns next tag or empty string (if it doesn't exit)
	// deletes from input!
	string getTag();
	// Returns position of next end tag or -1 (if it doesn't exit)
	int findEndTag(const string& name, int from);
	int findEndTag(const string& inp, const string& name, int from);

	// Returns name of the (first) tag or empty string (if it doesn't exit)
	string findName();
	string findName(const string& inp);

	// Returns value of an attribute or empty string (if it doesn't exit)
	string findAttrib(const string& name);
	string findAttrib(const string& inp, const string& name);
	// TODO: add findNextAttrib?

	// Returns the "inside" of the (first) tag or empty string (if it doesn't exit or it is not closed)
	string findContent();
	string findContent(const string& inp);

	// Finds an XML name from the position and before specified position (length)
	string findName(int from, int before);
	string findName(const string& inp, int from, int before);

	// Finds first XML string
	string findString();
	string findString(const string& inp);
	string findString(int from, int before);
	// Finds an XML string from the position and before specified position (length)
	string findString(const string& inp, int from, int before);

	// Finds first position of a substring, ignoring "strings" and whitespace
	int finds(const string& substr);
	int finds(const string& inp, const string& substr);
	// Finds -//- from the position and before specified position (length)
	int finds(const string& substr, int from, int before, bool inString=false);
	int finds(const string& inp, const string& substr, int from, int before, bool inString=false);

	// Transforms lowercase, ignoring "strings"
	void toLower();
	void toLower(string& inp);
};

#endif /* _SSXMLPARSER_H */

