/*******************************************************************************
 * Copyright (c) 2002, 2011 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 Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     GEBIT Gesellschaft fuer EDV-Beratung und Informatik-Technologien mbH - initial API and implementation
 * 	   IBM Corporation - bug fixes
 * 	   John-Mason P. Shackelford - bug 40255
 *     Mark Melvin - bug 93378
 *******************************************************************************/

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

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.ExternalHyperlink;
import org.eclipse.ant.internal.ui.IAntUIHelpContextIds;
import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
import org.eclipse.ant.internal.ui.editor.actions.FoldingActionGroup;
import org.eclipse.ant.internal.ui.editor.actions.OpenDeclarationAction;
import org.eclipse.ant.internal.ui.editor.actions.RenameInFileAction;
import org.eclipse.ant.internal.ui.editor.actions.RunToLineAdapter;
import org.eclipse.ant.internal.ui.editor.actions.ToggleLineBreakpointAction;
import org.eclipse.ant.internal.ui.editor.outline.AntEditorContentOutlinePage;
import org.eclipse.ant.internal.ui.editor.text.AntEditorDocumentProvider;
import org.eclipse.ant.internal.ui.editor.text.AntFoldingStructureProvider;
import org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant;
import org.eclipse.ant.internal.ui.editor.text.XMLTextHover;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntModelChangeEvent;
import org.eclipse.ant.internal.ui.model.AntModelCore;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.IAntModelListener;
import org.eclipse.ant.internal.ui.preferences.AntEditorPreferenceConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.ui.actions.IRunToLineTarget;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelExtension;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.IProjectionListener;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

/**
 * The actual editor implementation for Eclipse's Ant integration.
 */
public class AntEditor extends TextEditor implements IReconcilingParticipant, IProjectionListener {
	/**
	 * Updates the Ant outline page selection and this editor's range indicator.
	 * 
	 * @since 3.0
	 */
	private class EditorSelectionChangedListener implements ISelectionChangedListener  {
		
		/**
		 * Installs this selection changed listener with the given selection provider. If
		 * the selection provider is a post selection provider, post selection changed
		 * events are the preferred choice, otherwise normal selection changed events
		 * are requested.
		 * 
		 * @param selectionProvider
		 */
		public void install(ISelectionProvider selectionProvider) {
			if (selectionProvider == null || getAntModel() == null) {
				return;
			}
				
			if (selectionProvider instanceof IPostSelectionProvider)  {
				IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
				provider.addPostSelectionChangedListener(this);
			} else  {
				selectionProvider.addSelectionChangedListener(this);
			}
		}

		/**
		 * Removes this selection changed listener from the given selection provider.
		 * 
		 * @param selectionProvider
		 */
		public void uninstall(ISelectionProvider selectionProvider) {
			if (selectionProvider == null || getAntModel() == null) {
				return;
			}
			
			if (selectionProvider instanceof IPostSelectionProvider)  {
				IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
				provider.removePostSelectionChangedListener(this);
			} else  {
				selectionProvider.removeSelectionChangedListener(this);
			}
		}
		
		/*
		 * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
		 */
		public void selectionChanged(SelectionChangedEvent event) {
			AntModel model= getAntModel();
			ISelection selection= event.getSelection();
			AntElementNode node= null;
			if (selection instanceof ITextSelection) {
				ITextSelection textSelection= (ITextSelection)selection;
				int offset= textSelection.getOffset();
				node= model.getNode(offset, false);
				updateOccurrenceAnnotations(textSelection, model);
			}
		
			if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {
				synchronizeOutlinePage(node, true);
			}
			setSelection(node, false);
		}
	}
	
	class StatusLineSourceViewer extends ProjectionViewer{
		
		public StatusLineSourceViewer(Composite composite, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, int styles) {
			super(composite, verticalRuler, overviewRuler, isOverviewRulerVisible(), styles);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jface.text.ITextOperationTarget#doOperation(int)
		 */
		public void doOperation(int operation) {
			if (getTextWidget() == null || !redraws()) {
				return;
			}

			switch (operation) {
				case CONTENTASSIST_PROPOSALS:
					String msg= fContentAssistant.showPossibleCompletions();
					setStatusLineErrorMessage(msg);
					return;
			}
			
			super.doOperation(operation);
		}
	}
		
	
	/**
	 * Finds and marks occurrence annotations.
	 * 
	 * @since 3.1
	 */
	class OccurrencesFinderJob extends Job {
		
		private IDocument fDocument;
		private ISelection fSelection;
		private ISelectionValidator fPostSelectionValidator;
		private boolean fCanceled= false;
		private IProgressMonitor fProgressMonitor;
		private List fPositions;
		
		public OccurrencesFinderJob(IDocument document, List positions, ISelection selection) {
			super("Occurrences Marker"); //$NON-NLS-1$
			fDocument= document;
			fSelection= selection;
			fPositions= positions;
			
			if (getSelectionProvider() instanceof ISelectionValidator)
				fPostSelectionValidator= (ISelectionValidator)getSelectionProvider();
		}
		
