/*******************************************************************************
 * Copyright (c) 2000, 2005 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 API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.text;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.Token;


/**
 * An implementation of <code>IRule</code> capable of detecting words.
 * <p>
 * Word rules also allow for the association of tokens with specific words.
 * That is, not only can the rule be used to provide tokens for exact matches,
 * but also for the generalized notion of a word in the context in which it is used.
 * A word rules uses a word detector to determine what a word is.</p>
 * <p>
 * This word rule allows a word detector to be shared among different word matchers.
 * Its up to the word matchers to decide if a word matches and, in this a case, which
 * token is associated with that word.
 * </p>
 *
 * @see IWordDetector
 * @since 3.0
 */
public class CombinedWordRule implements IRule {

	/**
	 * Word matcher, that associates matched words with tokens.
	 */
	public static class WordMatcher {

		/** The table of predefined words and token for this matcher */
		private Map fWords= new HashMap();

		/**
		 * Adds a word and the token to be returned if it is detected.
		 *
		 * @param word the word this rule will search for, may not be <code>null</code>
		 * @param token the token to be returned if the word has been found, may not be <code>null</code>
		 */
		public void addWord(String word, IToken token) {
			Assert.isNotNull(word);
			Assert.isNotNull(token);

			fWords.put(new CharacterBuffer(word), token);
		}

		/**
		 * Returns the token associated to the given word and the scanner state.
		 *
		 * @param scanner the scanner
		 * @param word the word
		 * @return the token or <code>null</code> if none is associated by this matcher
		 */
		public IToken evaluate(ICharacterScanner scanner, CharacterBuffer word) {
			IToken token= (IToken) fWords.get(word);
			if (token != null)
				return token;
			return Token.UNDEFINED;
		}

		/**
		 * Removes all words.
		 */
		public void clearWords() {
			fWords.clear();
		}
	}

	/**
	 * Character buffer, mutable <b>or</b> suitable for use as key in hash maps.
	 */
	public static class CharacterBuffer {

		/** Buffer content */
		private char[] fContent;
		/** Buffer content size */
		private int fLength= 0;

		/** Is hash code cached? */
		private boolean fIsHashCached= false;
		/** The hash code */
		private int fHashCode;

		/**
		 * Initialize with the given capacity.
		 *
		 * @param capacity the initial capacity
		 */
		public CharacterBuffer(int capacity) {
			fContent= new char[capacity];
		}

		/**
		 * Initialize with the given content.
		 *
		 * @param string the initial content
		 */
		public CharacterBuffer(String content) {
			fContent= content.toCharArray();
			fLength= content.length();
		}

		/**
		 * Empties this buffer.
		 */
		public void clear() {
			fIsHashCached= false;
			fLength= 0;
		}

		/**
		 * Appends the given character to the buffer.
		 *
		 * @param c the character
		 */
		public void append(char c) {
			fIsHashCached= false;
			if (fLength == fContent.length) {
				char[] old= fContent;
				fContent= new char[old.length << 1];
				System.arraycopy(old, 0, fContent, 0, old.length);
			}
			fContent[fLength++]= c;
		}

		/**
		 * Returns the length of the content.
		 *
		 * @return the length
		 */
		public int length() {
			return fLength;
		}

		/**
		 * Returns the content as string.
		 *
		 * @return the content
		 */
		public String toString() {
			return new String(fContent, 0, fLength);
		}

		/**
		 * Returns the character at the given position.
		 *
		 * @param i the position
		 * @return the character at position <code>i</code>
		 */
		public char charAt(int i) {
			return fContent[i];
		}

		/*
		 * @see java.lang.Object#hashCode()
		 */
		public int hashCode() {
			if (fIsHashCached)
				return fHashCode;

			int hash= 0;
			for (int i= 0, n= fLength; i < n; i++)
				hash= 29*hash + fContent[i];
			fHashCode= hash;
			fIsHashCached= true;
			return hash;
		}


		/*
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			if (!(obj instanceof CharacterBuffer))
				return false;
			CharacterBuffer buffer= (CharacterBuffer) obj;
			int length= buffer.length();
			if (length != fLength)
				return false;
			for (int i= 0; i < length; i++)
				if (buffer.charAt(i) != fContent[i])
					return false;
			return true;
		}

		/**
		 * Is the content equal to the given string?
		 *
		 * @param string the string
		 * @return <code>true</code> iff the content is the same character sequence as in the string
		 */
		public boolean equals(String string) {
			int length= string.length();
			if (length != fLength)
				return false;
			for (int i= 0; i < length; i++)
				if (string.charAt(i) != fContent[i])
					return false;
			return true;
		}
	}

