/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.text.folding;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.preference.IPreferenceStore;

import org.eclipse.jface.text.BadLocationException;
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.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.projection.IProjectionListener;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionViewer;

import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IParent;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;

import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.text.folding.IJavaFoldingStructureProvider;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor;
import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;


/**
 * Updates the projection model of a class file or compilation unit.
 *
 * @since 3.0
 */
public class DefaultJavaFoldingStructureProvider implements IProjectionListener, IJavaFoldingStructureProvider {
	
	private static class JavaProjectionAnnotation extends ProjectionAnnotation {
		
		private IJavaElement fJavaElement;
		private boolean fIsComment;
		
		public JavaProjectionAnnotation(IJavaElement element, boolean isCollapsed, boolean isComment) {
			super(isCollapsed);
			fJavaElement= element;
			fIsComment= isComment;
		}
		
		public IJavaElement getElement() {
			return fJavaElement;
		}
		
		public void setElement(IJavaElement element) {
			fJavaElement= element;
		}
		
		public boolean isComment() {
			return fIsComment;
		}
		
		public void setIsComment(boolean isComment) {
			fIsComment= isComment;
		}
	}
	
	private class ElementChangedListener implements IElementChangedListener {
		
		/*
		 * @see org.eclipse.jdt.core.IElementChangedListener#elementChanged(org.eclipse.jdt.core.ElementChangedEvent)
		 */
		public void elementChanged(ElementChangedEvent e) {
			IJavaElementDelta delta= findElement(fInput, e.getDelta());
			if (delta != null)
				processDelta(delta);
		}
		
		private IJavaElementDelta findElement(IJavaElement target, IJavaElementDelta delta) {
			
			if (delta == null || target == null)
				return null;
			
			IJavaElement element= delta.getElement();
			
			if (element.getElementType() > IJavaElement.CLASS_FILE)
				return null;
			
			if (target.equals(element))
				return delta;				
			
			IJavaElementDelta[] children= delta.getAffectedChildren();
			if (children == null || children.length == 0)
				return null;
				
			for (int i= 0; i < children.length; i++) {
				IJavaElementDelta d= findElement(target, children[i]);
				if (d != null)
					return d;
			}
			
			return null;
		}		
	}
	
	
	private IDocument fCachedDocument;
	
	private ITextEditor fEditor;
	private ProjectionViewer fViewer;
	private IJavaElement fInput;
	private IElementChangedListener fElementListener;
	
	private boolean fAllowCollapsing= false;
	private boolean fCollapseJavadoc= false;
	private boolean fCollapseImportContainer= true;
	private boolean fCollapseInnerTypes= true;
	private boolean fCollapseMethods= false;
	
	public DefaultJavaFoldingStructureProvider() {
	}
	
	public void install(ITextEditor editor, ProjectionViewer viewer) {
		if (editor instanceof JavaEditor) {
			fEditor= editor;
			fViewer= viewer;
			fViewer.addProjectionListener(this);
		}
	}
	
	public void uninstall() {
		if (isInstalled()) {
			projectionDisabled();
			fViewer.removeProjectionListener(this);
			fViewer= null;
			fEditor= null;
		}
	}
	
	protected boolean isInstalled() {
		return fEditor != null;
	}
		
	/*
	 * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
	 */
	public void projectionEnabled() {
		if (fEditor instanceof JavaEditor) {
			initialize();
			fElementListener= new ElementChangedListener();
			JavaCore.addElementChangedListener(fElementListener);
		}
	}
	
	/*
	 * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
	 */
	public void projectionDisabled() {
		fCachedDocument= null;
		if (fElementListener != null) {
			JavaCore.removeElementChangedListener(fElementListener);
			fElementListener= null;
		}
	}
		
	public void initialize() {
		
		if (!isInstalled())
			return;
		
		initializePreferences();
		
		try {
			
			IDocumentProvider provider= fEditor.getDocumentProvider();
			fCachedDocument= provider.getDocument(fEditor.getEditorInput());
			fAllowCollapsing= true;
			
			if (fEditor instanceof CompilationUnitEditor) {
				IWorkingCopyManager manager= JavaPlugin.getDefault().getWorkingCopyManager();
				fInput= manager.getWorkingCopy(fEditor.getEditorInput());
			} else if (fEditor instanceof ClassFileEditor) {
				IClassFileEditorInput editorInput= (IClassFileEditorInput) fEditor.getEditorInput();
				fInput= editorInput.getClassFile();
			}
			
			if (fInput != null) {
				ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
				if (model != null) {
					Map additions= computeAdditions((IParent) fInput);
					model.removeAllAnnotations();
					model.replaceAnnotations(null, additions);
				}
			}
			
		} finally {
			fCachedDocument= null;
			fAllowCollapsing= false;
		}
	}

