/*
  defines bod_text_parser - class that can parse bod syntax at general level
*/

#ifndef BOD_TEXT_PARSER_INCLUDED
#define BOD_TEXT_PARSER_INCLUDED

#include "../common/ext_list.h"

class bod_text_parser
{
	public:
		struct token
		{
			enum Type{
				t_openBracket,
				t_closeBracket,
				t_semicolon,
				t_colon,
				t_openInstrBlock,
				t_closeInstrBlock,
				t_text,
				t_hdrinfo,
			};
			
			static const char* specialChars[];
			static char tabWidth;
			
			const char *text;

			int line;
			short col;
			
			Type type;
			
			token() { text=0; tabWidth=4; }
			token(const token& t) { text=t.text; line=t.line; col=t.col; type=t.type; }
			virtual ~token() { }
			
			const char* getText() const;
			
		};
		
	private:
		//size_t m_lastCharPos;
		size_t m_lastPos;
		size_t m_newPos;
		
		const char *m_pszBuffer;
		size_t m_buffLen;
		int m_lineIdx;
		bool m_ignoreRemarks;
		
		//size_t parseLines(char *buffer, size_t size, char ***array_ptr);
		void parseLine(char *line, int idx);
	
	public:
		char * nextLine(); // public because of use in x3objects which is hack anyway
		
	public:
		typedef ext::list<token*> TokenList;
		typedef TokenList::iterator iterator;
		TokenList tokens;
		
		bod_text_parser() 
		{ 
			tabWidth(4);
			/*m_lastCharPos=0;*/ 
			m_lastPos=0; m_newPos=0;
			m_pszBuffer=0;
			m_buffLen=0;
			m_lineIdx=0;
			m_ignoreRemarks=false;
		}
		
		bool eof() const { /*return m_lastCharPos>=m_buffLen;*/ return m_lastPos >= m_buffLen; }
		
		void tabWidth(int width) { token::tabWidth=width; }
		int tabWidth() const { return token::tabWidth; }
		
		bool ignoreRemarks() const { return m_ignoreRemarks; }
		void ignoreRemarks(bool ignore) { m_ignoreRemarks=ignore; }
		
		void preParseBuffer(char *pszBuffer, size_t size);
		size_t parseBuffer(size_t limit=-1);
};

#endif // !defined(BOD_TEXT_PARSER_INCLUDED)