/*******************************************************************************
 * Copyright (c) 2004, 2006 John-Mason P. Shackelford 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:
 *     John-Mason P. Shackelford - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui.editor.formatter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.ant.internal.ui.editor.templates.AntContext;
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultPositionUpdater;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateVariable;

/**
 * Utility class for using the ant code formatter in contexts where an IDocument
 * containing the text to format is not readily available.
 */
public class XmlFormatter {

	private static final String POS_CATEGORY= "tempAntFormatterCategory"; //$NON-NLS-1$
	
    /**
     * Format the text using the ant code formatter.
     * 
     * @param text
     *            The text to format. Must be a non-null value.
     * @param prefs
     *            Preferences to use for this format operation. If null, the
     *            preferences currently set in the plug-in's preferences store
     *            are used.
     * @return The formatted text.
     */
    public static String format(String text, FormattingPreferences prefs) {
        
      return format(text, prefs, -1);
    }
    
    private static String format(String text, FormattingPreferences prefs, int indent) {
    	 Assert.isNotNull(text);
         
         FormattingPreferences applyPrefs;
         if(prefs == null) {
             applyPrefs = new FormattingPreferences();
         } else {
             applyPrefs = prefs;
         }
         
         IDocument doc = new Document();
         doc.set(text);
         new AntDocumentSetupParticipant().setup(doc);

         format(applyPrefs, doc, indent);

         return doc.get();
    }

	private static void format(FormattingPreferences prefs, IDocument doc, int indent) {
		MultiPassContentFormatter formatter = new MultiPassContentFormatter(
                AntDocumentSetupParticipant.ANT_PARTITIONING,
                IDocument.DEFAULT_CONTENT_TYPE);

        formatter.setMasterStrategy(new XmlDocumentFormattingStrategy(prefs, indent));
        formatter.setSlaveStrategy(new XmlElementFormattingStrategy(prefs),
                AntEditorPartitionScanner.XML_TAG);
        formatter.format(doc, new Region(0, doc.getLength()));
	}

	/**
     * Format the text using the ant code formatter using the preferences
     * settings in the plug-in preference store.
     * 
     * @param text
     *            The text to format. Must be a non-null value.
     * @return The formatted text.
     */
    public static String format(String text) {
        return format(text,null);
    }
    
    public static void format(TemplateBuffer templateBuffer, AntContext antContext, FormattingPreferences prefs) {	
    	String templateString= templateBuffer.getString();
    	IDocument fullDocument= new Document(antContext.getDocument().get());
    	
    	int completionOffset= antContext.getCompletionOffset();
    	try {
    		//trim any starting whitespace
			IRegion lineRegion= fullDocument.getLineInformationOfOffset(completionOffset);
			String lineString= fullDocument.get(lineRegion.getOffset(), lineRegion.getLength());
			lineString= trimBegin(lineString);
			fullDocument.replace(lineRegion.getOffset(), lineRegion.getLength(), lineString);
		} catch (BadLocationException e1) {
			return;
		}
    	TemplateVariable[] variables= templateBuffer.getVariables();
		int[] offsets= variablesToOffsets(variables, completionOffset);
		
		IDocument origTemplateDoc= new Document(fullDocument.get());
		try {
			origTemplateDoc.replace(completionOffset, antContext.getCompletionLength(), templateString);
		} catch (BadLocationException e) {
			return; // don't format if the document has changed
		}
		
    	IDocument templateDocument= createDocument(origTemplateDoc.get(), createPositions(offsets));
    	
    	String leadingText= getLeadingText(fullDocument, antContext.getAntModel(), completionOffset);
    	String newTemplateString= leadingText + templateString;
    	int indent= XmlDocumentFormatter.computeIndent(leadingText, prefs.getTabWidth());
    	
    	newTemplateString= format(newTemplateString, prefs, indent);
    	
    	try {
    		templateDocument.replace(completionOffset, templateString.length(), newTemplateString);
		} catch (BadLocationException e) {
			return;
		}
		Position[] positions= null;
		try {
			positions= templateDocument.getPositions(POS_CATEGORY);
		} catch (BadPositionCategoryException e2) {
		}
    	//offsetsToVariables(offsets, variables, completionOffset);
		positionsToVariables(positions, variables, completionOffset);
    	templateBuffer.setContent(newTemplateString, variables);
    }
    
    private static void positionsToVariables(Position[] positions, TemplateVariable[] variables, int start) {
		for (int i= 0; i != variables.length; i++) {
		    TemplateVariable variable= variables[i];
		    
			int[] offsets= new int[variable.getOffsets().length];
			for (int j= 0; j != offsets.length; j++) {
				offsets[j]= positions[j].getOffset() - start;
			}
			
		 	variable.setOffsets(offsets);   
		}
	}	
    private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException {
		Document doc= new Document(string);
		try {
			if (positions != null) {
				
				doc.addPositionCategory(POS_CATEGORY);
				doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
					protected boolean notDeleted() {
						if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
							fPosition.offset= fOffset + fLength; // deleted positions: set to end of remove
							return false;
						}
						return true;
					}
				});
				for (int i= 0; i < positions.length; i++) {
					try {
						doc.addPosition(POS_CATEGORY, positions[i]);
					} catch (BadLocationException e) {
						throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + string.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
					}
				}
			}
		} catch (BadPositionCategoryException cannotHappen) {
			// can not happen: category is correctly set up
		}
		return doc;
	}
    
    public static String trimBegin(String toBeTrimmed) {
		
		int i= 0;
		while ((i != toBeTrimmed.length()) && Character.isWhitespace(toBeTrimmed.charAt(i))) {
			i++;
		}

		return toBeTrimmed.substring(i);
	}
    
    private static int[] variablesToOffsets(TemplateVariable[] variables, int start) {
		List list= new ArrayList();
		for (int i= 0; i != variables.length; i++) {
		    int[] offsets= variables[i].getOffsets();
		    for (int j= 0; j != offsets.length; j++) {
				list.add(new Integer(offsets[j]));
		    }
		}
		
		int[] offsets= new int[list.size()];
		for (int i= 0; i != offsets.length; i++) {
			offsets[i]= ((Integer) list.get(i)).intValue() + start;
		}

		Arrays.sort(offsets);

		return offsets;	    
	}
	
	/**
	 * Returns the indentation level at the position of code completion.
	 */
	private static String getLeadingText(IDocument document, IAntModel model, int completionOffset) {
		AntProjectNode project= model.getProjectNode(false);
		if (project == null) {
			return ""; //$NON-NLS-1$
		}
		AntElementNode node= project.getNode(completionOffset);// - fAccumulatedChange);
		if (node == null) {
			return ""; //$NON-NLS-1$
		}
		
		StringBuffer buf= new StringBuffer();
		buf.append(XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), document));
		buf.append(XmlDocumentFormatter.createIndent());
		return buf.toString();
	}
	
	 private static Position[] createPositions(int[] positions) {
    	Position[] p= null;
		
		if (positions != null) {
			p= new Position[positions.length];
			for (int i= 0; i < positions.length; i++) {
				p[i]= new Position(positions[i], 0);
			}
		}
		return p;
    }
}
