/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.dom;

import org.eclipse.jdt.core.compiler.CharOperation;

/**
 * Internal class.
 * @since 3.1
 */
class BindingKeyScanner {
	
	static final int START = -1;
	static final int PACKAGE = 0;
	static final int TYPE = 1;
	static final int FIELD = 2;
	static final int METHOD = 3;
	static final int ARRAY = 4;
	static final int LOCAL_VAR = 5;
	static final int END = 6;
	
	int index = 0, start;
	char[] source;
	int token = START;

	BindingKeyScanner(char[] source) {
		this.source = source;
	}
	
	char[] getTokenSource() {
		int length = this.index-this.start;
		char[] result = new char[length];
		System.arraycopy(this.source, this.start, result, 0, length);
		return result;
	}
	
	boolean isAtFieldOrMethodStart() {
		return 
			this.index+1 < this.source.length
			&& this.source[this.index+1] == '.';
	}
	
	boolean isAtLocalVariableStart() {
		return 
			this.index < this.source.length
			&& this.source[this.index] == '#';
	}
	
	boolean isAtMemberTypeStart() {
		return 
			this.index < this.source.length
			&& (this.source[this.index] == '$'
				|| (this.source[this.index] == '.' && this.source[this.index-1] == '>'));
	}
	
	boolean isAtParametersStart() {
		char currentChar;
		return 
			this.index > 0
			&& this.index < this.source.length
			&& ((currentChar = this.source[this.index]) == '<'
				|| currentChar == '%');
	}
	
	boolean isAtTypeParameterStart() {
		return 
			this.index+1 < this.source.length
			&& this.source[this.index+1] == 'T';
	}
	
	boolean isAtTypeVariableStart() {
		return 
			this.index+3 < this.source.length
			&& this.source[this.index+3] == ':';
	}

	boolean isAtTypeStart() {
		return this.index+1 < this.source.length && "LIZVCDBFJS[".indexOf(this.source[this.index+1]) != -1; //$NON-NLS-1$
	}
	
	boolean isAtWildCardStart() {
		return this.index+1 < this.source.length && "*+-".indexOf(this.source[this.index+1]) != -1; //$NON-NLS-1$
	}
	
	int nextToken() {
		int previousTokenEnd = this.index;
		this.start = this.index;
		int length = this.source.length;
		while (this.index <= length) {
			char currentChar = this.index == length ? Character.MIN_VALUE : this.source[this.index];
			switch (currentChar) {
				case 'B':
				case 'C':
				case 'D':
				case 'F':
				case 'I':
				case 'J':
				case 'S':
				case 'V':
				case 'Z':
					// base type
					if (this.index == previousTokenEnd) {
						this.index++;
						this.token = TYPE;
						return this.token;
					}
					break;
				case 'L':
				case 'T':
					if (this.index == previousTokenEnd) {
						this.start = this.index+1;
					}
					break;
				case ';':
				case '$':
					if (this.index == previousTokenEnd) {
						this.start = this.index+1;
						previousTokenEnd = this.start;
					} else {
						this.token = TYPE;
						return this.token;
					}
					break;
				case '.':
				case '%':
				case ':':
					this.start = this.index+1;
					previousTokenEnd = this.start;
					break;
				case '[':
					while (this.index < length && this.source[this.index] == '[')
						this.index++;
					this.token = ARRAY;
					return this.token;
				case '<':
					if (this.index == previousTokenEnd) {
						this.start = this.index+1;
						previousTokenEnd = this.start;
					} else if (this.start > 0) {
						switch (this.source[this.start-1]) {
							case '.':
								if (this.source[this.start-2] == '>')
									// case of member type where enclosing type is parameterized
									this.token = TYPE;
								else
									this.token = METHOD;
								return this.token;
							default:
								this.token = TYPE;
								return this.token;
						}
					} 
					break;
				case '(':
					this.token = METHOD;
					return this.token;
				case ')':
					this.start = ++this.index;
					this.token = END;
					return this.token;
				case '#':
					if (this.index == previousTokenEnd) {
						this.start = this.index+1;
						previousTokenEnd = this.start;
					} else {
						this.token = LOCAL_VAR;
						return this.token;
					}
					break;
				case Character.MIN_VALUE:
					switch (this.token) {
						case START:
							this.token = PACKAGE;
							break;
						case METHOD:
						case LOCAL_VAR:
							this.token = LOCAL_VAR;
							break;
						case TYPE:
							if (this.index > this.start && this.source[this.start-1] == '.')
								this.token = FIELD;
							else
								this.token = END;
							break;
						default:
							this.token = END;
							break;
					}
					return this.token;
				case '*':
				case '+':
				case '-':
					this.index++;
					this.token = TYPE;
					return this.token;
			}
			this.index++;
		}
		this.token = END;
		return this.token;
	}
	
	void skipMethodSignature() {
		char currentChar;
		while (this.index < this.source.length && (currentChar = this.source[this.index]) != '#' && currentChar != '%')
			this.index++;
	}
	
	void skipParametersEnd() {
		while (this.index < this.source.length && this.source[this.index] != '>')
			this.index++;
		this.index++;
	}
	
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		switch (this.token) {
			case START:
				buffer.append("START: "); //$NON-NLS-1$
				break;
			case PACKAGE:
				buffer.append("PACKAGE: "); //$NON-NLS-1$
				break;
			case TYPE:
				buffer.append("TYPE: "); //$NON-NLS-1$
				break;
			case FIELD:
				buffer.append("FIELD: "); //$NON-NLS-1$
				break;
			case METHOD:
				buffer.append("METHOD: "); //$NON-NLS-1$
				break;
			case ARRAY:
				buffer.append("ARRAY: "); //$NON-NLS-1$
				break;
			case LOCAL_VAR:
				buffer.append("LOCAL VAR: "); //$NON-NLS-1$
				break;
			case END:
				buffer.append("END: "); //$NON-NLS-1$
				break;
		}
		if (this.index < 0) {
			buffer.append("**"); //$NON-NLS-1$
			buffer.append(this.source);
		} else if (this.index <= this.source.length) {
			buffer.append(CharOperation.subarray(this.source, 0, this.start));
			buffer.append('*');
			if (this.start <= this.index) {
				buffer.append(CharOperation.subarray(this.source, this.start, this.index));
				buffer.append('*');
				buffer.append(CharOperation.subarray(this.source, this.index, this.source.length));
			} else {
				buffer.append('*');
				buffer.append(CharOperation.subarray(this.source, this.start, this.source.length));
			}
		} else {
			buffer.append(this.source);
			buffer.append("**"); //$NON-NLS-1$
		}
		return buffer.toString();
	}

}
