/*********************************************************************
 * This file is part of the cpplibs suite.
 *
 * Copyright (C) 2001 Topi Mäenpää
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.2 $
 *********************************************************************/

#ifndef _UTIL_REGEX_H
#define _UTIL_REGEX_H

#include <string>
#include <List.h>

#define REGEX_MAX_SUBSTRINGS		9

namespace util
{
	/**
	 * Regex is a class for easy implementation of regular expression
	 * search and replace operations. It provides support for POSIX
	 * extended regular expressions in both case sensitive and case
	 * insensitive modes.
	 **/
	class Regex
	{
	public:
		/**
		 * Find <i>needle</i> in <i>haystack</i>.
		 *
		 * @param haystack any string
		 * @param needle a POSIX extended regular expression
		 * @param startIndex start search at this point
		 * @param ignoreCase if true, the search is case-insensitive
		 * @return the index of the first match, or -1 if not found
		 **/
		static int find(const std::string& haystack,
										const std::string& needle,
										bool ignoreCase = false,
										int startIndex = 0);
		/**
		 * Replace <i>needle</i> with <i>replacement</i> in
		 * <i>haystack</i>. <i>Needle</i> is a regular expression
		 * complying to the POSIX extended regex specification.
		 * <i>Replacement</i> may contain escaped sequences '\0' to '\9'
		 * that are replaced with the respective substring matches. '\0'
		 * means the whole match, '\1' means the first substring etc.<p>
		 *
		 * Example:
		 * <pre>
		 * //replace "_text_" with "{text}" in str
		 * str = replace(str,"_(.+)_","{\1}");
		 * //replace "http://www.foo.com/" with [www.foo.com]
		 * str = replace(str,"http://(.+)([[:blank:][:punct:]])","[\1]\2");
		 * //replace "email@host.com" with "mailto:email@host.com"
		 * str = replace(str,"[[:alnum:].-]+@[[:alnum:].-]+[a-z]","mailto:\0");
		 * </pre>
		 *
		 * @param haystack search in this string
		 * @param needle search for this regex
		 * @param replacement replace each match with this
		 * @param max replace at most this many occurrences (<1 for all)
		 * @param ignoreCase if true, the search is case-insensitive
		 * @return a new string with regex matches replaced
		 **/
		static std::string replace(const std::string& haystack,
															 const std::string& needle,
															 const std::string& replacement,
															 bool ignoreCase = false,
															 int max = -1);

		/**
		 * Split a string by a regular expression.
		 *
		 * @param str the string to be split
		 * @param regex a regular expression that matches item separators
		 * @param result store the resulting pieces in this list
		 * @param max maximum number of pieces
		 **/
		static void tokenize(const std::string& str,
												 const std::string& regex,
												 List<std::string>& result,
												 bool ignoreCase = false,
												 int max = -1);

		/**
		 * Split a string by a regular expression.
		 *
		 * @param str the string to be split
		 * @param regex a regular expression that matches item separators
		 * @param max maximum number of pieces
		 * @return the pieces in a list
		 **/
		static List<std::string> tokenize(const std::string& str,
																			const std::string& regex,
																			bool ignoreCase = false,
																			int max = -1)
		{
			List<std::string> result;
			tokenize(str,regex,result,ignoreCase,max);
			return result;
		}
	};
}

#endif
