/* Copyright (C) 2007 One Laptop Per Child
 * Author: Marc Maurer <uwog@uwog.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#ifndef ABI_DEVELOP_LANGPATT_H
#define ABI_DEVELOP_LANGPATT_H

#include <libxml/tree.h>
#include <regex.h>

#include <string>
#include <vector>

using std::string;
using std::vector;

class LanguagePattern
{
public:
	virtual ~LanguagePattern()
	{
		if (comp_regex)
		{
			regfree(comp_regex);
			DELETEP(comp_regex);
		}

		if (comp_start_regex)
		{
			regfree(comp_start_regex);
			DELETEP(comp_start_regex);
		}

		if (comp_end_regex)
		{
			regfree(comp_end_regex);
			DELETEP(comp_end_regex);
		}
	}

	enum PatternType
	{
		ESCAPE_CHAR,
		STRING,
		KEYWORD_LIST,
		KEYWORD,
		LINE_COMMENT,
		BLOCK_COMMENT,
		SYNTAX_ITEM,
		PATTERN_ITEM,
		_NULL
	};
	
	static void					construct(xmlNode* pattern, vector<LanguagePattern*>& patterns);
	
	PatternType					type;
	string						name;
	string						style;
	bool						endAtLineEnd;

	string						escape_char;

	string						regex;
	string						start_regex;
	string						end_regex;

	regex_t*					comp_regex;
	regex_t*					comp_start_regex;
	regex_t*					comp_end_regex;

protected:
	LanguagePattern()
		: type(LanguagePattern::_NULL),
		endAtLineEnd(true),
		comp_regex(NULL),
		comp_start_regex(NULL),
		comp_end_regex(NULL)
	{
	}

	virtual void				_parseAttribs(xmlNode* patternNode);
	virtual void				_parseElements(xmlNode* patternNode);
};

class StringLanguagePattern : public LanguagePattern
{
public:	
	StringLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::STRING;
	}
};

// TODO: deprecate this class
class KeywordListLanguagePattern : public LanguagePattern
{
public:
	KeywordListLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::KEYWORD_LIST;
	}
	
	vector<string>				m_vKeywords;
	bool						caseSensitive;
	bool						matchEmptyStringAtBeginning;
	bool						matchEmptyStringAtEnd;

	string						attr_beginning_regex;
	string						attr_end_regex;

	virtual void				_parseAttribs(xmlNode* patternNode);
	virtual void				_parseElements(xmlNode* patternNode);
};

class KeywordLanguagePattern : public LanguagePattern
{
public:
	KeywordLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::KEYWORD;
	}
	
	bool						caseSensitive;
	bool						matchEmptyStringAtBeginning;
	bool						matchEmptyStringAtEnd;
};

class LineCommentLanguagePattern : public LanguagePattern
{
public:	
	LineCommentLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::LINE_COMMENT;
	}	
};

class BlockCommentLanguagePattern : public LanguagePattern
{
public:	
	BlockCommentLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::BLOCK_COMMENT;
		endAtLineEnd = false;
	}	
};

class SyntaxItemLanguagePattern : public LanguagePattern
{
public:	
	SyntaxItemLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::SYNTAX_ITEM;
	}	
};

class PatternItemLanguagePattern : public LanguagePattern
{
public:	
	PatternItemLanguagePattern()
		: LanguagePattern()
	{
		type = LanguagePattern::PATTERN_ITEM;
	}	
};

#endif /* ABI_DEVELOP_LANGPATT_H */