/*******************************************************************************
 * Copyright (c) 2000, 2009 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.jdt.internal.ui.javaeditor;

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

import org.eclipse.core.runtime.CoreException;

import org.eclipse.core.resources.IResource;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.source.IAnnotationModel;

import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;

import org.eclipse.ui.editors.text.FileDocumentProvider;

import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jdt.ui.text.JavaTextTools;

import org.eclipse.jdt.internal.ui.IResourceLocator;
import org.eclipse.jdt.internal.ui.JavaPlugin;


/**
 * A document provider for class files. Class files can be either inside
 */
public class ClassFileDocumentProvider extends FileDocumentProvider {

	/**
	 * An input change listener to request the editor to reread the input.
	 */
	public interface InputChangeListener {
		void inputChanged(IClassFileEditorInput input);
	}

	/**
	 * Synchronizes the document with external resource changes.
	 */
	protected class ClassFileSynchronizer implements IElementChangedListener {

		protected IClassFileEditorInput fInput;
		protected IPackageFragmentRoot fPackageFragmentRoot;

		/**
		 * Default constructor.
		 * 
		 * @param input the class file editor input
		 */
		public ClassFileSynchronizer(IClassFileEditorInput input) {

			fInput= input;

			IJavaElement parent= fInput.getClassFile().getParent();
			while (parent != null && !(parent instanceof IPackageFragmentRoot)) {
				parent= parent.getParent();
			}
			fPackageFragmentRoot= (IPackageFragmentRoot) parent;
		}

		/**
		 * Installs the synchronizer.
		 */
		public void install() {
			JavaCore.addElementChangedListener(this);
		}

		/**
		 * Uninstalls the synchronizer.
		 */
		public void uninstall() {
			JavaCore.removeElementChangedListener(this);
		}

		/*
		 * @see IElementChangedListener#elementChanged
		 */
		public void elementChanged(ElementChangedEvent e) {
			check(fPackageFragmentRoot, e.getDelta());
		}

