/*******************************************************************************
 * Copyright (c) 2002, 2003 GEBIT Gesellschaft fuer EDV-Beratung
 * und Informatik-Technologien mbH, 
 * Berlin, Duesseldorf, Frankfurt (Germany) 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:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug 24108
 *******************************************************************************/

package org.eclipse.ant.ui.internal.editor.text;

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

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.rules.DefaultPartitioner;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModelEvent;
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.ant.ui.internal.editor.outline.AntModel;
import org.eclipse.ant.ui.internal.editor.outline.IProblem;
import org.eclipse.ant.ui.internal.editor.outline.LocationProvider;
import org.eclipse.ant.ui.internal.editor.outline.IProblemRequestor;
import org.eclipse.ant.ui.internal.editor.outline.XMLCore;
import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;

/*
 * This file originates from an internal package of Eclipse's 
 * Manifest Editor. It has been copied by GEBIT to here in order to
 * permanently use those features. It has been renamed and edited by GEBIT 
 * after copying.
 */
public class AntEditorDocumentProvider extends FileDocumentProvider {

	protected class XMLAnnotationModel extends ResourceMarkerAnnotationModel implements IProblemRequestor {
		
		private List fGeneratedAnnotations= new ArrayList();
		private List fCollectedProblems= new ArrayList();
		
		private ReverseMap fReverseMap= new ReverseMap();
		private List fPreviouslyOverlaid= null; 
		private List fCurrentlyOverlaid= new ArrayList();

		/**
		 * Constructor for XMLAnnotationModel.
		 * @param resource
		 */
		public XMLAnnotationModel(IFileEditorInput input) {
			super(input.getFile());
		}

		/*
		 * @see org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel#createMarkerAnnotation(org.eclipse.core.resources.IMarker)
		 */
		protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
			return new XMLMarkerAnnotation(marker);
		}

		protected Position createPositionFromProblem(IProblem problem) {
			int start= problem.getOffset();
			if (start >= 0) {
				int length= problem.getLength();
					
				if (length >= 0)
					return new Position(start, length);
			}

			return null;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.ant.ui.internal.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.ui.internal.editor.outline.IProblem)
		 */
		public void acceptProblem(IProblem problem) {
			fCollectedProblems.add(problem);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.ant.ui.internal.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.ui.internal.editor.outline.IProblem)
		 */
		public void beginReporting() {
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.ant.ui.internal.editor.outline.IProblemRequestor#acceptProblem(org.eclipse.ant.ui.internal.editor.outline.IProblem)
		 */
		public void endReporting() {
			boolean temporaryProblemsChanged= false;
			fPreviouslyOverlaid= fCurrentlyOverlaid;
			fCurrentlyOverlaid= new ArrayList();
				
			synchronized (fAnnotations) {
					
				if (fGeneratedAnnotations.size() > 0) {
					temporaryProblemsChanged= true;	
					removeAnnotations(fGeneratedAnnotations, false, true);
					fGeneratedAnnotations.clear();
				}
					
				if (fCollectedProblems != null && fCollectedProblems.size() > 0) {
					Iterator e= fCollectedProblems.iterator();
					while (e.hasNext()) {
							
						IProblem problem= (IProblem) e.next();
							
						Position position= createPositionFromProblem(problem);
						if (position != null) {
								
							XMLProblemAnnotation annotation= new XMLProblemAnnotation(problem);
							overlayMarkers(position, annotation);								
							fGeneratedAnnotations.add(annotation);
							addAnnotation(annotation, position, false);
								
							temporaryProblemsChanged= true;
						}
					}
						
					fCollectedProblems.clear();
				}
					
				removeMarkerOverlays();
				fPreviouslyOverlaid.clear();
				fPreviouslyOverlaid= null;
			}
					
			if (temporaryProblemsChanged)
				fireModelChanged(new AnnotationModelEvent(this));
		}

		private void removeMarkerOverlays() {
			Iterator e= fPreviouslyOverlaid.iterator();
			while (e.hasNext()) {
				XMLMarkerAnnotation annotation= (XMLMarkerAnnotation) e.next();
				annotation.setOverlay(null);
			}			
		}
			
		/**
		 * Overlays value with problem annotation.
		 * @param problemAnnotation
		 */
		private void setOverlay(Object value, XMLProblemAnnotation problemAnnotation) {
			if (value instanceof  XMLMarkerAnnotation) {
				XMLMarkerAnnotation annotation= (XMLMarkerAnnotation) value;
				if (annotation.isProblem()) {
					annotation.setOverlay(problemAnnotation);
					fPreviouslyOverlaid.remove(annotation);
					fCurrentlyOverlaid.add(annotation);
				}
			}
		}
			
		private void  overlayMarkers(Position position, XMLProblemAnnotation problemAnnotation) {
			Object value= getAnnotations(position);
			if (value instanceof List) {
				List list= (List) value;
				for (Iterator e = list.iterator(); e.hasNext();)
					setOverlay(e.next(), problemAnnotation);
			} else {
				setOverlay(value, problemAnnotation);
			}
		}

		private Object getAnnotations(Position position) {
			return fReverseMap.get(position);
		}
						
		/*
		 * @see AnnotationModel#addAnnotation(Annotation, Position, boolean)
		 */
		protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) {
			super.addAnnotation(annotation, position, fireModelChanged);
				
			Object cached= fReverseMap.get(position);
			if (cached == null)
				fReverseMap.put(position, annotation);
			else if (cached instanceof List) {
				List list= (List) cached;
				list.add(annotation);
			} else if (cached instanceof Annotation) {
				List list= new ArrayList(2);
				list.add(cached);
				list.add(annotation);
				fReverseMap.put(position, list);
			}
		}
			