		// cannot use cancel() because it is declared final
		void doCancel() {
			fCanceled= true;
			cancel();
		}
		
		private boolean isCanceled() {
			return fCanceled || fProgressMonitor.isCanceled()
				||  fPostSelectionValidator != null && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
				|| LinkedModeModel.hasInstalledModel(fDocument);
		}
		
		/*
		 * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
		 */
		public IStatus run(IProgressMonitor progressMonitor) {
			
			fProgressMonitor= progressMonitor;
			
			if (isCanceled())
				return Status.CANCEL_STATUS;
			
			ITextViewer textViewer= getViewer();
			if (textViewer == null)
				return Status.CANCEL_STATUS;
			
			IDocument document= textViewer.getDocument();
			if (document == null)
				return Status.CANCEL_STATUS;
			
			IDocumentProvider documentProvider= getDocumentProvider();
			if (documentProvider == null)
				return Status.CANCEL_STATUS;
		
			IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
			if (annotationModel == null)
				return Status.CANCEL_STATUS;
			
			// Add occurrence annotations
			int length= fPositions.size();
			Map annotationMap= new HashMap(length);
			for (int i= 0; i < length; i++) {
				
				if (isCanceled())
					return Status.CANCEL_STATUS;
				
				String message;
				Position position= (Position) fPositions.get(i);
				
				// Create & add annotation
				try {
					message= document.get(position.offset, position.length);
				} catch (BadLocationException ex) {
					// Skip this match
					continue;
				}
				annotationMap.put(
						new Annotation("org.eclipse.jdt.ui.occurrences", false, message), //$NON-NLS-1$
						position);
			}
			
			if (isCanceled()) {
				return Status.CANCEL_STATUS;
            }
			
            Object lock= getLockObject(document);
            if (lock == null) {
                updateAnnotations(annotationModel, annotationMap);
            } else {
                synchronized (lock) {
                    updateAnnotations(annotationModel, annotationMap);
                }
            }

			return Status.OK_STATUS;
		}

        private void updateAnnotations(IAnnotationModel annotationModel, Map annotationMap) {
            if (annotationModel instanceof IAnnotationModelExtension) {
            	((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap);
            } else {
            	removeOccurrenceAnnotations();
            	Iterator iter= annotationMap.entrySet().iterator();
            	while (iter.hasNext()) {
            		Map.Entry mapEntry= (Map.Entry)iter.next();
            		annotationModel.addAnnotation((Annotation)mapEntry.getKey(), (Position)mapEntry.getValue());
            	}
            }
            fOccurrenceAnnotations= (Annotation[])annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
        }
	}
	
	/**
	 * Cancels the occurrences finder job upon document changes.
	 * 
	 * @since 3.1
	 */
	class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {

		public void install() {
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer == null)
				return;
				
			StyledText text= sourceViewer.getTextWidget();
			if (text == null || text.isDisposed())
				return;

			sourceViewer.addTextInputListener(this);
			
			IDocument document= sourceViewer.getDocument();
			if (document != null)
				document.addDocumentListener(this);
		}
		
		public void uninstall() {
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer != null)
				sourceViewer.removeTextInputListener(this);

			IDocumentProvider documentProvider= getDocumentProvider();
			if (documentProvider != null) {
				IDocument document= documentProvider.getDocument(getEditorInput());
				if (document != null)
					document.removeDocumentListener(this);
			}
		}
				

		/*
		 * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
		 */
		public void documentAboutToBeChanged(DocumentEvent event) {
			if (fOccurrencesFinderJob != null)
				fOccurrencesFinderJob.doCancel();
		}

		/*
		 * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
		 */
		public void documentChanged(DocumentEvent event) {
		}

		/*
		 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
		 */
		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			if (oldInput == null)
				return;

			oldInput.removeDocumentListener(this);
		}