		/**
		 * Recursively check whether the class file has been deleted.
		 * 
		 * @param input the package fragment root
		 * @param delta the Java element delta
		 * @return <code>true</code> if delta processing can be stopped
		 */
		protected boolean check(IPackageFragmentRoot input, IJavaElementDelta delta) {
			IJavaElement element= delta.getElement();

			if ((delta.getKind() & IJavaElementDelta.REMOVED) != 0 || (delta.getFlags() & IJavaElementDelta.F_CLOSED) != 0) {
				// http://dev.eclipse.org/bugs/show_bug.cgi?id=19023
				if (element.equals(input.getJavaProject()) || element.equals(input)) {
					handleDeleted(fInput);
					return true;
				}
			}

			if (((delta.getFlags() & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0) && input.equals(element)) {
				handleDeleted(fInput);
				return true;
			}

			if (((delta.getFlags() & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) && input.equals(element)) {
				handleDeleted(fInput);
				return true;
			}

			IJavaElementDelta[] subdeltas= delta.getAffectedChildren();
			for (int i= 0; i < subdeltas.length; i++) {
				if (check(input, subdeltas[i]))
					return true;
			}

			if ((delta.getFlags() & IJavaElementDelta.F_SOURCEDETACHED) != 0 ||
				(delta.getFlags() & IJavaElementDelta.F_SOURCEATTACHED) != 0)
			{
				IClassFile file= fInput != null ? fInput.getClassFile() : null;
				IJavaProject project= input != null ? input.getJavaProject() : null;

				boolean isOnClasspath= false;
				if (file != null && project != null)
					isOnClasspath= project.isOnClasspath(file);

				if (isOnClasspath) {
					fireInputChanged(fInput);
					return false;
				} else {
					handleDeleted(fInput);
					return true;
				}
			}

			return false;
		}
	}

	/**
	 * Correcting the visibility of <code>FileSynchronizer</code>.
	 */
	protected class _FileSynchronizer extends FileSynchronizer {
		public _FileSynchronizer(IFileEditorInput fileEditorInput) {
			super(fileEditorInput);
		}
	}

	/**
	 * Bundle of all required informations.
	 */
	protected class ClassFileInfo extends FileInfo {

		ClassFileSynchronizer fClassFileSynchronizer= null;

		ClassFileInfo(IDocument document, IAnnotationModel model, _FileSynchronizer fileSynchronizer) {
			super(document, model, fileSynchronizer);
		}

		ClassFileInfo(IDocument document, IAnnotationModel model, ClassFileSynchronizer classFileSynchronizer) {
			super(document, model, null);
			fClassFileSynchronizer= classFileSynchronizer;
		}
	}

	/** Input change listeners. */
	private List<InputChangeListener> fInputListeners= new ArrayList<InputChangeListener>();

	/**
	 * Creates a new document provider.
	 */
	public ClassFileDocumentProvider() {
		super();
	}

	/*
	 * @see StorageDocumentProvider#setDocumentContent(IDocument, IEditorInput)
	 */
	@Override
	protected boolean setDocumentContent(IDocument document, IEditorInput editorInput, String encoding) throws CoreException {
		if (editorInput instanceof IClassFileEditorInput) {
			IClassFile classFile= ((IClassFileEditorInput) editorInput).getClassFile();
			String source= classFile.getSource();
			if (source == null)
				source= ""; //$NON-NLS-1$
			document.set(source);
			return true;
		}
		return super.setDocumentContent(document, editorInput, encoding);
	}

	/**
	 * Creates an annotation model derived from the given class file editor input.
	 *
	 * @param classFileEditorInput the editor input from which to query the annotations
	 * @return the created annotation model
	 * @exception CoreException if the editor input could not be accessed
	 */
	protected IAnnotationModel createClassFileAnnotationModel(IClassFileEditorInput classFileEditorInput) throws CoreException {
		IResource resource= null;
		IClassFile classFile= classFileEditorInput.getClassFile();

		IResourceLocator locator= (IResourceLocator) classFile.getAdapter(IResourceLocator.class);
		if (locator != null)
			resource= locator.getContainingResource(classFile);

		if (resource != null) {
			ClassFileMarkerAnnotationModel model= new ClassFileMarkerAnnotationModel(resource);
			model.setClassFile(classFile);
			return model;
		}

		return null;
	}

	/*
	 * @see org.eclipse.ui.editors.text.StorageDocumentProvider#createEmptyDocument()
	 * @since 3.1
	 */
	@Override
	protected IDocument createEmptyDocument() {
		IDocument document= FileBuffers.getTextFileBufferManager().createEmptyDocument(null, LocationKind.IFILE);
		if (document instanceof ISynchronizable)
			((ISynchronizable)document).setLockObject(new Object());
		return document;
	}

	/*
	 * @see AbstractDocumentProvider#createDocument(Object)
	 */
	@Override
	protected IDocument createDocument(Object element) throws CoreException {
		IDocument document= super.createDocument(element);
		if (document != null) {
			JavaTextTools tools= JavaPlugin.getDefault().getJavaTextTools();
			tools.setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
		}
		return document;
	}

	/*
	 * @see AbstractDocumentProvider#createElementInfo(Object)
	 */
	@Override
	protected ElementInfo createElementInfo(Object element) throws CoreException {

		if (element instanceof IClassFileEditorInput) {

			IClassFileEditorInput input = (IClassFileEditorInput) element;
			ExternalClassFileEditorInput external= null;
			if (input instanceof ExternalClassFileEditorInput)
				external= (ExternalClassFileEditorInput) input;

			if (external != null) {
				try {
					refreshFile(external.getFile());
				} catch (CoreException x) {
					handleCoreException(x, JavaEditorMessages.ClassFileDocumentProvider_error_createElementInfo);
				}
			}

			IDocument d= createDocument(input);
			IAnnotationModel m= createClassFileAnnotationModel(input);

			if (external != null) {
				ClassFileInfo info= new ClassFileInfo(d, m,  (_FileSynchronizer) null);
				info.fModificationStamp= computeModificationStamp(external.getFile());
				info.fEncoding= getPersistedEncoding(element);
				return info;
			} else if (input instanceof InternalClassFileEditorInput) {
				ClassFileSynchronizer s= new ClassFileSynchronizer(input);
				s.install();
				ClassFileInfo info= new ClassFileInfo(d, m, s);
				info.fEncoding= getPersistedEncoding(element);
				return info;
			}
		}

		return null;
	}

	/*
	 * @see FileDocumentProvider#disposeElementInfo(Object, ElementInfo)
	 */
	@Override
	protected void disposeElementInfo(Object element, ElementInfo info) {
		ClassFileInfo classFileInfo= (ClassFileInfo) info;
		if (classFileInfo.fClassFileSynchronizer != null) {
			classFileInfo.fClassFileSynchronizer.uninstall();
			classFileInfo.fClassFileSynchronizer= null;
		}

		super.disposeElementInfo(element, info);
	}

	/*
	 * @see org.eclipse.ui.texteditor.IDocumentProviderExtension3#isSynchronized(java.lang.Object)
	 * @since 3.0
	 */
	@Override
	public boolean isSynchronized(Object element) {
		Object elementInfo= getElementInfo(element);
		if (elementInfo instanceof ClassFileInfo) {
			IClassFileEditorInput input= (IClassFileEditorInput)element;
			IResource resource;
			try {
				resource= input.getClassFile().getUnderlyingResource();
			} catch (JavaModelException e) {
				return true;
			}
			return resource == null || resource.isSynchronized(IResource.DEPTH_ZERO);
		}
		return false;
	}

	/**
	 * Handles the deletion of the element underlying the given class file editor input.
	 * @param input the editor input
	 */
	protected void handleDeleted(IClassFileEditorInput input) {
		if (input == null) {
			fireElementDeleted(input);
			return;
		}

		if (input.exists())
			return;

		IClassFile cf= input.getClassFile();
		try {
			/*
			 * Let's try to find the class file - maybe the JAR changed
			 */
			IType type= cf.getType();
			IJavaProject project= cf.getJavaProject();
			if (project != null) {
				type= project.findType(type.getFullyQualifiedName());
				if (type != null) {
					IEditorInput editorInput= EditorUtility.getEditorInput(type.getParent());
					if (editorInput instanceof IClassFileEditorInput) {
						fireInputChanged((IClassFileEditorInput)editorInput);
						return;
					}
				}
			}
		} catch (JavaModelException x) {
			// Don't log and fall through: element deleted
		}

		fireElementDeleted(input);

	}

	/**
	 * Fires input changes to input change listeners.
	 * 
	 * @param input the class file editor input
	 */
	protected void fireInputChanged(IClassFileEditorInput input) {
		List<InputChangeListener> list= new ArrayList<InputChangeListener>(fInputListeners);
		for (Iterator<InputChangeListener> i = list.iterator(); i.hasNext();)
			i.next().inputChanged(input);
	}

	/**
	 * Adds an input change listener.
	 * 
	 * @param listener the input change listener
	 */
	public void addInputChangeListener(InputChangeListener listener) {
		fInputListeners.add(listener);
	}

	/**
	 * Removes an input change listener.
	 * 
	 * @param listener the input change listener
	 */
	public void removeInputChangeListener(InputChangeListener listener) {
		fInputListeners.remove(listener);
	}

}
