/*******************************************************************************
 * Copyright (c) 2005, 2008 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.core.internal.utility.jdt;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jpt.common.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

/**
 * This implementation will clean up some of the nasty Eclipse annotation
 * formatting (or lack thereof); e.g. arrays of annotations.
 */
public final class DefaultAnnotationEditFormatter
	implements AnnotationEditFormatter
{
	private static final DefaultAnnotationEditFormatter INSTANCE = new DefaultAnnotationEditFormatter();

	/**
	 * Return the singleton.
	 */
	public static DefaultAnnotationEditFormatter instance() {
		return INSTANCE;
	}

	/**
	 * Ensure single instance.
	 */
	private DefaultAnnotationEditFormatter() {
		super();
	}

	/**
	 * TODO
	 */
	public void format(IDocument doc, TextEdit editTree) throws MalformedTreeException, BadLocationException {
		TextEdit[] edits = editTree.getChildren();
		int len = edits.length;
		if (len == 0) {
			return;
		}

		MultiTextEdit extraEdits = new MultiTextEdit();
		for (int i = 0; i < len; i++) {
			TextEdit edit1 = edits[i];
			if ( ! (edit1 instanceof InsertEdit)) {
				continue;  // if the edit is not an insert, skip to the next edit
			}
			InsertEdit insert1 = (InsertEdit) edit1;
			int j = i + 1;
			if (j < len) {
				TextEdit edit2 = edits[j];
				if (edit2 instanceof InsertEdit) {
					InsertEdit insert2 = (InsertEdit) edit2;
					String text1 = insert1.getText();
					String text2 = insert2.getText();
					int offset1 = insert1.getOffset();
					int offset2 = insert2.getOffset();
					if (this.stringIsAnnotation(text1) && text2.equals(" ")) { //$NON-NLS-1$
						// an annotation was inserted before something on the same line;
						// replace the trailing space with a newline and appropriate indent
						extraEdits.addChild(new ReplaceEdit(offset2, 1, this.buildCR(doc, offset2)));
						i++;  // jump the index past 'edit2'
						continue;  // go to the next edit
					}
					int comma1Length = this.commaLength(text1);
					if ((comma1Length != 0) && this.stringIsAnnotation(text2)) {
						// an annotation was inserted in an array initializer on the
						// same line as the previous array element;
						// replace the preceding space with a newline and appropriate indent
						extraEdits.addChild(new ReplaceEdit(offset1 + comma1Length, text1.length() - comma1Length, this.buildCR(doc, offset1)));
						i++;  // jump the index past 'edit2'
						continue;  // go to the next edit
					}
				}
			}
			this.formatArrayInitializer(doc, insert1, extraEdits);
		}
		extraEdits.apply(doc, TextEdit.NONE);
	}

	/**
	 * If the insert edit is inserting an annotation containing an array of annotations as
	 * its value then format them nicely.
	 */
	private void formatArrayInitializer(IDocument doc, InsertEdit insertEdit, MultiTextEdit extraEdits) throws BadLocationException {
		String s = insertEdit.getText();
		if ( ! this.stringIsAnnotation(s)) {
			return;
		}
		int len = s.length();
		int pos = 1;  // skip '@'
		while (pos < len) {
			char c = s.charAt(pos);
			pos++;  // bump to just past first '('
			if (c == '(') {
				break;
			}
		}
		if (pos == len) {
			return;  // reached end of string
		}
		while (pos < len) {
			char c = s.charAt(pos);
			pos++;  // bump to just past first '{'
			if (c == '{') {
				break;
			}
			if (c != ' ') {
				return;
			}
		}
		if (pos == len) {
			return;  // reached end of string
		}
		// now look for '@' not inside parentheses and put in 
		// line delimeter and indent string before each
		int offset = insertEdit.getOffset();
		String indent = null;
		int parenDepth = 0;
		while (pos < len) {
			switch (s.charAt(pos)) {
				case '(' :
					parenDepth++;
					break;
				case ')' :
					parenDepth--;
					break;
				case '@' :
					if (parenDepth == 0) {
						if (indent == null) {
							indent = this.buildCR(doc, offset, "\t");  // TODO use tab preference? //$NON-NLS-1$
						}
						extraEdits.addChild(new InsertEdit(offset + pos, indent));
					}
					break;
				case '}' :
					if (parenDepth == 0) {
						extraEdits.addChild(new InsertEdit(offset + pos, this.buildCR(doc, offset)));
					}
					break;
			}
			pos++;
		}
	}

	/**
	 * Build a string containing a line delimeter and indenting characters 
	 * matching the indent level of the line containing the character offset
	 * (i.e. the new line's indent matches the current line).
	 */
	private String buildCR(IDocument doc, int offset) throws BadLocationException {
		return this.buildCR(doc, offset, ""); //$NON-NLS-1$
	}

	private String buildCR(IDocument doc, int offset, String suffix) throws BadLocationException {
		int line = doc.getLineOfOffset(offset);
		StringBuilder sb = new StringBuilder();
		sb.append(doc.getLineDelimiter(line));  // use same CR as current line

		int o = doc.getLineOffset(line);  // match the whitespace of the current line
		char c = doc.getChar(o++);
		while ((c == ' ') || (c == '\t')) {
			sb.append(c);
			c = doc.getChar(o++);
		}
		sb.append(suffix);
		return sb.toString();
	}

	/**
	 * Return whether the specified string is an annotation.
	 */
	private boolean stringIsAnnotation(String string) {
		return (string.length() > 1) && string.charAt(0) == '@';
	}

	/**
	 * If the specified string is a single comma, possibly surrounded by
	 * spaces, return the length of the substring containing the
	 * initial spaces and the comma.
	 */
	private int commaLength(String string) {
		boolean comma = false;
		int len = string.length();
		int result = 0;
		for (int i = 0; i < len; i++) {
			switch (string.charAt(i)) {
				case ' ' :
					if ( ! comma) {
						result++;  // space preceding comma
					}
					break;
				case ',' :
					if (comma) {
						return 0;  // second comma!
					}
					comma = true;
					result++;
					break;
				default:
					return 0;  // non-comma, non-space char
			}
		}
		return result;
	}

}
