package org.eclipse.wst.jsdt.web.ui.internal.format;

import java.util.LinkedList;
import java.util.Map;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IDocumentPartitioningListener;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TypedPosition;
import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IFormattingContext;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.jsdt.core.ICompilationUnit;
import org.eclipse.wst.jsdt.core.IJavaProject;
import org.eclipse.wst.jsdt.core.JavaCore;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.core.formatter.CodeFormatter;
import org.eclipse.wst.jsdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.wst.jsdt.internal.formatter.DefaultCodeFormatter;
import org.eclipse.wst.jsdt.web.core.internal.java.JSPTranslationUtil;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.text.rules.StructuredTextPartitioner;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

public class FormattingStrategyJSPJava extends ContextBasedFormattingStrategy{
	/** Documents to be formatted by this strategy */
	private final LinkedList fDocuments= new LinkedList();
	/** Partitions to be formatted by this strategy */
	private final LinkedList fPartitions= new LinkedList();
	
	private static final int regionStartIndentLevel=1;
	
	private int startIndentLevel;

	/**
	 * Creates a new java formatting strategy.
 	 */
	public FormattingStrategyJSPJava() {
		super();
	}
	
	private class partitionerAttachedChangeListener implements IDocumentPartitioningListener{
		
		private IDocument attachedDoc;
		
		partitionerAttachedChangeListener(IDocument attachedDoc){
			this.attachedDoc=attachedDoc;
		}
	
		public void documentPartitioningChanged(IDocument document) {
			if (document==attachedDoc && document instanceof IDocumentExtension3) {
				IDocumentExtension3 extension3= (IDocumentExtension3) document;
				String[] partitionings= extension3.getPartitionings();
				Vector partitioners = new Vector();
				for (int i= 0; i < partitionings.length; i++) {
					IDocumentPartitioner partitioner= extension3.getDocumentPartitioner(partitionings[i]);
					if (partitioner instanceof StructuredTextPartitioner) {
						IDOMModel xmlModel = null;
						try {
							xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(document);
							xmlModel.reinit();
						}catch(Exception e){
							System.out.println("Exception in adapter for model re-init"+e);
						} finally {
							if (xmlModel != null) {
								xmlModel.releaseFromRead();
							}
						}
						document.removeDocumentPartitioningListener(this);
					}
				}
			}
			
		}
	}

	/*
	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#format()
	 */
	public void format() {
		super.format();
		final IStructuredDocument document= (IStructuredDocument)fDocuments.removeFirst();
		final TypedPosition partition= (TypedPosition)fPartitions.removeFirst();
	
		if (document != null) {
			try {
				JSPTranslationUtil translationUtil = new JSPTranslationUtil(document);
				ICompilationUnit cu = translationUtil.getCompilationUnit();
				if (cu != null) {
					String cuSource = cu.getSource();
					
					int javaStart = translationUtil.getTranslation().getJavaOffset(partition.getOffset());
					int javaLength =  partition.getLength();
					TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, cuSource, javaStart, javaLength, startIndentLevel, TextUtilities.getDefaultLineDelimiter(document), getPreferences());
					IDocument doc = translationUtil.getTranslation().getJavaDocument();
					edit.apply(doc);
					String replaceText =  TextUtilities.getDefaultLineDelimiter(document) + getIndentationString(getPreferences(),startIndentLevel) + (doc.get(edit.getOffset(), edit.getLength())).trim() + TextUtilities.getDefaultLineDelimiter(document);
				
					/* this is necisary since SSE disconnects document partitioners..  Because of that, the 
					 * replaced regions are considered 'partitionless' when the linestyle provider trys to 
					 * color them. 
					 * 
					 */
					document.replaceText(document, partition.getOffset(), partition.getLength(), replaceText);
					document.addDocumentPartitioningListener(new partitionerAttachedChangeListener(document));			
				}
			}catch(BadLocationException e){
				
			}catch(JavaModelException e){
				
			}
		}
 	}

	/*
	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
	 */
	public void formatterStarts(final IFormattingContext context) {
		fPartitions.addLast(context.getProperty(FormattingContextProperties.CONTEXT_PARTITION));
		fDocuments.addLast(context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM));
		
		startIndentLevel = regionStartIndentLevel + 0;
		
		Map projectOptions = (Map)context.getProperty(FormattingContextProperties.CONTEXT_PREFERENCES);
		if(projectOptions==null ){
			IDocument doc = (IDocument)context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM);
			context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, getProjectOptions(doc));
		}	 
		super.formatterStarts(context);
	
	}

	/*
	 * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
	 */
	public void formatterStops() {
		super.formatterStops();
		fPartitions.clear();
		fDocuments.clear();
		startIndentLevel=0;
	}
	
	public String getIndentationString(Map options, int indentationLevel){
		DefaultCodeFormatter formatter = new DefaultCodeFormatter(options);
		return formatter.createIndentationString(indentationLevel);
	}
	
	private Map getProjectOptions(IDocument baseDocument){
		IJavaProject javaProject = null;
		IDOMModel xmlModel = null;
		Map options = null;
		try {
			xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(baseDocument);
			String baseLocation = xmlModel.getBaseLocation();
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			IPath filePath = new Path(baseLocation);
			IProject project = null;
			if (filePath.segmentCount() > 0) {
				project = root.getProject(filePath.segment(0));
			}

			if(project!=null)
				javaProject = JavaCore.create(project);
		} finally {
			if (xmlModel != null) {
				xmlModel.releaseFromRead();
			}
		}
		
		if(javaProject!=null){
			options = javaProject.getOptions(true);
		}
		return options;	
	}
	
	private Map getNodeFromRegion(IDocument baseDocument){
		IJavaProject javaProject = null;
		IDOMModel xmlModel = null;
		Map options = null;
		try {
			xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(baseDocument);
			
		} finally {
			if (xmlModel != null) {
				xmlModel.releaseFromRead();
			}
		}
		
		if(javaProject!=null){
			options = javaProject.getOptions(true);
		}
		return options;	
	}
}
