/*******************************************************************************
 * 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.ant.internal.ui.editor;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormatter;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;

/**
 * Auto edit strategy for Ant build files
 * Current does special indenting.
 */
public class AntAutoEditStrategy extends DefaultIndentLineAutoEditStrategy {
	
	private AntModel fModel;
	private int fAccumulatedChange= 0;
	
	public AntAutoEditStrategy(AntModel model) {
		fModel= model;
	}
	
	/**
	 * Sets the indentation based on the Ant element node that contains the offset
	 * of the document command.
	 *
	 * @param d the document to work on
	 * @param c the command to deal with
	 */
	private synchronized void autoIndentAfterNewLine(IDocument d, DocumentCommand c) {
		
		if (c.offset == -1 || d.getLength() == 0 || fModel.getProjectNode(false) == null) {
			return;
		}
		
		int position= (c.offset == d.getLength() ? c.offset  - 1 : c.offset);
		AntElementNode node= fModel.getProjectNode(false).getNode(position - fAccumulatedChange);
		if (node == null) {
			return;
		}
		
		try {
			StringBuffer correct= XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), d);
			if (!nextNodeIsEndTag(c.offset, d)) {
				correct.append(XmlDocumentFormatter.createIndent());
			}
			StringBuffer buf= new StringBuffer(c.text);
			buf.append(correct);
			fAccumulatedChange+= buf.length();
			
			int line= d.getLineOfOffset(position);
			IRegion reg= d.getLineInformation(line);
			int lineEnd= reg.getOffset() + reg.getLength();
			int contentStart= findEndOfWhiteSpace(d, c.offset, lineEnd);
			