	private void initializePreferences() {
		IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
		fCollapseInnerTypes= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INNERTYPES);
		fCollapseImportContainer= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_IMPORTS);
		fCollapseJavadoc= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_JAVADOC);
		fCollapseMethods= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_METHODS);
	}

	private Map computeAdditions(IParent parent) {
		Map map= new HashMap();
		try {
			computeAdditions(parent.getChildren(), map);
		} catch (JavaModelException x) {
		}
		return map;
	}

	private void computeAdditions(IJavaElement[] elements, Map map) throws JavaModelException {
		for (int i= 0; i < elements.length; i++) {
			IJavaElement element= elements[i];
			
			computeAdditions(element, map);
			
			if (element instanceof IParent) {
				IParent parent= (IParent) element;
				computeAdditions(parent.getChildren(), map);
			}
		}
	}

	private void computeAdditions(IJavaElement element, Map map) {
		
		boolean createProjection= false;
		
		boolean collapse= false;
		switch (element.getElementType()) {
			
			case IJavaElement.IMPORT_CONTAINER:
				collapse= fAllowCollapsing && fCollapseImportContainer;
				createProjection= true;
				break;
			case IJavaElement.TYPE:
				collapse= fAllowCollapsing && fCollapseInnerTypes && isInnerType((IType) element);
				createProjection= true;
				break;
			case IJavaElement.METHOD:
				collapse= fAllowCollapsing && fCollapseMethods;
				createProjection= true;
				break;
		}
		
		if (createProjection) {
			IRegion[] regions= computeProjectionRanges(element);
			if (regions != null) {
				// comments
				for (int i= 0; i < regions.length - 1; i++) {
					Position position= createProjectionPosition(regions[i]);
					if (position != null)
						map.put(new JavaProjectionAnnotation(element, fAllowCollapsing && fCollapseJavadoc, true), position);
				}
				// code
				Position position= createProjectionPosition(regions[regions.length - 1]);
				if (position != null)
					map.put(new JavaProjectionAnnotation(element, collapse, false), position);
			}
		}
	}

	private boolean isInnerType(IType type) {
		
		try {
			return type.isMember();
		} catch (JavaModelException x) {
			IJavaElement parent= type.getParent();
			if (parent != null) {
				int parentType= parent.getElementType();
				return (parentType != IJavaElement.COMPILATION_UNIT && parentType != IJavaElement.CLASS_FILE);
			}
		}
		
		return false;		
	}

	private IRegion[] computeProjectionRanges(IJavaElement element) {
		
		try {
			if (element instanceof ISourceReference) {
				ISourceReference reference= (ISourceReference) element;
				ISourceRange range= reference.getSourceRange();
				String contents= reference.getSource();
				if (contents == null)
					return null;
				
				IScanner scanner= ToolFactory.createScanner(true, false, false, false);
				scanner.setSource(contents.toCharArray());
				List regions= new ArrayList();
				int shift= range.getOffset();
				int start= shift;
				while (true) {
					
					int token= scanner.getNextToken();
					start= shift + scanner.getCurrentTokenStartPosition();
					
					switch (token) {
						case ITerminalSymbols.TokenNameCOMMENT_JAVADOC:
						case ITerminalSymbols.TokenNameCOMMENT_BLOCK: {
							int end= shift + scanner.getCurrentTokenEndPosition() + 1;
							regions.add(new Region(start, end - start));
						}
						case ITerminalSymbols.TokenNameCOMMENT_LINE:
							continue;
					}
					
					break;
				}
				
				regions.add(new Region(start, range.getOffset() + range.getLength() - start));
				
				if (regions.size() > 0) {
					IRegion[] result= new IRegion[regions.size()];
					regions.toArray(result);
					return result;
				}
			}
		} catch (JavaModelException e) {
		} catch (InvalidInputException e) {
		}
		
		return null;
	}
	
	private Position createProjectionPosition(IRegion region) {
		
		if (fCachedDocument == null)
			return null;
		
		try {
			
			int start= fCachedDocument.getLineOfOffset(region.getOffset());
			int end= fCachedDocument.getLineOfOffset(region.getOffset() + region.getLength());
			if (start != end) {
				int offset= fCachedDocument.getLineOffset(start);
				int endOffset= fCachedDocument.getLineOffset(end + 1);
				return new Position(offset, endOffset - offset);
			}
			
		} catch (BadLocationException x) {
		}
		
		return null;
	}
		
	protected void processDelta(IJavaElementDelta delta) {
		
		if (!isInstalled())
			return;
		
		ProjectionAnnotationModel model= (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
		if (model == null)
			return;
		
		try {
			
			IDocumentProvider provider= fEditor.getDocumentProvider();
			fCachedDocument= provider.getDocument(fEditor.getEditorInput());
			fAllowCollapsing= false;
			
			Map additions= new HashMap();
			List deletions= new ArrayList();
			List updates= new ArrayList();
			
			Map updated= computeAdditions((IParent) fInput);
			Map previous= createAnnotationMap(model);
			
			
			Iterator e= updated.keySet().iterator();
			while (e.hasNext()) {
				JavaProjectionAnnotation annotation= (JavaProjectionAnnotation) e.next();
				IJavaElement element= annotation.getElement();
				Position position= (Position) updated.get(annotation);
				
				List annotations= (List) previous.get(element);
				if (annotations == null) {
					
					additions.put(annotation, position);
					
				} else {
					
					Iterator x= annotations.iterator();
					while (x.hasNext()) {
						JavaProjectionAnnotation a= (JavaProjectionAnnotation) x.next();
						if (annotation.isComment() == a.isComment()) {
							Position p= model.getPosition(a);
							if (p != null && !position.equals(p)) {
								p.setOffset(position.getOffset());
								p.setLength(position.getLength());
								updates.add(a);
							}
							x.remove();
							break;
						}
					}
										
					if (annotations.isEmpty())
						previous.remove(element);
				}
			}
			
			e= previous.values().iterator();
			while (e.hasNext()) {
				List list= (List) e.next();
				int size= list.size();
				for (int i= 0; i < size; i++)
					deletions.add(list.get(i));
			}
			
			match(model, deletions, additions, updates);
			
			Annotation[] removals= new Annotation[deletions.size()];
			deletions.toArray(removals);
			Annotation[] changes= new Annotation[updates.size()];
			updates.toArray(changes);
			model.modifyAnnotations(removals, additions, changes);
			
		} finally {
			fCachedDocument= null;
			fAllowCollapsing= true;
		}
	}
	
	private void match(ProjectionAnnotationModel model, List deletions, Map additions, List changes) {
		if (deletions.isEmpty() || (additions.isEmpty() && changes.isEmpty()))
			return;
		
		List newDeletions= new ArrayList();
		List newChanges= new ArrayList();
		
		Iterator deletionIterator= deletions.iterator();
		outer: while (deletionIterator.hasNext()) {
			JavaProjectionAnnotation deleted= (JavaProjectionAnnotation) deletionIterator.next();
			Position deletedPosition= model.getPosition(deleted);
			if (deletedPosition == null)
				continue;
			
			Iterator changesIterator= changes.iterator();
			while (changesIterator.hasNext()) {
				JavaProjectionAnnotation changed= (JavaProjectionAnnotation) changesIterator.next();
				if (deleted.isComment() == changed.isComment()) {
					Position changedPosition= model.getPosition(changed);
					if (changedPosition == null)
						continue;
					
					if (deletedPosition.getOffset() == changedPosition.getOffset()) {
						
						deletedPosition.setLength(changedPosition.getLength());
						deleted.setElement(changed.getElement());
						
						deletionIterator.remove();
						newChanges.add(deleted);
						
						changesIterator.remove();
						newDeletions.add(changed);
						
						continue outer;
					}
				}
			}
			
			Iterator additionsIterator= additions.keySet().iterator();
			while (additionsIterator.hasNext()) {
				JavaProjectionAnnotation added= (JavaProjectionAnnotation) additionsIterator.next();
				if (deleted.isComment() == added.isComment()) {
					Position addedPosition= (Position) additions.get(added);
					
					if (deletedPosition.getOffset() == addedPosition.getOffset()) {
						
						deletedPosition.setLength(addedPosition.getLength());
						deleted.setElement(added.getElement());
						
						deletionIterator.remove();
						newChanges.add(deleted);
						
						additionsIterator.remove();
						
						break;
					}
				}
			}
		}
		
		deletions.addAll(newDeletions);
		changes.addAll(newChanges);
	}

	private Map createAnnotationMap(IAnnotationModel model) {
		Map map= new HashMap();
		Iterator e= model.getAnnotationIterator();
		while (e.hasNext()) {
			Object annotation= e.next();
			if (annotation instanceof JavaProjectionAnnotation) {
				JavaProjectionAnnotation java= (JavaProjectionAnnotation) annotation;
				List list= (List) map.get(java.getElement());
				if (list == null) {
					list= new ArrayList(2);
					map.put(java.getElement(), list);
				}
				list.add(java);
			}
		}
		return map;
	}
}
