/*******************************************************************************
 * Copyright (c) 2003, 2004 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
 *******************************************************************************/
/*
 * Created on Nov 11, 2003
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.eclipse.jst.common.internal.annotations.core;

/**
 * @author Pat Kelley
 * 
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class AnnotationTagParser {

	private TagParseEventHandler handler;

	private char[] input;

	int pos;

	int endOfLastGoodAttParse;

	public AnnotationTagParser(TagParseEventHandler tp) {
		if (tp == null) {
			throw new IllegalArgumentException(AnnotationsCoreResources.getString("AnnotationTagParser.0")); //$NON-NLS-1$
		}
		handler = tp;
	}

	private boolean eos() {
		return pos >= input.length;
	}

	private boolean isWS(char c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t';
	}

	private void skipWS() {
		while (pos < input.length && (isWS(input[pos]) || input[pos] == '*')) {
			pos++;
		}
	}

	// Caller is expected to make sure the eos has not been reached.
	private char peek() {
		return input[pos];
	}

	// Caller is expected to check for EOS.
	private char nextChar() {
		return input[pos++];
	}

	private boolean isNextChar(char c) {
		if (eos())
			return false;
		return peek() == c;
	}

	private boolean isIDChar(char c) {
		return !isWS(c) && c != '=' && c != '@' && c != '\"';
	}

	private Token collectID() {
		StringBuffer b = new StringBuffer(16);
		Token t = new Token();

		t.setBeginning(pos);
		while (!eos() && isIDChar(peek())) {
			b.append(nextChar());
		}
		t.setEnd(pos - 1);
		t.setText(b.toString());
		return t;
	}

	private Token expectAttribName() {
		if (eos()) {
			return null;
		}
		int save = pos;

		Token retval = collectID();
		if (retval.length() == 0) {
			pos = save;
			return null;
		}
		return retval;
	}

	private Token expectTag() {
		if (eos()) {
			return null;
		}
		int savePos = pos;

		if (nextChar() != '@') {
			return null;
		}

		if (eos() || isWS(peek())) {
			return null;
		}

		Token retval = expectAttribName();

		if (retval.length() == 0) {
			pos = savePos + 1;
		}
		retval.setBeginning(savePos);

		// Save end of parse so we can pass it as the end of the parsed tag.
		endOfLastGoodAttParse = pos;
		return retval;
	}

	private Token expectQuotedValue() {
		skipWS();
		if (eos()) {
			return null;
		}

		Token tok = new Token();

		tok.setBeginning(pos);
		if (peek() != '\"') {
			return null;
		}
		nextChar();

		if (eos()) {
			return null;
		}

		StringBuffer b = new StringBuffer(64);

		while (!eos() && peek() != '\"') {
			b.append(nextChar());
		}
		if (!eos()) {
			nextChar();
		}

		tok.setEnd(pos - 1);
		tok.setText(b.toString());
		return tok;
	}

	private boolean expectAssign() {
		if (eos()) {
			return false;
		}

		if (nextChar() == '=') {
			return true;
		}
		pos--;
		return false;
	}

	private Token mkNullToken() {
		Token retval = new Token();

		retval.setBeginning(pos);
		retval.setEnd(pos - 1);
		retval.setText(""); //$NON-NLS-1$
		return retval;
	}

	private boolean parseNextAttribute() {
		skipWS();
		if (eos()) {
			return false;
		}
		Token key = collectID();

		if (key == null || key.length() == 0) {
			return false;
		}

		skipWS();
		if (eos()) {
			// Go ahead and report it, even though it is a partial attribute. (
			// we still fail here )
			handler.attribute(key, -1, mkNullToken());
			return false;
		}

		int eqPos = pos;

		if (!expectAssign()) {
			// Even though we won't parse this as a full attribute, go ahead and
			// call the handler with it. Some clients want to see partial
			// attributes.
			handler.attribute(key, -1, mkNullToken());
			return false;
		}
		skipWS();

		if (eos()) {
			// Same here - we fail on it, but we report it anyway
			handler.attribute(key, eqPos, mkNullToken());
			return false;
		}
		Token value = expectQuotedValue();

		if (value == null) {
			value = collectID();
			if (isNextChar('=')) {
				pos = value.getBeginning();
				value = mkNullToken();
			}
		}
		endOfLastGoodAttParse = pos;
		handler.attribute(key, eqPos, value);
		return true;
	}

	private void parseAttributes() {
		while (!eos() && parseNextAttribute()) {
			// loop while not end of string
		}
	}

	private void skipToTagChar() {
		while (!eos() && peek() != '@') {
			nextChar();
		}
	}

	public void setParserInput(char[] text) {
		input = text;
		pos = 0;
		endOfLastGoodAttParse = 0;
	}

	public void setParserInput(String text) {
		setParserInput(text.toCharArray());
	}

	public void parse() {
		while (!eos()) {
			skipToTagChar();
			Token tag = expectTag();
			if (tag == null) {
				break;
			}
			handler.annotationTag(tag);
			parseAttributes();
			handler.endOfTag(endOfLastGoodAttParse);
		}
	}

}