		/*
		 * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
		 */
		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			if (newInput == null)
				return;
			newInput.addDocumentListener(this);
		}
	}
	
	/**
	 * Internal activation listener.
	 * @since 3.1
	 */
	private class ActivationListener extends ShellAdapter {
		/*
		 * @see org.eclipse.swt.events.ShellAdapter#shellActivated(org.eclipse.swt.events.ShellEvent)
		 */
		public void shellActivated(ShellEvent e) {
			if (fMarkOccurrenceAnnotations && isActivePart()) {
				ISelection selection= getSelectionProvider().getSelection();
				if (selection instanceof ITextSelection) {
					fForcedMarkOccurrencesSelection= (ITextSelection) selection;
					updateOccurrenceAnnotations(fForcedMarkOccurrencesSelection, getAntModel());
				}
			}
		}
		
		/*
		 * @see org.eclipse.swt.events.ShellAdapter#shellDeactivated(org.eclipse.swt.events.ShellEvent)
		 */
		public void shellDeactivated(ShellEvent e) {
			if (fMarkOccurrenceAnnotations && isActivePart())
				removeOccurrenceAnnotations();
		}
	}

	/**
	 * Selection changed listener for the outline view.
	 */
    protected ISelectionChangedListener fSelectionChangedListener = new ISelectionChangedListener(){
        public void selectionChanged(SelectionChangedEvent event) {
        	fSelectionSetFromOutline= false;
            doSelectionChanged(event);
            fSelectionSetFromOutline= true;
        }
    };
    
    private IAntModelListener fAntModelListener;
    
    /**
     * The page that shows the outline.
     */
    protected AntEditorContentOutlinePage fOutlinePage;
    
	
	private boolean fInitialReconcile= true;
	
	/**
	 * The editor selection changed listener.
	 * 
	 * @since 3.0
	 */
	private EditorSelectionChangedListener fEditorSelectionChangedListener;

	private ProjectionSupport fProjectionSupport;
	
	private AntFoldingStructureProvider fFoldingStructureProvider;
	
	private boolean fSelectionSetFromOutline= false;

    private FoldingActionGroup fFoldingGroup;
	
	/**
	 * Holds the current occurrence annotations.
	 * @since 3.1
	 */
	private Annotation[] fOccurrenceAnnotations= null;

	private OccurrencesFinderJob fOccurrencesFinderJob;
	private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
	
	private ITextSelection fForcedMarkOccurrencesSelection;
	/**
	 * The internal shell activation listener for updating occurrences.
	 * @since 3.1
	 */
	private ActivationListener fActivationListener= new ActivationListener();
	
	private boolean fMarkOccurrenceAnnotations;
	private boolean fStickyOccurrenceAnnotations;
    
    private AntModel fAntModel;
    

    /* (non-Javadoc)
     * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
     */
    protected void createActions() {
        super.createActions();

        ResourceBundle bundle = ResourceBundle.getBundle("org.eclipse.ant.internal.ui.editor.AntEditorMessages"); //$NON-NLS-1$
        
		IAction action= new TextOperationAction(bundle, "ContentFormat.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
        action.setActionDefinitionId(IJavaEditorActionDefinitionIds.FORMAT);
        setAction("ContentFormat", action); //$NON-NLS-1$
        
        action = new OpenDeclarationAction(this);
        setAction("OpenDeclaration", action); //$NON-NLS-1$
        
        fFoldingGroup= new FoldingActionGroup(this, getViewer());
        
		action= new RenameInFileAction(this);
		action.setActionDefinitionId("org.eclipse.ant.ui.renameInFile"); //$NON-NLS-1$
		setAction("renameInFile", action); //$NON-NLS-1$
    }

	/*
	 *  (non-Javadoc)
	 * @see org.eclipse.ui.editors.text.TextEditor#initializeEditor()
	 * Called from TextEditor.<init>
	 */
    protected void initializeEditor() {
		setPreferenceStore(AntUIPlugin.getDefault().getCombinedPreferenceStore());
		setCompatibilityMode(false);
		
		setHelpContextId(IAntUIHelpContextIds.ANT_EDITOR);
		setRulerContextMenuId("org.eclipse.ant.internal.ui.editor.AntEditor.RulerContext"); //$NON-NLS-1$
        setEditorContextMenuId("org.eclipse.ant.internal.ui.editor.AntEditor"); //$NON-NLS-1$
		configureInsertMode(SMART_INSERT, false);
		setInsertMode(INSERT);
		fMarkOccurrenceAnnotations= getPreferenceStore().getBoolean(AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES);
		fStickyOccurrenceAnnotations= getPreferenceStore().getBoolean(AntEditorPreferenceConstants.EDITOR_STICKY_OCCURRENCES);
		
		setSourceViewerConfiguration(new AntEditorSourceViewerConfiguration(this));
		setDocumentProvider(AntUIPlugin.getDefault().getDocumentProvider());
		
		fAntModelListener= new IAntModelListener() {

			/* (non-Javadoc)
			 * @see org.eclipse.ant.internal.ui.editor.outline.IDocumentModelListener#documentModelChanged(org.eclipse.ant.internal.ui.editor.outline.DocumentModelChangeEvent)
			 */
			public void antModelChanged(AntModelChangeEvent event) {
				AntModel model= getAntModel();
				if (event.getModel() == model) {
					if (event.isPreferenceChange()) {
						updateEditorImage(model);
					}
					if (fFoldingStructureProvider != null) {
						fFoldingStructureProvider.updateFoldingRegions(model);
					}
				}
			}
		};
		AntModelCore.getDefault().addAntModelListener(fAntModelListener);
    }
   
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
    public Object getAdapter(Class key) {
        if (key.equals(IContentOutlinePage.class)) {
			return getOutlinePage();
        }
        
        if (fProjectionSupport != null) {
        	Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), key);
        	if (adapter != null) {
            	return adapter;
            }
        }

        if (key == IShowInTargetList.class) {
			return new IShowInTargetList() {
				public String[] getShowInTargetIds() {
					return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_RES_NAV };
				}
			};
		}
        
        if (key == IToggleBreakpointsTarget.class) {
			return new ToggleLineBreakpointAction();
		}
        
        if (key == IRunToLineTarget.class) {
			return new RunToLineAdapter();
		}
        
        return super.getAdapter(key);
    }

	private AntEditorContentOutlinePage getOutlinePage() {
		if (fOutlinePage == null) {
			fOutlinePage= new AntEditorContentOutlinePage(AntModelCore.getDefault(), this);
			fOutlinePage.addPostSelectionChangedListener(fSelectionChangedListener);
			setOutlinePageInput();
		}
		return fOutlinePage;
	}

    private void doSelectionChanged(SelectionChangedEvent selectionChangedEvent) {
        IStructuredSelection selection= (IStructuredSelection)selectionChangedEvent.getSelection();

        if (!isActivePart() && AntUIPlugin.getActivePage() != null) {
			AntUIPlugin.getActivePage().bringToTop(this);
        }
        
        AntElementNode selectedXmlElement = (AntElementNode)selection.getFirstElement();
        if(selectedXmlElement != null) {
			setSelection(selectedXmlElement, !isActivePart());
        }
    }

    private boolean isActivePart() {
        IWorkbenchPart part= getActivePart();
        return part != null && part.equals(this);
    }
    
    public void setSelection(AntElementNode reference, boolean moveCursor) {
    	if (fSelectionSetFromOutline) {
    		//the work has all just been done via a selection setting in the outline
    		fSelectionSetFromOutline= false;
    		return;
    	}
        if (reference == null) {
        	if (moveCursor) {
        		 resetHighlightRange();
                 markInNavigationHistory();
        	}
        	return;
        }
		
		if (moveCursor) {
			markInNavigationHistory();
		}
		
    	while (reference.getImportNode() != null) {
    		reference= reference.getImportNode();
    	}
    	if (reference.isExternal()) {
    		return;
    	}
        
        ISourceViewer sourceViewer= getSourceViewer();
        if (sourceViewer == null) {
            return;
        }
        StyledText textWidget= sourceViewer.getTextWidget();
        if (textWidget == null) {
            return;
        }
            
        try {
            int offset= reference.getOffset();
            if (offset < 0) {
                return;
            }
            int length= reference.getSelectionLength();
            int highLightLength= reference.getLength();
               
            textWidget.setRedraw(false);
            
            if (highLightLength > 0) {
                setHighlightRange(offset, highLightLength, moveCursor);
            }
            
            if (!moveCursor) {
                return;
            }
                                        
            if (offset > -1 && length > 0) {
                sourceViewer.revealRange(offset, length);
                // Selected region begins one index after offset
                sourceViewer.setSelectedRange(offset, length);
                markInNavigationHistory();
            }
        } catch (IllegalArgumentException x) {
        	AntUIPlugin.log(x);
        } finally {
            textWidget.setRedraw(true);
        }
    }

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#affectsTextPresentation(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
		return ((AntEditorSourceViewerConfiguration)getSourceViewerConfiguration()).affectsTextPresentation(event);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		String property= event.getProperty();
		
		if (AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
			Object value= event.getNewValue();
			StatusLineSourceViewer viewer= (StatusLineSourceViewer) getSourceViewer();
			int newValue= -1;
			if (value instanceof Integer) {
				newValue=((Integer) value).intValue();
			} else if (value instanceof String) {
				newValue= Integer.parseInt((String) value);
			}
			if (newValue != -1) {
				viewer.getTextWidget().setTabs(newValue);
			}
			return;
		}
		
		if (AntEditorPreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
			boolean newBooleanValue= Boolean.valueOf(event.getNewValue().toString()).booleanValue();
			if (newBooleanValue != fMarkOccurrenceAnnotations) {
				fMarkOccurrenceAnnotations= newBooleanValue;
				if (fMarkOccurrenceAnnotations) {
					installOccurrencesFinder();
				} else {
					uninstallOccurrencesFinder();
				}
			}
			return;
		}
		if (AntEditorPreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) {
			boolean newBooleanValue= Boolean.valueOf(event.getNewValue().toString()).booleanValue();
			fStickyOccurrenceAnnotations= newBooleanValue;
			return;
		}
		
		if (AntEditorPreferenceConstants.EDITOR_FOLDING_ENABLED.equals(property)) {
			ISourceViewer sourceViewer= getSourceViewer();
			if (sourceViewer instanceof ProjectionViewer) {
				ProjectionViewer pv= (ProjectionViewer) sourceViewer;
				if (pv.isProjectionMode() != isFoldingEnabled()) {
					if (pv.canDoOperation(ProjectionViewer.TOGGLE)) {
						pv.doOperation(ProjectionViewer.TOGGLE);
					}
				}
			}
			return;
		}

		AntEditorSourceViewerConfiguration sourceViewerConfiguration= (AntEditorSourceViewerConfiguration)getSourceViewerConfiguration();
        if (sourceViewerConfiguration != null) {
            if (affectsTextPresentation(event)) {
                sourceViewerConfiguration.adaptToPreferenceChange(event);
            }

            sourceViewerConfiguration.changeConfiguration(event);
        }
		super.handlePreferenceStoreChanged(event);
	}
	
	/*
	 * @see org.eclipse.ui.editors.text.TextEditor#doSetInput(org.eclipse.ui.IEditorInput)
	 */
	protected void doSetInput(IEditorInput input) throws CoreException {
		fAntModel= null;
		super.doSetInput(input);
		setOutlinePageInput();
		if (fFoldingStructureProvider != null) {
			fFoldingStructureProvider.setDocument(getDocumentProvider().getDocument(input));
		}
	}

	private void setOutlinePageInput() {
		if (fOutlinePage != null) {
			fOutlinePage.setPageInput(getAntModel());
		}
	}
	
	/**
	 * Returns the Ant model for the current editor input of this editor.
	 * @return the Ant model for this editor or <code>null</code>
	 */
	public AntModel getAntModel() {
        if (fAntModel == null) {
            IDocumentProvider provider= getDocumentProvider();
            if (provider instanceof AntEditorDocumentProvider) {
                AntEditorDocumentProvider documentProvider= (AntEditorDocumentProvider) provider;
                fAntModel= documentProvider.getAntModel(getEditorInput());
            }
        }
		return fAntModel;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
	 */
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		fOverviewRuler= createOverviewRuler(getSharedColors());
		ISourceViewer viewer= new StatusLineSourceViewer(parent, ruler, getOverviewRuler(), styles);
		//ensure decoration support has been created and configured.
		getSourceViewerDecorationSupport(viewer);
		return viewer;
	}
	
	/**
	 * Set the given message as error message to this editor's status line.
	 * @param msg message to be set
	 */
	protected void setStatusLineErrorMessage(String msg) {
		IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
		if (statusLine != null)
			statusLine.setMessage(true, msg, null);
	}

	public void openReferenceElement() {
		ISelection selection= getSelectionProvider().getSelection();
		Object target= null;
		if (selection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection)selection;
			ISourceViewer viewer= getSourceViewer();
			int textOffset= textSelection.getOffset();
			IRegion region= XMLTextHover.getRegion(viewer, textOffset);
			target= findTarget(region);
		}
		
		openTarget(target);
	}
	
	protected void openTarget(Object node) {
		String errorMessage= null;
		if (node instanceof AntElementNode) {
			errorMessage= openNode((AntElementNode) node);
			if (errorMessage == null) {
				return;
			}
		} else if (node instanceof String){
			errorMessage= openInEditor((String) node, getAntModel().getEditedFile());
			if (errorMessage == null) {
				return;
			}
		}
		if (errorMessage == null || errorMessage.length() == 0) {
			errorMessage= AntEditorMessages.getString("AntEditor.3"); //$NON-NLS-1$
		}
		setStatusLineErrorMessage(errorMessage);
		getSite().getShell().getDisplay().beep();
	}

	/**
     * @param region The region to find the navigation target
     * @return the navigation target at the specified region
     */
    public Object findTarget(IRegion region) {
        ISourceViewer viewer = getSourceViewer();
        AntElementNode node= null;
       
		if (region != null) {
			IDocument document= viewer.getDocument();
			String text= null;
			try {
				text= document.get(region.getOffset(), region.getLength());
			} catch (BadLocationException e) {
			}
			if (text != null && text.length() > 0) {
				AntModel model= getAntModel();
				if (model == null) {
					return null;
				}
				node= model.getReferenceNode(text);
				if (node == null) {
					node= model.getTargetNode(text);
					if (node == null) {
						node= model.getPropertyNode(text);
						if (node == null) {
							String path= model.getPath(text, region.getOffset());
							if (path != null) {
								path = model.getProjectNode().getProject().replaceProperties(path);
								return path;
							}
                            
                            node= model.getDefininingTaskNode(text);
                            if (node == null) {
                                node= model.getMacroDefAttributeNode(text);
                            }
						}
					}
				}
			}
		}
		return node;
    }


    private String openNode(AntElementNode node) {
		String errorMessage= null;
		if (node.isExternal()) {
			String path= node.getFilePath();
			errorMessage= openInEditor(path, null);
		} else {
			setSelection(node, true);
		}
		return errorMessage;
	}
	
	private String openInEditor(String path, File buildFile) {
		File buildFileParent= null;
		if (buildFile != null) {
			buildFileParent= buildFile.getParentFile();
		}
		IFile file= AntUtil.getFileForLocation(path, buildFileParent);
		if (file != null && file.exists()) {
			try {
				IWorkbenchPage p= getEditorSite().getPage();
				if (p != null) {
					IDE.openEditor(p, file, isActivePart());
				}
				return null;
			} catch (PartInitException e) {
				return e.getLocalizedMessage();
			}
		}
        File externalFile= new File(path);
        if (externalFile.exists()) {
            new ExternalHyperlink(externalFile, -1).linkActivated();
            return null;
        }
        
		return IAntCoreConstants.EMPTY_STRING;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#editorContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	public void editorContextMenuAboutToShow(IMenuManager menu) {
		super.editorContextMenuAboutToShow(menu);
		
		if (getAntModel() != null) {
			IAction action= getAction("OpenDeclaration"); //$NON-NLS-1$
			if (action != null) {
				String openGroup = "group.open"; //$NON-NLS-1$
	    	    menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, new Separator(openGroup));
				menu.appendToGroup(openGroup, action);
			}
			
			action= getAction("renameInFile"); //$NON-NLS-1$
			String editGroup = "group.edit"; //$NON-NLS-1$
		    menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, new Separator(editGroup));
			menu.appendToGroup(editGroup, action);
			
			action= getAction("ContentFormat"); //$NON-NLS-1$
			menu.appendToGroup(editGroup, action);
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		
		ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer();
        createFoldingSupport(projectionViewer);
        if (isFoldingEnabled()) {
        	projectionViewer.doOperation(ProjectionViewer.TOGGLE);
        }
        
		if (fMarkOccurrenceAnnotations) {
			installOccurrencesFinder();
		}
		getEditorSite().getShell().addShellListener(fActivationListener);
		
		fEditorSelectionChangedListener= new EditorSelectionChangedListener();
		fEditorSelectionChangedListener.install(getSelectionProvider());
	}
	
	private void createFoldingSupport(ProjectionViewer projectionViewer) {
		fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
    	fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell shell) {
				return new AntSourceViewerInformationControl(shell);
			}
		});
        fProjectionSupport.install();
		((ProjectionViewer)getViewer()).addProjectionListener(this);
        
	}


	private boolean isFoldingEnabled() {
		IPreferenceStore store= getPreferenceStore();
		return store.getBoolean(AntEditorPreferenceConstants.EDITOR_FOLDING_ENABLED);
	}

	/*
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#isTabsToSpacesConversionEnabled()
	 * @since 3.3
	 */
	protected boolean isTabsToSpacesConversionEnabled() {
		return super.isTabsToSpacesConversionEnabled(); //provide package visibility
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	public void dispose() {
		if (fEditorSelectionChangedListener != null)  {
			fEditorSelectionChangedListener.uninstall(getSelectionProvider());
			fEditorSelectionChangedListener= null;
		}
		
		((ProjectionViewer)getViewer()).removeProjectionListener(this);
		if (fProjectionSupport != null) {
			fProjectionSupport.dispose();
			fProjectionSupport= null;
		}
		
		uninstallOccurrencesFinder();
		
		if (fActivationListener != null) {
			Shell shell= getEditorSite().getShell();
			if (shell != null && !shell.isDisposed()) {
				shell.removeShellListener(fActivationListener);
			}
			fActivationListener= null;
		}
		
		AntModelCore.getDefault().removeAntModelListener(fAntModelListener);
		fAntModel= null;

		super.dispose();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		super.doSave(monitor);
		AntModel model= getAntModel();
		model.updateMarkers();
		updateEditorImage(model);
	}
	
	private void updateEditorImage(AntModel model) {
		Image titleImage= getTitleImage();
		if (titleImage == null) {
			return;
		}
		AntProjectNode node= model.getProjectNode();
		if (node != null) {
			postImageChange(node);
		}
	}
	
	private void updateForInitialReconcile() {
		IDocumentProvider provider=  getDocumentProvider();
		if (provider == null) {//disposed
			return;
		}
		if (getAntModel() == null) {
			return;
		}
        IDocument doc= provider.getDocument(getEditorInput());
        if (doc == null) {
            return; //disposed
        }
        Object lock= getLockObject(doc);
		//ensure to synchronize so that the AntModel is not nulled out underneath in the AntEditorDocumentProvider
		//when the editor/doc provider are disposed
        if (lock == null) {
            updateModelForInitialReconcile();
        } else {
            synchronized (lock) {
                updateModelForInitialReconcile();
            }
        }
	}
    
    private void updateModelForInitialReconcile() {
        AntModel model= getAntModel();
        if (model == null) {
            return;
        }

        fInitialReconcile= false;
        updateEditorImage(model);
        model.updateForInitialReconcile();
    }
    
    private Object getLockObject(IDocument doc) {
        Object lock= null;
        if (doc instanceof ISynchronizable) {
            lock= ((ISynchronizable) doc).getLockObject();
        } else {
            lock= getAntModel();
        }
        return lock;
    }
	
	private void postImageChange(final AntElementNode node) {
		Shell shell= getSite().getShell();
		if (shell != null && !shell.isDisposed()) {
			shell.getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (getSite().getShell() == null || getSite().getShell().isDisposed()) {
						return;
					}
					Image titleImage= getTitleImage();
					Image newImage= node.getImage();
					if (titleImage != newImage) {
						setTitleImage(newImage);
					}
				}
			});
		}
	}

	public void synchronizeOutlinePage(boolean checkIfOutlinePageActive) {
		if (getSelectionProvider() == null) {
			return;
		}
		AntElementNode node= getNode();
		synchronizeOutlinePage(node, checkIfOutlinePageActive);
		
	}
	
	protected void synchronize(boolean checkIfOutlinePageActive) {
		if (getSelectionProvider() == null) {
			return;
		}
		AntElementNode node= getNode();
		if (AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.OUTLINE_LINK_WITH_EDITOR)) {
			synchronizeOutlinePage(node, checkIfOutlinePageActive);
		}
		setSelection(node, false);
		
	}
	
	private AntElementNode getNode() {
		AntModel model= getAntModel();
		if (model == null) {
			return null;
		}
		AntElementNode node= null;
		ISelection selection= getSelectionProvider().getSelection();
		if (selection instanceof ITextSelection) {
			ITextSelection textSelection= (ITextSelection)selection;
			int offset= textSelection.getOffset();
			node= model.getNode(offset, false);
		}
		return node;
	}
	
	protected void synchronizeOutlinePage(AntElementNode node, boolean checkIfOutlinePageActive) {
		if (fOutlinePage != null && !(checkIfOutlinePageActive && isAntOutlinePageActive())) {
			fOutlinePage.removePostSelectionChangedListener(fSelectionChangedListener);
			fOutlinePage.select(node);
			fOutlinePage.addPostSelectionChangedListener(fSelectionChangedListener);
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ant.internal.ui.editor.text.IReconcilingParticipant#reconciled()
	 */
	public void reconciled() {
		if (fInitialReconcile) {
			updateForInitialReconcile();
		}
		
		SourceViewerConfiguration config= getSourceViewerConfiguration();
		if (config == null) {
			return; //editor has been disposed.
		}
		IAutoEditStrategy[] strategies= config.getAutoEditStrategies(getViewer(), null);
		for (int i = 0; i < strategies.length; i++) {
			IAutoEditStrategy strategy = strategies[i];
			if (strategy instanceof AntAutoEditStrategy) {
				((AntAutoEditStrategy)strategy).reconciled();
			}
		}
		
		Shell shell= getSite().getShell();
		if (shell != null && !shell.isDisposed()) {
			shell.getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (getSite().getShell() == null || getSite().getShell().isDisposed()) {
						return;
					}
					synchronize(true);
				}
			});
		}
	}
	
	private boolean isAntOutlinePageActive() {
		IWorkbenchPart part= getActivePart();
		return part instanceof ContentOutline && ((ContentOutline)part).getCurrentPage() == fOutlinePage;
	}

	private IWorkbenchPart getActivePart() {
		IWorkbenchWindow window= getSite().getWorkbenchWindow();
		IPartService service= window.getPartService();
		return service.getActivePart();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(org.eclipse.jface.viewers.ISelection)
	 */
	protected void doSetSelection(ISelection selection) {
		super.doSetSelection(selection);
		synchronizeOutlinePage(true);
	}

    /**
     * Returns the viewer associated with this editor
     * @return The viewer associated with this editor
     */
    public ISourceViewer getViewer() {
        return getSourceViewer();
    }

    protected FoldingActionGroup getFoldingActionGroup() {
        return fFoldingGroup;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionEnabled()
     */
    public void projectionEnabled() {
    	fFoldingStructureProvider= new AntFoldingStructureProvider(this);
		fFoldingStructureProvider.setDocument(getDocumentProvider().getDocument(getEditorInput()));
		fFoldingStructureProvider.updateFoldingRegions(getAntModel());
		IPreferenceStore preferenceStore = AntUIPlugin.getDefault().getPreferenceStore();
		preferenceStore.setValue(AntEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, true);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.text.source.projection.IProjectionListener#projectionDisabled()
     */
    public void projectionDisabled() {
    	fFoldingStructureProvider= null;
    	IPreferenceStore preferenceStore = AntUIPlugin.getDefault().getPreferenceStore();
		preferenceStore.setValue(AntEditorPreferenceConstants.EDITOR_FOLDING_ENABLED, false);
    }
    
    /* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
	 */
	protected void initializeKeyBindingScopes() {
		setKeyBindingScopes(new String[] { "org.eclipse.ant.ui.AntEditorScope" });  //$NON-NLS-1$
	}
	
	protected IPreferenceStore getEditorPreferenceStore() {
		return getPreferenceStore();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
	 * @since 3.1
	 */
	protected String[] collectContextMenuPreferencePages() {
		String[] ids= super.collectContextMenuPreferencePages();
		String[] more= new String[ids.length + 6];
		more[0]= "org.eclipse.ant.ui.AntEditorPreferencePage"; //$NON-NLS-1$
		more[1]= "org.eclipse.ant.ui.AntCodeFormatterPreferencePage"; //$NON-NLS-1$
		more[2]= "org.eclipse.ant.ui.AntCodeAssistPreferencePage"; //$NON-NLS-1$
		more[3]= "org.eclipse.ant.ui.TemplatesPreferencePage"; //$NON-NLS-1$
		more[4]= "org.eclipse.ant.ui.AntPreferencePage"; //$NON-NLS-1$
		more[5]= "org.eclipse.ant.ui.AntRuntimePreferencePage"; //$NON-NLS-1$
		System.arraycopy(ids, 0, more, 6, ids.length);
		return more;
	}
	
	/**
	 * Updates the occurrences annotations based
	 * on the current selection.
	 * 
	 * @param selection the text selection
	 * @param antModel the model for the buildfile
	 * @since 3.1
	 */
	protected void updateOccurrenceAnnotations(ITextSelection selection, AntModel antModel) {

		if (fOccurrencesFinderJob != null)
			fOccurrencesFinderJob.cancel();

		if (!fMarkOccurrenceAnnotations) {
			return;
		}
		
		if (selection == null || antModel == null) {
			return;
		}
		
		IDocument document= getSourceViewer().getDocument();
		if (document == null) {
			return;
		}
		
		List positions= null;
		
		OccurrencesFinder finder= new OccurrencesFinder(this, antModel, document, selection.getOffset());
		positions= finder.perform();
		
		if (positions == null || positions.size() == 0) {
			if (!fStickyOccurrenceAnnotations) {
				removeOccurrenceAnnotations();
			}
			return;
		}
			
		fOccurrencesFinderJob= new OccurrencesFinderJob(document, positions, selection);
		fOccurrencesFinderJob.run(new NullProgressMonitor());
	}
	
	private void removeOccurrenceAnnotations() {
		IDocumentProvider documentProvider= getDocumentProvider();
		if (documentProvider == null) {
			return;
		}
		
		IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
		if (annotationModel == null || fOccurrenceAnnotations == null) {
			return;
		}

		IDocument document= documentProvider.getDocument(getEditorInput());
        Object lock= getLockObject(document);
        if (lock == null) {
            updateAnnotationModelForRemoves(annotationModel);
        } else {
            synchronized (lock) {
                updateAnnotationModelForRemoves(annotationModel);
            }
        }
	}


    private void updateAnnotationModelForRemoves(IAnnotationModel annotationModel) {
        if (annotationModel instanceof IAnnotationModelExtension) {
        	((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, null);
        } else {
        	for (int i= 0, length= fOccurrenceAnnotations.length; i < length; i++) {
        		annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
        	}
        }
        fOccurrenceAnnotations= null;
    }

	protected void installOccurrencesFinder() {
		fMarkOccurrenceAnnotations= true;
		
		if (getSelectionProvider() != null) {
			ISelection selection= getSelectionProvider().getSelection();
			if (selection instanceof ITextSelection) {
				fForcedMarkOccurrencesSelection= (ITextSelection) selection;
				updateOccurrenceAnnotations(fForcedMarkOccurrencesSelection, getAntModel());
			}
		}
		if (fOccurrencesFinderJobCanceler == null) {
			fOccurrencesFinderJobCanceler= new OccurrencesFinderJobCanceler();
			fOccurrencesFinderJobCanceler.install();
		}
	}
	
	protected void uninstallOccurrencesFinder() {
		fMarkOccurrenceAnnotations= false;
		
		if (fOccurrencesFinderJob != null) {
			fOccurrencesFinderJob.cancel();
			fOccurrencesFinderJob= null;
		}

		if (fOccurrencesFinderJobCanceler != null) {
			fOccurrencesFinderJobCanceler.uninstall();
			fOccurrencesFinderJobCanceler= null;
		}
		
		removeOccurrenceAnnotations();
	}
	
	public boolean isMarkingOccurrences() {
		return fMarkOccurrenceAnnotations;
	}


	/**
	 * The editor has entered or exited linked mode.
	 * @param inLinkedMode whether an enter or exit has occurred
	 * @param affectsOccurrences whether to change the state of the occurrences finder
	 */
	public void setInLinkedMode(boolean inLinkedMode, boolean affectsOccurrences) {
		if (inLinkedMode) {
			getAntModel().setShouldReconcile(false);
			if (affectsOccurrences) {
				uninstallOccurrencesFinder();
			}
		} else {
			getAntModel().setShouldReconcile(true);
			if (affectsOccurrences) {
				installOccurrencesFinder();
			}
		}
	}
}