//------------------------------------------------------------------------------
// 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.publishing.services.index;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.epf.library.util.ResourceHelper;


public class KeyWordStatic {

	// note: pattern with [^>] does not match when there are non-english
	// characters, maybe it's a jre bug?
	public static final Pattern p_index_ref = Pattern.compile(
			"<a\\s+?(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
	// "<a\\s+?([^>]*?(name\\s*=\\s*\"XE_|class\\s*=\\s*\"index).*?)>",
	// Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	/**
	 * get the key words with key and text description. There are two types of
	 * index format: 1. old format: <a name="KEY__TEXT" ...> 2. new format: <a
	 * class="index" name="bookmark" key="KEY" text="TEXT" ...> TEXT part is
	 * optional
	 */
	public static List getKeyWords(String realString) {
		if (realString == null) {
			System.err
					.println("KeyWordStatic:getKeyWords\n" + HelpMessages.INPUT_PARAMETER_NULL); //$NON-NLS-1$
			return null;
		}

		List anchors = new ArrayList(2); //$NON-NLS-1$

		Matcher m = p_index_ref.matcher(realString);
		while (m.find()) {
			String attributes = m.group(1);
			if (attributes.length() == 0) {
				continue;
			}
			
			Map attrMap = ResourceHelper.getTagAttributes(attributes);
			String keyWord = (String) attrMap.get(ResourceHelper.TAG_ATTR_NAME);
			if (keyWord == null || keyWord.length() == 0) {
				continue;
			}

			String cls = (String) attrMap.get(ResourceHelper.TAG_ATTR_CLASS);
			String key = null;
			String text = null;
			if ((cls != null)
					&& cls.equals(ResourceHelper.TAG_ATTR_VALUE_INDEX)) {
				key = (String) attrMap.get(ResourceHelper.TAG_ATTR_KEY);
				text = (String) attrMap.get(ResourceHelper.TAG_ATTR_TEXT);
			}
			// The getKeyWordPrefix() returns the tag which is used to delimit
			// keywords.
			// Currently this tag is XE and is defined in keywordconfig.txt
			if ((key != null)
					|| keyWord.startsWith(KeyWordIndexHelper.defObj
							.getKeyWordPrefix())) {
				anchors.add(new KeyWordDef(keyWord, key, text));
			}
		}
		return anchors;

	}

	public static String convertKeyWord(String keyWord) {
		return convertKeyWord(keyWord, null, null);
	}

	public static String convertKeyWord(String keyWord, String key, String text) {

		if (keyWord == null) {
			System.err
					.println("KeyWordStatic:convertKeyWord\n" + HelpMessages.INPUT_PARAMETER_NULL); //$NON-NLS-1$
			return null;
		}
		IO.printDebug("convertKeyWord " + keyWord); // Error if we get a keyword
		// that does not contain the
		// tag. //$NON-NLS-1$
		if ((key != null) && (key.length() > 0)) {
			if (text == null || text.length() == 0) {
				return key;
			} else {
				return key + KeyWordIndexHelper.defObj.levelSeparatorReplace
						+ text;
			}
		}

		if (!keyWord.startsWith(KeyWordIndexHelper.defObj.getKeyWordPrefix())) {
			System.out
					.println("KeyWordStatic:convertKeyWord\n" + keyWord + HelpMessages.KEYWORD_SYNTAX_ERROR + KeyWordIndexHelper.defObj.getKeyWordPrefix()); //$NON-NLS-1$
			return null;
		}

		// Remove the first three characters from the keyWord (namely XE_).
		String tmpK = keyWord.substring(3);
		String tmp = ""; //$NON-NLS-1$
		int i = 0;
		int pos = 0;
		while (i != -1) {
			// getKeyWordLevelSeparator() is hard-coded as __
			i = tmpK.indexOf(KeyWordIndexHelper.defObj
					.getKeyWordLevelSeparator(), pos);
			if (i != -1) {
				// Insert a separator between keywords, which in this case is
				// the ":"
				tmp += tmpK.substring(pos, i);
				tmp += KeyWordIndexHelper.defObj.levelSeparatorReplace;
				pos = i + 2;
			} else {
				tmp += tmpK.substring(pos);
			}
		}
		return tmp.replace('_', ' ');
	}

}