//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence.util;

import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Utility class with static methods to create search pattern
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class PatternConstructor {

	private PatternConstructor() {
		// don't instantiate
	}

	public static Pattern createPattern(String pattern,
			boolean isCaseSensitive, boolean isRegex)
			throws PatternSyntaxException {
		return createPattern(pattern, isRegex, true, isCaseSensitive, false);
	}

	/**
	 * Creates a pattern element from the pattern string which is either a
	 * reg-ex expression or in our old 'StringMatcher' format.
	 * 
	 * @param pattern
	 *            The search pattern
	 * @param isRegex
	 *            <code>true</code> if the passed string already is a reg-ex
	 *            pattern
	 * @param isStringMatcher
	 *            <code>true</code> if the passed string is in the
	 *            StringMatcher format.
	 * @param isCaseSensitive
	 *            Set to <code>true</code> to create a case insensitive
	 *            pattern
	 * @param isWholeWord
	 *            <code>true</code> to create a pattern that requires a word
	 *            boundary at the beginning and the end.
	 * @return The created pattern
	 * @throws PatternSyntaxException
	 */
	public static Pattern createPattern(String pattern, boolean isRegex,
			boolean isStringMatcher, boolean isCaseSensitive,
			boolean isWholeWord) throws PatternSyntaxException {
		if (isRegex) {
			if (isWholeWord) {
				StringBuffer buffer = new StringBuffer(pattern.length() + 10);
				buffer.append("\\b(?:").append(pattern).append(")\\b"); //$NON-NLS-1$ //$NON-NLS-2$
				pattern = buffer.toString();
			}
		} else {
			int len = pattern.length();
			StringBuffer buffer = new StringBuffer(len + 10);
			// don't add a word boundary if the search text does not start with
			// a word char. (this works around a user input error).
			if (isWholeWord && len > 0 && isWordChar(pattern.charAt(0))) {
				buffer.append("\\b"); //$NON-NLS-1$
			}
			appendAsRegEx(isStringMatcher, pattern, buffer);
			if (isWholeWord && len > 0 && isWordChar(pattern.charAt(len - 1))) {
				buffer.append("\\b"); //$NON-NLS-1$
			}
			pattern = buffer.toString();
		}

		int regexOptions = Pattern.MULTILINE;
		if (!isCaseSensitive) {
			regexOptions |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
		}
		return Pattern.compile(pattern, regexOptions);
	}

	private static boolean isWordChar(char c) {
		return Character.isLetterOrDigit(c);
	}

	/**
	 * Creates a pattern element from an array of patterns in the old
	 * 'StringMatcher' format.
	 * 
	 * @param patterns
	 *            The search patterns
	 * @param isCaseSensitive
	 *            Set to <code>true</code> to create a case insensitive
	 *            pattern
	 * @return The created pattern
	 * @throws PatternSyntaxException
	 */
	public static Pattern createPattern(String[] patterns,
			boolean isCaseSensitive) throws PatternSyntaxException {
		StringBuffer pattern = new StringBuffer();
		for (int i = 0; i < patterns.length; i++) {
			if (i > 0) {
				// note that this works only as we know that the operands of the
				// or expression will be simple and need no brackets.
				pattern.append('|');
			}
			appendAsRegEx(true, patterns[i], pattern);
		}
		return createPattern(pattern.toString(), true, true, isCaseSensitive,
				false);
	}

	public static StringBuffer appendAsRegEx(boolean isStringMatcher,
			String pattern, StringBuffer buffer) {
		boolean isEscaped = false;
		for (int i = 0; i < pattern.length(); i++) {
			char c = pattern.charAt(i);
			switch (c) {
			// the backslash
			case '\\':
				// the backslash is escape char in string matcher
				if (isStringMatcher && !isEscaped) {
					isEscaped = true;
				} else {
					buffer.append("\\\\"); //$NON-NLS-1$
					isEscaped = false;
				}
				break;
			// characters that need to be escaped in the regex.
			case '(':
			case ')':
			case '{':
			case '}':
			case '.':
			case '[':
			case ']':
			case '$':
			case '^':
			case '+':
			case '|':
				if (isEscaped) {
					buffer.append("\\\\"); //$NON-NLS-1$
					isEscaped = false;
				}
				buffer.append('\\');
				buffer.append(c);
				break;
			case '?':
				if (isStringMatcher && !isEscaped) {
					buffer.append('.');
				} else {
					buffer.append('\\');
					buffer.append(c);
					isEscaped = false;
				}
				break;
			case '*':
				if (isStringMatcher && !isEscaped) {
					buffer.append(".*"); //$NON-NLS-1$
				} else {
					buffer.append('\\');
					buffer.append(c);
					isEscaped = false;
				}
				break;
			default:
				if (isEscaped) {
					buffer.append("\\\\"); //$NON-NLS-1$
					isEscaped = false;
				}
				buffer.append(c);
				break;
			}
		}
		if (isEscaped) {
			buffer.append("\\\\"); //$NON-NLS-1$
			isEscaped = false;
		}
		return buffer;
	}

}