		/*
		 * @see AnnotationModel#removeAllAnnotations(boolean)
		 */
		protected void removeAllAnnotations(boolean fireModelChanged) {
			super.removeAllAnnotations(fireModelChanged);
			fReverseMap.clear();
		}
			
		/*
		 * @see AnnotationModel#removeAnnotation(Annotation, boolean)
		 */
		protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) {
			Position position= getPosition(annotation);
			Object cached= fReverseMap.get(position);
			if (cached instanceof List) {
				List list= (List) cached;
				list.remove(annotation);
				if (list.size() == 1) {
					fReverseMap.put(position, list.get(0));
					list.clear();
				}
			} else if (cached instanceof Annotation) {
				fReverseMap.remove(position);
			}
				
			super.removeAnnotation(annotation, fireModelChanged);
		}
	};
	
	/**
	 * Remembers a XML document model for each element.
	 */
	protected class XMLFileInfo extends FileInfo {
		
		public XMLFileInfo(IDocument document, IAnnotationModel annotationModel, FileSynchronizer fileSynchronizer, AntModel model) {
			super(document, annotationModel, fileSynchronizer);
		}
		
		public AntModel getAntModel() {
			return (AntModel)fModel;
		}
	};
	
	/**
	 * Internal structure for mapping positions to some value. 
	 * The reason for this specific structure is that positions can
	 * change over time. Thus a lookup is based on value and not
	 * on hash value.
	 */
	protected static class ReverseMap {
			
		static class Entry {
			Position fPosition;
			Object fValue;
		};
			
		private List fList= new ArrayList(2);
		private int fAnchor= 0;
			
		public ReverseMap() {
		}
			
		public Object get(Position position) {
				
			Entry entry;
				
			// behind anchor
			int length= fList.size();
			for (int i= fAnchor; i < length; i++) {
				entry= (Entry) fList.get(i);
				if (entry.fPosition.equals(position)) {
					fAnchor= i;
					return entry.fValue;
				}
			}
				
			// before anchor
			for (int i= 0; i < fAnchor; i++) {
				entry= (Entry) fList.get(i);
				if (entry.fPosition.equals(position)) {
					fAnchor= i;
					return entry.fValue;
				}
			}
				
			return null;
		}
			
		private int getIndex(Position position) {
			Entry entry;
			int length= fList.size();
			for (int i= 0; i < length; i++) {
				entry= (Entry) fList.get(i);
				if (entry.fPosition.equals(position))
					return i;
			}
			return -1;
		}
			
		public void put(Position position,  Object value) {
			int index= getIndex(position);
			if (index == -1) {
				Entry entry= new Entry();
				entry.fPosition= position;
				entry.fValue= value;
				fList.add(entry);
			} else {
				Entry entry= (Entry) fList.get(index);
				entry.fValue= value;
			}
		}
			
		public void remove(Position position) {
			int index= getIndex(position);
			if (index > -1)
				fList.remove(index);
		}
			
		public void clear() {
			fList.clear();
		}
	}
	
	
	private XMLCore fCore;

	public AntEditorDocumentProvider(XMLCore core) {
		super();
		fCore= core;
	}

    private IDocumentPartitioner createDocumentPartitioner() {
        DefaultPartitioner partitioner =
            new DefaultPartitioner(
                new AntEditorPartitionScanner(),
                new String[] {
                    AntEditorPartitionScanner.XML_TAG,
                    AntEditorPartitionScanner.XML_COMMENT });
        return partitioner;
    }

    public IDocument createDocument(Object element) throws CoreException {
	    IDocument document;
	    if (element instanceof IEditorInput) {
		    document= new PartiallySynchronizedDocument();
		    if (setDocumentContent(document, (IEditorInput) element, getEncoding(element))) {
			    initializeDocument(document);
		    }
	    } else {
		    document= null;
	    }
	    return document;
    }
	
    protected void initializeDocument(IDocument document) {
	    IDocumentPartitioner partitioner= createDocumentPartitioner();
	    document.setDocumentPartitioner(partitioner);
	    partitioner.connect(document);
    }

    public AntModel getAntModel(Object element) {
	    ElementInfo info= getElementInfo(element);
	    if (info instanceof XMLFileInfo) {
		    XMLFileInfo xmlInfo= (XMLFileInfo) info;
		    return xmlInfo.getAntModel();
	    }
	    return null;
    }

    /*
     * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object)
     */
    protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
	    if (element instanceof IFileEditorInput) {
		    IFileEditorInput input= (IFileEditorInput) element;
		    return new XMLAnnotationModel(input);
	    }
	    return super.createAnnotationModel(element);
    }

    protected AntModel createAntModel(Object element, IDocument document, IAnnotationModel annotationModel) {
	    IProblemRequestor requestor= annotationModel instanceof IProblemRequestor ? (IProblemRequestor) annotationModel : null;
	    return new AntModel(fCore, document, requestor, new LocationProvider(element instanceof IFileEditorInput ? ((IFileEditorInput) element).getFile() : null));
    }

    /*
     * @see org.eclipse.ui.editors.text.FileDocumentProvider#createElementInfo(java.lang.Object)
     */
    protected ElementInfo createElementInfo(Object element) throws CoreException {
	    if (element instanceof IFileEditorInput) {
			
		    IFileEditorInput input= (IFileEditorInput) element;
			
		    try {
			    refreshFile(input.getFile());
		    } catch (CoreException x) {
			    handleCoreException(x, "XMLDocumentProvider.createElementInfo: Core exception"); //$NON-NLS-1$
		    }
			
		    IDocument d= null;
		    IStatus s= null;
			
		    try {
			    d= createDocument(element);
		    } catch (CoreException x) {
			    s= x.getStatus();
			    d= createEmptyDocument();
		    }
			
		    IAnnotationModel m= createAnnotationModel(element);
		    AntModel o= createAntModel(element, d, m);
		    o.install();
		    FileSynchronizer f= new FileSynchronizer(input);
		    f.install();
			
		    XMLFileInfo info= new XMLFileInfo(d, m, f, o);
		    info.fModificationStamp= computeModificationStamp(input.getFile());
		    info.fStatus= s;
		    info.fEncoding= getPersistedEncoding(input);
			
		    return info;
	    }
		
	    return super.createElementInfo(element);
    }
	
    /*
     * @see org.eclipse.ui.editors.text.FileDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.ui.texteditor.AbstractDocumentProvider.ElementInfo)
     */
    protected void disposeElementInfo(Object element, ElementInfo info) {
	    if (info.fModel != null &&  info instanceof XMLFileInfo) {
		    XMLFileInfo xmlInfo= (XMLFileInfo) info;
		    xmlInfo.getAntModel().dispose();
	    }
	    super.disposeElementInfo(element, info);	
    }
}