			c.length=  Math.max(contentStart - c.offset, 0);
			c.caretOffset= c.offset + buf.length();
			c.shiftsCaret= false;
			c.text= buf.toString();
	
		} catch (BadLocationException e) {
			AntUIPlugin.log(e);
		}
	}
	
	private boolean nextNodeIsEndTag(int offset, IDocument document) {
		if (offset + 1 > document.getLength()) {
			return false;
		}
		try {
			IRegion lineRegion= document.getLineInformationOfOffset(offset);
			offset= findEndOfWhiteSpace(document, offset, lineRegion.getOffset() + lineRegion.getLength());
			String nextChars= document.get(offset, 2).trim();
			if ("</".equals(nextChars) || "/>".equals(nextChars)) { //$NON-NLS-1$ //$NON-NLS-2$
				return true;
			}
		} catch (BadLocationException e) {
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.IAutoEditStrategy#customizeDocumentCommand(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.DocumentCommand)
	 */
	public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
		
		if (c.length == 0 && c.text != null && isLineDelimiter(d, c.text)) {
			autoIndentAfterNewLine(d, c);
		} else if (c.text.length() > 1) {
			smartPaste(d, c);
		}
	}
	
	 private boolean isLineDelimiter(IDocument document, String text) {
		String[] delimiters= document.getLegalLineDelimiters();
		if (delimiters != null)
			return TextUtilities.equals(delimiters, text) > -1;
		return false;
	}
	
	public synchronized void reconciled() {
		fAccumulatedChange= 0;
	}
	
	private void smartPaste(IDocument document, DocumentCommand command) {
		try {
			if (command.offset == -1 || document.getLength() == 0 || fModel.getProjectNode(false) == null) {
				return;
			}
			String origChange= command.text;
			int position= (command.offset == document.getLength() ? command.offset  - 1 : command.offset);
			AntElementNode node= fModel.getProjectNode(false).getNode(position - fAccumulatedChange);
			if (node == null) {
				return;
			}
			
			// eat any WS before the insertion to the beginning of the line
			int firstLine= 1; // don't format the first line if it has other content before it
			IRegion line= document.getLineInformationOfOffset(command.offset);
			String notSelected= document.get(line.getOffset(), command.offset - line.getOffset());
			if (notSelected.trim().length() == 0) {
				command.length += notSelected.length();
				command.offset= line.getOffset();
				firstLine= 0;
			}
			
			// handle the indentation computation inside a temporary document
			Document temp= new Document(command.text);
			
			// indent the first and second line
			// compute the relative indentation difference from the second line
			// (as the first might be partially selected) and use the value to
			// indent all other lines.
			boolean isIndentDetected= false;
			StringBuffer addition= new StringBuffer();
			int insertLength= 0;
			int lines= temp.getNumberOfLines();
			for (int l= firstLine; l < lines; l++) { // we don't change the number of lines while adding indents
				
				IRegion r= temp.getLineInformation(l);
				int lineOffset= r.getOffset();
				int lineLength= r.getLength();
				
				if (lineLength == 0) { // don't modify empty lines
					continue;
				}
				
				if (!isIndentDetected){
					
					// indent the first pasted line
					StringBuffer current= XmlDocumentFormatter.getLeadingWhitespace(lineOffset, temp);
					StringBuffer correct= XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), document);
					correct.append(XmlDocumentFormatter.createIndent());
					
					insertLength= subtractIndent(correct, current, addition);
					isIndentDetected= true;
				}
				
				// relatively indent all pasted lines 
				if (insertLength > 0) {
					addIndent(temp, l, addition);
				} else if (insertLength < 0) {
					cutIndent(temp, l, -insertLength);
				}	
			}
			
			// modify the command
			if (!origChange.equals(temp.get())) {
				fAccumulatedChange+=  temp.getLength();
				command.text= temp.get();
			}
			
		} catch (BadLocationException e) {
			AntUIPlugin.log(e);
		}
	}
	
	/**
	 * Indents line <code>line</code> in <code>document</code> with <code>indent</code>.
	 * Leaves leading comment signs alone.
	 * 
	 * @param document the document
	 * @param line the line
	 * @param indent the indentation to insert
	 * @throws BadLocationException on concurrent document modification
	 */
	private void addIndent(Document document, int line, CharSequence indent) throws BadLocationException {
		IRegion region= document.getLineInformation(line);
		int insert= region.getOffset();
		
		// insert indent
		document.replace(insert, 0, indent.toString());
	}
	
	/**
	 * Cuts the visual equivalent of <code>toDelete</code> characters out of the
	 * indentation of line <code>line</code> in <code>document</code>.
	 * 
	 * @param document the document
	 * @param line the line
	 * @param toDelete the number of space equivalents to delete.
	 * @throws BadLocationException on concurrent document modification
	 */
	private void cutIndent(Document document, int line, int toDelete) throws BadLocationException {
		IRegion region= document.getLineInformation(line);
		int from= region.getOffset();
		int endOffset= region.getOffset() + region.getLength();
		
		int to= from;
		while (toDelete > 0 && to < endOffset) {
			char ch= document.getChar(to);
			if (!Character.isWhitespace(ch))
				break;
			toDelete -= computeVisualLength(ch);
			if (toDelete >= 0) {
				to++;
			} else {
				break;
			}
		}
		
		document.replace(from, to - from, null);
	}
	
	/**
	 * Returns the visual length of a given character taking into
	 * account the visual tabulator length.
	 * 
	 * @param ch the character to measure
	 * @return the visual length of <code>ch</code>
	 */
	private int computeVisualLength(char ch) {
		if (ch == '\t') {
			return getVisualTabLengthPreference();
		} 
			
		return 1;
	}
	
	/**
	 * Returns the visual length of a given <code>CharSequence</code> taking into
	 * account the visual tabulator length.
	 * 
	 * @param seq the string to measure
	 * @return the visual length of <code>seq</code>
	 */
	private int computeVisualLength(CharSequence seq) {
		int size= 0;
		int tablen= getVisualTabLengthPreference();
		
		for (int i= 0; i < seq.length(); i++) {
			char ch= seq.charAt(i);
			if (ch == '\t') {
				size += tablen - size % tablen;
			} else {
				size++;
			}
		}
		return size;
	}
	
	/**
	 * Computes the difference of two indentations and returns the difference in
	 * length of current and correct. If the return value is positive, <code>addition</code>
	 * is initialized with a substring of that length of <code>correct</code>.
	 * 
	 * @param correct the correct indentation
	 * @param current the current indentation (might contain non-whitespace)
	 * @param difference a string buffer - if the return value is positive, it will be cleared and set to the substring of <code>current</code> of that length
	 * @return the difference in length of <code>correct</code> and <code>current</code> 
	 */
	private int subtractIndent(CharSequence correct, CharSequence current, StringBuffer difference) {
		int c1= computeVisualLength(correct);
		int c2= computeVisualLength(current);
		int diff= c1 - c2;
		if (diff <= 0) {
			return diff;
		}
		
		difference.setLength(0);
		int len= 0, i= 0;
		while (len < diff) {
			char c= correct.charAt(i++);
			difference.append(c);
			len += computeVisualLength(c);
		}
		
		return diff;
	}
	
	/**
	 * The preference setting for the visual tabulator display.
	 *  
	 * @return the number of spaces displayed for a tabulator in the editor
	 */
	private int getVisualTabLengthPreference() {
		return AntUIPlugin.getDefault().getCombinedPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH);
	}
}