	/** Internal setting for the uninitialized column constraint */
	private static final int UNDEFINED= -1;

	/** The word detector used by this rule */
	private IWordDetector fDetector;
	/** The default token to be returned on success and if nothing else has been specified. */
	private IToken fDefaultToken;
	/** The column constraint */
	private int fColumn= UNDEFINED;
	/** Buffer used for pattern detection */
	private CharacterBuffer fBuffer= new CharacterBuffer(16);

	/** List of word matchers */
	private List fMatchers= new ArrayList();

	/**
	 * Creates a rule which, with the help of an word detector, will return the token
	 * associated with the detected word. If no token has been associated, the scanner
	 * will be rolled back and an undefined token will be returned in order to allow
	 * any subsequent rules to analyze the characters.
	 *
	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
	 *
	 * @see #addWord(String, IToken)
	 */
	public CombinedWordRule(IWordDetector detector) {
		this(detector, null, Token.UNDEFINED);
	}

	/**
	 * Creates a rule which, with the help of an word detector, will return the token
	 * associated with the detected word. If no token has been associated, the
	 * specified default token will be returned.
	 *
	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
	 * @param defaultToken the default token to be returned on success
	 *		if nothing else is specified, may not be <code>null</code>
	 *
	 * @see #addWord(String, IToken)
	 */
	public CombinedWordRule(IWordDetector detector, IToken defaultToken) {
		this(detector, null, defaultToken);
	}

	/**
	 * Creates a rule which, with the help of an word detector, will return the token
	 * associated with the detected word. If no token has been associated, the scanner
	 * will be rolled back and an undefined token will be returned in order to allow
	 * any subsequent rules to analyze the characters.
	 *
	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
	 * @param matcher the initial word matcher
	 *
	 * @see #addWord(String, IToken)
	 */
	public CombinedWordRule(IWordDetector detector, WordMatcher matcher) {
		this(detector, matcher, Token.UNDEFINED);
	}

	/**
	 * Creates a rule which, with the help of an word detector, will return the token
	 * associated with the detected word. If no token has been associated, the
	 * specified default token will be returned.
	 *
	 * @param detector the word detector to be used by this rule, may not be <code>null</code>
	 * @param matcher the initial word matcher
	 * @param defaultToken the default token to be returned on success
	 *		if nothing else is specified, may not be <code>null</code>
	 *
	 * @see #addWord(String, IToken)
	 */
	public CombinedWordRule(IWordDetector detector, WordMatcher matcher, IToken defaultToken) {

		Assert.isNotNull(detector);
		Assert.isNotNull(defaultToken);

		fDetector= detector;
		fDefaultToken= defaultToken;
		if (matcher != null)
			addWordMatcher(matcher);
	}


	/**
	 * Adds the given matcher.
	 *
	 * @param matcher the matcher
	 */
	public void addWordMatcher(WordMatcher matcher) {
		fMatchers.add(matcher);
	}

	/**
	 * Sets a column constraint for this rule. If set, the rule's token
	 * will only be returned if the pattern is detected starting at the
	 * specified column. If the column is smaller then 0, the column
	 * constraint is considered removed.
	 *
	 * @param column the column in which the pattern starts
	 */
	public void setColumnConstraint(int column) {
		if (column < 0)
			column= UNDEFINED;
		fColumn= column;
	}

	/*
	 * @see IRule#evaluate(ICharacterScanner)
	 */
	public IToken evaluate(ICharacterScanner scanner) {
		int c= scanner.read();
		if (fDetector.isWordStart((char) c)) {
			if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {

				fBuffer.clear();
				do {
					fBuffer.append((char) c);
					c= scanner.read();
				} while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
				scanner.unread();

				for (int i= 0, n= fMatchers.size(); i < n; i++) {
					IToken token= ((WordMatcher) fMatchers.get(i)).evaluate(scanner, fBuffer);
					if (!token.isUndefined())
						return token;
				}

				if (fDefaultToken.isUndefined())
					unreadBuffer(scanner);

				return fDefaultToken;
			}
		}

		scanner.unread();
		return Token.UNDEFINED;
	}

	/**
	 * Returns the characters in the buffer to the scanner.
	 *
	 * @param scanner the scanner to be used
	 */
	private void unreadBuffer(ICharacterScanner scanner) {
		for (int i= fBuffer.length() - 1; i >= 0; i--)
			scanner.unread();
	}
}
