package org.eclipse.ui.texteditor;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;

import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.util.Assert;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;



/**
 * An abstract base implementation of a shareable document provider.
 * <p>
 * Subclasses must implement <code>createDocument</code>,
 * <code>createAnnotationModel</code>, and <code>doSaveDocument</code>.
 * </p>
 */
public abstract class AbstractDocumentProvider implements IDocumentProvider, IDocumentProviderExtension {
	
	
		/**
		 * Collection of all information managed for a connected element.
		 */
		protected class ElementInfo implements IDocumentListener {
			
			/** The element for which the info is stored */
			public Object fElement;
			/** How often the element has been connected */
			public int fCount;
			/** Can the element be saved */
			public boolean fCanBeSaved;
			/** The element's document */
			public IDocument fDocument;
			/** The element's annotation model */
			public IAnnotationModel fModel;
			/** Has element state been validated */
			public boolean fIsStateValidated;
			
			
			/**
			 * Creates a new element info, initialized with the given
			 * document and annotation model.
			 *
			 * @param document the document
			 * @param model the annotation model
			 */
			public ElementInfo(IDocument document, IAnnotationModel model) {
				fDocument= document;
				fModel= model;
				fCount= 0;
				fCanBeSaved= false;
				fIsStateValidated= false;
			}
			
			/**
			 * An element info equals another object if this object is an element info
			 * and if the documents of the two element infos are equal.
			 * @see Object#equals
			 */
			public boolean equals(Object o) {
				if (o instanceof ElementInfo) {
					ElementInfo e= (ElementInfo) o;
					return fDocument.equals(e.fDocument);
				}
				return false;
			}
			
			/*
			 * @see Object#hashCode
			 */
			public int hashCode() {
				return fDocument.hashCode();
			}
			
			/*
			 * @see IDocumentListener#documentChanged(DocumentEvent)
			 */
			public void documentChanged(DocumentEvent event) {
				fCanBeSaved= true;
				removeUnchangedElementListeners(fElement, this);
				fireElementDirtyStateChanged(fElement, fCanBeSaved);
			}
			
			/*
			 * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
			 */
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
		};
		
	
	/** 
	 * Indicates whether this provider should behave as described in
	 * use case 5 of http://bugs.eclipse.org/bugs/show_bug.cgi?id=10806.
	 */ 
	static final boolean PR10806_UC5_ENABLED= false;
	
	/**
	 * Indicates whether this provider should behave as described in
	 * http://bugs.eclipse.org/bugs/show_bug.cgi?id=14469
	 * Notes: This contradicts <code>PR10806_UC5_ENABLED</code>.
	 */
	static final boolean PR14469_ENABLED= true;
	
	
	/** Information of all connected elements */
	private Map fElementInfoMap= new HashMap();
	/** The element state listeners */
	private List fElementStateListeners= new ArrayList();
	
	
	/**
	 * Creates a new document provider.
	 */
	protected AbstractDocumentProvider() {
	}
	
	/**
	 * Creates a textual representation for the given element, i.e. the
	 * document for the given element.<p>
	 * Subclasses must implement this method.
	 *
	 * @param element the element
	 * @return the document
	 * @exception CoreException if the document could not be created
	 */
	protected abstract IDocument createDocument(Object element) throws CoreException;
	
	/**
	 * Creates an annotation model for the given element. <p>
	 * Subclasses must implement this method.
	 *
	 * @param element the element
	 * @return the annotation model
	 * @exception CoreException if the annotation model could not be created
	 */
	protected abstract IAnnotationModel createAnnotationModel(Object element) throws CoreException;
	
	/**
	 * Performs the actual work of saving the given document provided for the 
	 * given element. <p>
	 * Subclasses must implement this method.
	 *
	 * @param monitor a progress monitor to report progress and request cancelation
	 * @param element the element
	 * @param document the document
	 * @param overwrite indicates whether an overwrite should happen if necessary
	 * @exception CoreException if document could not be stored to the given element
	 */
	protected abstract void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException;
	
	
	/**
	 * Returns the element info object for the given element.
	 *
	 * @param element the element
	 * @return the element info object, or <code>null</code> if none
	 */
	protected ElementInfo getElementInfo(Object element) {
		return (ElementInfo) fElementInfoMap.get(element);
	}
	
