package org.eclipse.jdt.internal.core;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.jdt.internal.compiler.IProblem;
import org.eclipse.jdt.core.*;

import java.util.Vector;

/**
 * Implementation of a working copy compilation unit. A working
 * copy maintains the timestamp of the resource it was created
 * from.
 */

/* package */ class WorkingCopy extends CompilationUnit {

	
	/**
	 * A boolean indicating if this working copy has been
	 * destroyed. Once destroyed, it cannot be opened
	 * and non-handle info can not be accessed. This is
	 * never true if this compilation unit is not a working
	 * copy.
	 */
	protected boolean fDestroyed= false;
/**
 */
protected WorkingCopy(IPackageFragment parent, String name) {
	super(parent, name);
}
/**
 * @see IWorkingCopy
 */
public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
	CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force);
	runOperation(op, monitor);
}
/**
 * Returns a new element info for this element.
 */
protected OpenableElementInfo createElementInfo() {
	return new WorkingCopyElementInfo();
}
/**
 * @see IWorkingCopy
 */
public void destroy() {
	try {
		close();
	} catch (JavaModelException e) {
		// do nothing
	}
	fDestroyed= true;
}
/**
 * Working copies must be identical to be equal.
 *
 * @see Object#equals
 */
public boolean equals(Object o) {
	return this == o;
}
/**
 * @see IWorkingCopy
 */
public IJavaElement getOriginal(IJavaElement workingCopyElement) {
	//not a element contained in a compilation unit
	int javaElementType = workingCopyElement.getElementType();
	if (javaElementType < COMPILATION_UNIT || javaElementType == CLASS_FILE) {
		return null;
	}
	if (workingCopyElement instanceof BinaryMember) {
		return null;
	}
	IJavaElement parent = workingCopyElement.getParent();
	Vector hierarchy = new Vector(4);
	
	while (parent.getElementType() > COMPILATION_UNIT) {
		hierarchy.addElement(parent);
		parent = parent.getParent();
	}
	if (parent.getElementType() == COMPILATION_UNIT) {
		hierarchy.addElement(((ICompilationUnit)parent).getOriginalElement());
	}
	
	ICompilationUnit cu = (ICompilationUnit) getOriginalElement();
	if (javaElementType == COMPILATION_UNIT) {
		parent = workingCopyElement;
	}
	if (((ICompilationUnit) parent).isWorkingCopy() && !((ICompilationUnit) parent).getOriginalElement().equals(cu)) {
		return null;
	}
	switch (javaElementType) {
		case PACKAGE_DECLARATION :
			return cu.getPackageDeclaration(workingCopyElement.getElementName());
		case IMPORT_DECLARATION :
			return cu.getImport(workingCopyElement.getElementName());
		case TYPE :
			if (hierarchy.size() == 1) {
				return cu.getType(workingCopyElement.getElementName());
			} else {
				//inner type
				return getOriginalType(hierarchy).getType(workingCopyElement.getElementName());
			}
		case METHOD :
			IType type;
			if (hierarchy.size() == 2) {
				String typeName = ((IJavaElement) hierarchy.elementAt(0)).getElementName();
				type = cu.getType(typeName);
			} else {
				//inner type
				type = getOriginalType(hierarchy);
			}
			return type.getMethod(workingCopyElement.getElementName(), ((IMethod) workingCopyElement).getParameterTypes());
		case FIELD :
			if (hierarchy.size() == 2) {
				String typeName = ((IJavaElement) hierarchy.elementAt(0)).getElementName();
				type = cu.getType(typeName);
			} else {
				//inner type
				type = getOriginalType(hierarchy);
			}
			return type.getField(workingCopyElement.getElementName());
		case INITIALIZER :
			if (hierarchy.size() == 2) {
				String typeName = ((IJavaElement) hierarchy.elementAt(0)).getElementName();
				type = cu.getType(typeName);
			} else {
				//inner type
				type = getOriginalType(hierarchy);
			}
			return type.getInitializer(((Initializer) workingCopyElement).getOccurrenceCount());
		case COMPILATION_UNIT :
			return cu;
		default :
			return null;
	}
}
/**
 * @see IWorkingCopy
 */
public IJavaElement getOriginalElement() {
	return new CompilationUnit((IPackageFragment)getParent(), getElementName());
}
protected IType getOriginalType(Vector hierarchy) {
	int size = hierarchy.size() - 1;
	ICompilationUnit typeCU = (ICompilationUnit) hierarchy.elementAt(size);
	String typeName = ((IJavaElement) hierarchy.elementAt(size - 1)).getElementName();
	IType type = typeCU.getType(typeName);
	size= size - 2;
	while (size > -1) {
		typeName = ((IJavaElement) hierarchy.elementAt(size)).getElementName();
		type = ((IType) type).getType(typeName);
		size--;
	}
	return type;
}
/**
 * Returns <code>null<code> - a working copy does not have an underlying resource.
 *
 * @see IJavaElement
 */