	/**
	 * Creates a new element info object for the given element.<p>
	 * This method is called from <code>connect</code> when an element info needs
	 * to be created. The <code>AbstractDocumentProvider</code> implementation 
	 * of this method returns a new element info object whose document and 
	 * annotation model are the values of <code>createDocument(element)</code> 
	 * and  <code>createAnnotationModel(element)</code>, respectively. Subclasses 
	 * may override.
	 *
	 * @param element the element
	 * @return a new element info object
	 * @exception CoreException if the document or annotation model could not be created
	 */
	protected ElementInfo createElementInfo(Object element) throws CoreException {
		return new ElementInfo(createDocument(element), createAnnotationModel(element));
	}
	
	/**
	 * Disposes of the given element info object. <p>
	 * This method is called when an element info is disposed. The 
	 * <code>AbstractDocumentProvider</code> implementation of this
	 * method does nothing. Subclasses may reimplement.
	 *
	 * @param element the element
	 * @param info the element info object
	 */
	protected void disposeElementInfo(Object element, ElementInfo info) {
	}
	
	/**
	 * Called on initial creation and when the dirty state of the element
	 * changes to <code>false</code>. Adds all listeners which must be 
	 * active as long as the element is not dirty. This method is called
	 * before <code>fireElementDirtyStateChanged</code> or <code>
	 * fireElementContentReplaced</code> is called.
	 * Subclasses may extend.
	 * 
	 * @param element the element
	 * @param info the element info object
	 */
	protected void addUnchangedElementListeners(Object element, ElementInfo info) {
		if (info.fDocument != null)
			info.fDocument.addDocumentListener(info);
	}
	
	/**
	 * Called when the given element gets dirty. Removes all listeners
	 * which must be active only when the element is not dirty. This 
	 * method is called before <code>fireElementDirtyStateChanged</code>
	 * or <code>fireElementContentReplaced</code> is called.
	 * Subclasses may extend.
	 * 
	 * @param element the element
	 * @param info the element info object
	 */
	protected void removeUnchangedElementListeners(Object element, ElementInfo info) {
		if (info.fDocument != null)
			info.fDocument.removeDocumentListener(info);
	}
	
	/**
	 * Enumerates the elements connected via this document provider.	
	 *
	 * @return the list of elements (element type: <code>Object</code>)
	 */
	protected Iterator getConnectedElements() {
		Set s= new HashSet();
		Set keys= fElementInfoMap.keySet();
		if (keys != null)
			s.addAll(keys);
		return s.iterator();
	}
	
	/*
	 * @see IDocumentProvider#connect
	 */
	public final void connect(Object element) throws CoreException {
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info == null) {
			
			info= createElementInfo(element);
			if (info == null) 
				info= new ElementInfo(null, null);
			
			info.fElement= element;
			
			addUnchangedElementListeners(element, info);
			
			fElementInfoMap.put(element, info);
		}	
		++ info.fCount;		
	}
	
	/*
	 * @see IDocumentProvider#disconnect
	 */
	public final void disconnect(Object element) {
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		
		if (info == null)
			return;
		
		if (info.fCount == 1) {
			
			fElementInfoMap.remove(element);
			removeUnchangedElementListeners(element, info);
			disposeElementInfo(element, info);
			
		} else
		 	-- info.fCount;
	}		
	
	
	/*
	 * @see IDocumentProvider#getDocument
	 */
	public IDocument getDocument(Object element) {
		
		if (element == null)
			return null;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		return (info != null ? info.fDocument : null);
	}
	
	/*
	 * @see IDocumentProvider#mustSaveDocument
	 */
	public boolean mustSaveDocument(Object element) {
		
		if (element == null)
			return false;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		return (info != null ? info.fCount == 1 && info.fCanBeSaved : false);
	}	
	
	/*
	 * @see IDocumentProvider#getAnnotationModel
	 */
	public IAnnotationModel getAnnotationModel(Object element) {
		
		if (element == null)
			return null;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		return (info != null ? info.fModel : null);
	}
	
	/*
	 * @see IDocumentProvider#canSaveDocument(Object)
	 */
	public boolean canSaveDocument(Object element) {
		
		if (element == null)
			return false;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		return (info != null ? info.fCanBeSaved : false);
	}
	
	/*
	 * @see IDocumentProvider#resetDocument(Object)
	 */
	public void resetDocument(Object element) throws CoreException {
		if (element == null)
			return;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info != null && info.fCanBeSaved) {
			IDocument original= createDocument(element);
			if (original != null) {
				fireElementContentAboutToBeReplaced(element);
				info.fDocument.set(original.get());
				info.fCanBeSaved= false;
				addUnchangedElementListeners(element, info);
				fireElementContentReplaced(element);
			}
		}
	}
	
	/*
	 * @see IDocumentProvider#saveDocument(IProgressMonitor, Object, IDocument, boolean)
	 */
	public void saveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		
		if (element == null)
			return;
			
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info != null) {
			Assert.isTrue(info.fDocument == document);
			doSaveDocument(monitor, element, document, overwrite);
			info.fCanBeSaved= false;
			addUnchangedElementListeners(element, info);
			fireElementDirtyStateChanged(element, false);
			
		} else {
			doSaveDocument(monitor, element, document, overwrite);
		}	
	}
	
	/**
	 * The <code>AbstractDocumentProvider</code> implementation of this 
	 * <code>IDocumentProvider</code> method does nothing. Subclasses may
	 * reimplement.
	 */
	public void aboutToChange(Object element) {
	}
	
	/**
	 * The <code>AbstractDocumentProvider</code> implementation of this 
	 * <code>IDocumentProvider</code> method does nothing. Subclasses may
	 * reimplement.
	 */
	public void changed(Object element) {
	}
	
	/*
	 * @see IDocumentProvider#addElementStateListener(IElementStateListener)
	 */
	public void addElementStateListener(IElementStateListener listener) {
		Assert.isNotNull(listener);
		if (!fElementStateListeners.contains(listener))
			fElementStateListeners.add(listener);
	}
	
	/*
	 * @see IDocumentProvider#removeElementStateListener(IElementStateListener)
	 */
	public void removeElementStateListener(IElementStateListener listener) {
		Assert.isNotNull(listener);
		fElementStateListeners.remove(listener);
	}
		
	/**
	 * Informs all registered element state listeners about a change in the
	 * dirty state of the given element.
	 *
	 * @param element the element
	 * @param isDirty the new dirty state
	 * @see IElementStateListener#elementDirtyStateChanged
	 */
	protected void fireElementDirtyStateChanged(Object element, boolean isDirty) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			IElementStateListener l= (IElementStateListener) e.next();
			l.elementDirtyStateChanged(element, isDirty);
		}
	}
	
	/**
	 * Informs all registered element state listeners about an impending 
	 * replace of the given element's content.
	 *
	 * @param element the element
	 * @see IElementStateListener#elementContentAboutToBeReplaced
	 */
	protected void fireElementContentAboutToBeReplaced(Object element) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			IElementStateListener l= (IElementStateListener) e.next();
			l.elementContentAboutToBeReplaced(element);
		}
	}
	
	/**
	 * Informs all registered element state listeners about the just-completed
	 * replace of the given element's content.
	 *
	 * @param element the element
	 * @see IElementStateListener#elementContentReplaced
	 */
	protected void fireElementContentReplaced(Object element) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			IElementStateListener l= (IElementStateListener) e.next();
			l.elementContentReplaced(element);
		}
	}
	
	/**
	 * Informs all registered element state listeners about the deletion
	 * of the given element.
	 *
	 * @param element the element
	 * @see IElementStateListener#elementDeleted
	 */
	protected void fireElementDeleted(Object element) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			IElementStateListener l= (IElementStateListener) e.next();
			l.elementDeleted(element);
		}
	}
	
	/**
	 * Informs all registered element state listeners about a move.
	 *
	 * @param originalElement the element before the move
	 * @param movedElement the element after the move
	 * @see IElementStateListener#elementMoved
	 */
	protected void fireElementMoved(Object originalElement, Object movedElement) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			IElementStateListener l= (IElementStateListener) e.next();
			l.elementMoved(originalElement, movedElement);
		}
	}
	
	/*
	 * @see IDocumentProvider#getModificationStamp(Object)
	 */
	public long getModificationStamp(Object element) {
		return 0;
	}
	
	/*
	 * @see IDocumentProvider#getSynchronizationStamp(Object)
	 */
	public long getSynchronizationStamp(Object element) {
		return 0;
	}
	
	/*
	 * @see IDocumentProvider#isDeleted(Object)
	 */
	public boolean isDeleted(Object element) {
		return false;
	}
	
	/*
	 * @see IDocumentProviderExtension#isReadOnly(Object)
	 */
	public boolean isReadOnly(Object element) {
		return true;
	}
	
	/*
	 * @see IDocumentProviderExtension#isModifiable(Object)
	 */
	public boolean isModifiable(Object element) {
		return false;
	}
	
	/**
	 * Returns whether <code>validateState</code> has been called for the given element
	 * since the element's state has potentially been invalidated.
	 * 
	 * @param element the element
	 * @return whether <code>validateState</code> has been called for the given element
	 */
	public boolean isStateValidated(Object element) {
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info != null)
			return info.fIsStateValidated;
		return false;
	}
	
	/**
	 * Hook method for validating the state of the given element. Must not take care of cache updating etc.
	 * Default implementation is empty.
	 * 
	 * @param element the element
	 * @param computationContext the context in which validation happens
	 */
	protected void doValidateState(Object  element, Object computationContext) throws CoreException {
	}
	
	/*
	 * @see IDocumentProviderExtension#validateState(Object, Object)
	 */
	final public void validateState(Object element, Object computationContext) throws CoreException {
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info != null) {
			doValidateState(element, computationContext);
			doUpdateStateCache(element);
			info.fIsStateValidated= true;
			fireElementStateValidationChanged(element, true);
		}
	}
	
	/**
	 * Hook method for updating the state of the given element.
	 * Default implementation is empty.
	 * 
	 * @param element the element
	 */
	protected void doUpdateStateCache(Object element) throws CoreException {
	}
	
	/**
	 * Returns whether the state of the element must be invalidated given its
	 * previous read-only state.
	 * 
	 * @param element the element
	 * @param wasReadOnly the previous read-only state
	 * @return <code>true</code> if the state of the given element must be invalidated
	 */
	protected boolean invalidatesState(Object element, boolean wasReadOnly) {
		Assert.isTrue(PR10806_UC5_ENABLED != PR14469_ENABLED);
		boolean readOnlyChanged= (isReadOnly(element) != wasReadOnly);
		if (PR14469_ENABLED)
			return readOnlyChanged && !canSaveDocument(element);
		return readOnlyChanged;
	}
	
	/*
	 * @see IDocumentProviderExtension#updateStateCache(Object)
	 */
	final public void updateStateCache(Object element) throws CoreException {
		ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
		if (info != null) {
			boolean wasReadOnly= isReadOnly(element);
			doUpdateStateCache(element);
			if (invalidatesState(element, wasReadOnly)) {
				info.fIsStateValidated= false;
				fireElementStateValidationChanged(element, false);
			}
		}
	}
	
	/*
	 * @see IDocumentProviderExtension#setCanSaveDocument(Object)
	 */
	public void setCanSaveDocument(Object element) {
		if (element != null) {
			ElementInfo info= (ElementInfo) fElementInfoMap.get(element);
			if (info != null) {
				info.fCanBeSaved= true;
				removeUnchangedElementListeners(element, info);
				fireElementDirtyStateChanged(element, info.fCanBeSaved);
			}
		}
	}
	
	/**
	 * Informs all registered element state listeners about a change in the
	 * state validation of the given element.
	 *
	 * @param element the element
	 * @param isStateValidated
	 * @see IElementStateListenerExtension#elementValidationStateChanged
	 */
	protected void fireElementStateValidationChanged(Object element, boolean isStateValidated) {
		Iterator e= new ArrayList(fElementStateListeners).iterator();
		while (e.hasNext()) {
			Object o= e.next();
			if (o instanceof IElementStateListenerExtension) {
				IElementStateListenerExtension l= (IElementStateListenerExtension) o;
				l.elementStateValidationChanged(element, isStateValidated);
			}
		}
	}
}