public IResource getUnderlyingResource() throws JavaModelException {
	return null;
}
/**
 * @see IWorkingCopy
 */
public IJavaElement getWorkingCopy() throws JavaModelException {
	return this;
}
/**
 * @see IWorkingCopy
 */
public boolean isBasedOn(IResource resource) {
	if (resource.getType() != IResource.FILE) {
		return false;
	}
	if (fDestroyed) {
		return false;
	}
	try {
		// if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached
		// timestamp
		return ((CompilationUnitElementInfo) getElementInfo()).fTimestamp == ((IFile) resource).getModificationStamp();
	} catch (JavaModelException e) {
		return false;
	}
}
/**
 * @see IWorkingCopy
 */
public boolean isWorkingCopy() {
	return true;
}
/**
 * @see IOpenable
 * @see IWorkingCopy
 *
 * @exception JavaModelException attempting to open a read only element for something other than navigation
 * 	or if this is a working copy being opened after it has been destroyed.
 */
public void open(IProgressMonitor pm) throws JavaModelException {
	if (fDestroyed) {
		throw newNotPresentException();
	} else {
		super.open(pm);
	}
}
/**
 * @see Openable
 */
protected IBuffer openBuffer(IProgressMonitor pm) throws JavaModelException {
	ICompilationUnit original= (ICompilationUnit)this.getOriginalElement();
	IBuffer buf= getBufferManager().openBuffer((char[])original.getBuffer().getCharacters().clone(), pm, this, isReadOnly());
	buf.addBufferChangedListener(this);
	return buf;	
}
/**
 * @see IWorkingCopy
 */
public IMarker[] reconcile() throws JavaModelException {
	// create the delta builder (this remembers the current content of the cu)
	JavaElementDeltaBuilder deltaBuilder = new JavaElementDeltaBuilder(this);

	// update the element infos with the content of the working copy
	this.makeConsistent(null);

	// build the deltas
	deltaBuilder.buildDeltas();
	
	// fire the deltas
	boolean shouldFire = false;
	JavaModelManager manager = null;
	if (deltaBuilder.delta != null) {
		manager = (JavaModelManager)JavaModelManager.getJavaModelManager();
		if (deltaBuilder.delta.getAffectedChildren().length > 0) {
			manager.registerJavaModelDelta(deltaBuilder.delta);
			shouldFire = true;
		}
	}
	if (shouldFire)
		manager.fire();

	// report syntax problems
	return null;
/* DISABLED because of 1GAJJ3A: ITPJUI:WINNT - Deadlock in Java Editor
	try {
		WorkingCopyElementInfo info = (WorkingCopyElementInfo)JavaModelManager.getJavaModelManager().getInfo(this);
		IProblem[] problems = info.problems;
		int length; 
		IResource resource = getOriginalElement().getUnderlyingResource();
		
		// flush previous markers first
		IMarker[] markers = resource.findMarkers(IJavaModelMarker.TRANSIENT_PROBLEM, true,  IResource.DEPTH_ONE);
		resource.getWorkspace().deleteMarkers(markers);

		// create markers if needed
		if (problems == null || (length = problems.length) == 0) return null;
		markers = new IMarker[length];
		for (int i = 0; i < length; i++) {
			IProblem problem = problems[i];
			IMarker marker = resource.createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
			marker.setAttribute(IJavaModelMarker.ID, problem.getID());
			marker.setAttribute(IJavaModelMarker.CHAR_START, problem.getSourceStart());
			marker.setAttribute(IJavaModelMarker.CHAR_END, problem.getSourceEnd() + 1);
			marker.setAttribute(IJavaModelMarker.LINE_NUMBER, problem.getSourceLineNumber());
			marker.setAttribute(IMarker.LOCATION, "#" + problem.getSourceLineNumber());
			marker.setAttribute(IMarker.MESSAGE, problem.getMessage());
			marker.setAttribute(IMarker.PRIORITY, (problem.isWarning() ? IMarker.PRIORITY_LOW : IMarker.PRIORITY_HIGH));
			markers[i] = marker;
		}
		return markers;
	} catch (CoreException e) {
		throw new JavaModelException(e);
	}
*/
}
/**
 * @see IWorkingCopy
 */
public void restore() throws JavaModelException {
	if (!fDestroyed) {
		CompilationUnit original = (CompilationUnit) getOriginalElement();
		getBuffer().setContents(original.getContents());

		long timeStamp =
			((IFile) original.getUnderlyingResource()).getModificationStamp();
		if (timeStamp == IResource.NULL_STAMP) {
			throw new JavaModelException(
				new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
		}
		((CompilationUnitElementInfo) getElementInfo()).fTimestamp = timeStamp;
		makeConsistent(null);
	}
}
/**
 * @private Debugging purposes
 */
protected void toString(int tab, StringBuffer buffer) {
	buffer.append(this.tabString(tab));
	buffer.append("(working copy)\n"/*nonNLS*/);
	super.toString(tab, buffer);
}
}
