/*******************************************************************************
 * Copyright (c) 2005 The Regents of the University of California. 
 * This material was produced under U.S. Government contract W-7405-ENG-36 
 * for Los Alamos National Laboratory, which is operated by the University 
 * of California for the U.S. Department of Energy. The U.S. Government has 
 * rights to use, reproduce, and distribute this software. NEITHER THE 
 * GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR 
 * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified 
 * to produce derivative works, such modified software should be clearly marked, 
 * so as not to confuse it with the version available from LANL.
 * 
 * Additionally, 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
 * 
 * LA-CC 04-115
 *******************************************************************************/
package org.eclipse.ptp.debug.internal.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.resources.FileStorage;
import org.eclipse.ptp.debug.core.IPDebugEventListener;
import org.eclipse.ptp.debug.core.IPSession;
import org.eclipse.ptp.debug.core.PTPDebugCorePlugin;
import org.eclipse.ptp.debug.core.TaskSet;
import org.eclipse.ptp.debug.core.event.IPDebugEvent;
import org.eclipse.ptp.debug.core.event.IPDebugInfo;
import org.eclipse.ptp.debug.core.event.IPDebugSuspendInfo;
import org.eclipse.ptp.debug.core.model.IPDebugTarget;
import org.eclipse.ptp.debug.core.model.IPStackFrame;
import org.eclipse.ptp.debug.core.model.IPThread;
import org.eclipse.ptp.debug.core.pdi.PDIException;
import org.eclipse.ptp.debug.core.pdi.request.IPDIListStackFramesRequest;
import org.eclipse.ptp.debug.core.sourcelookup.PSourceLookupDirector;
import org.eclipse.ptp.debug.ui.IPTPDebugUIConstants;
import org.eclipse.ptp.debug.ui.PTPDebugUIPlugin;
import org.eclipse.ptp.debug.ui.UIDebugManager;
import org.eclipse.ptp.debug.ui.messages.Messages;
import org.eclipse.ptp.proxy.debug.client.ProxyDebugLocator;
import org.eclipse.ptp.proxy.debug.client.ProxyDebugStackFrame;
import org.eclipse.ptp.ui.IElementManager;
import org.eclipse.ptp.ui.listeners.IJobChangedListener;
import org.eclipse.ptp.ui.model.IElementHandler;
import org.eclipse.ptp.ui.model.IElementSet;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

/*
 * @author Clement chu
 * 
 */
public class PAnnotationManager implements IJobChangedListener, IPDebugEventListener {
	private static PAnnotationManager instance = null;
	private final Object LOCK = new Object();
	protected Map<String, AnnotationGroup> annotationMap = Collections.synchronizedMap(new HashMap<String, AnnotationGroup>());
	protected UIDebugManager uiDebugManager = null;

	/* Constructor
	 * @param uiDebugManager
	 */
	public PAnnotationManager(UIDebugManager uiDebugManager) {
		this.uiDebugManager = uiDebugManager;
		// make sure every time created the same object reference
		if (instance == null) {
			uiDebugManager.addJobChangedListener(this);
			PTPDebugCorePlugin.getDefault().addDebugEventListener(this);
			instance = this;
		}
	}
	
	/* Get instance of PAnnotationManager
	 * @return
	 */
	public static PAnnotationManager getDefault() {
		if (instance == null)
			instance = new PAnnotationManager(PTPDebugUIPlugin.getUIDebugManager());
		return instance;
	}
	
	/* Clean all settings and listeners
	 * 
	 */
	public void shutdown() {
		clearAllAnnotations();
		PTPDebugCorePlugin.getDefault().removeDebugEventListener(this);
		uiDebugManager.removeJobChangedListener(this);
		annotationMap = null;
	}
	
	/* Clean all stored annotations
	 * 
	 */
	protected void clearAllAnnotations() {
		synchronized (LOCK) {
			for (Iterator<AnnotationGroup> i = annotationMap.values().iterator(); i.hasNext();) {
				i.next().removeAnnotations();
			}
			annotationMap.clear();
		}
	}
	
	/* Remove annotation group by given job
	 * @param job_id job ID
	 */
	protected void removeAnnotationGroup(String job_id) {
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = (AnnotationGroup) annotationMap.remove(job_id);
			if (annotationGroup != null) {
				annotationGroup.removeAnnotations();
			}
		}
	}
	
	/* Add annotation to given job
	 * @param job_id Job ID
	 * @param annotationGroup
	 */
	protected void putAnnotationGroup(String job_id, AnnotationGroup annotationGroup) {
		synchronized (LOCK) {
			annotationMap.put(job_id, annotationGroup);
		}
	}
	
	/* Get annotation by given hob ID
	 * @param job_id job ID
	 * @return
	 */
	protected AnnotationGroup getAnnotationGroup(String job_id) {
		synchronized (LOCK) {
			return (AnnotationGroup) annotationMap.get(job_id);
		}
	}

	/* Get editor and open editor if it is not opened or focus on it if it is already opened
	 * @param page
	 * @param input
	 * @param id
	 * @return
	 */
	protected IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) {
		final IEditorPart[] editor = new IEditorPart[] { null };
		Runnable r = new Runnable() {
			public void run() {
				try {
					editor[0] = page.openEditor(input, id, false);
				} catch (PartInitException e) {
					PTPDebugUIPlugin.errorDialog(PTPDebugUIPlugin.getActiveWorkbenchShell(), Messages.PAnnotationManager_0, Messages.PAnnotationManager_1, e);
				}
			}
		};
		BusyIndicator.showWhile(Display.getDefault(), r);
		return editor[0];
	}
	
	/* Get editor part
	 * @param file
	 * @return
	 */
	protected IEditorPart getEditorPart(final IFile file) {
		final IEditorPart[] editor = new IEditorPart[] { null };
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				IWorkbenchPage page = PTPDebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
				IEditorPart editorPart = page.getActiveEditor();
				if (editorPart != null) {
					IEditorInput editorInput = editorPart.getEditorInput();
					if (editorInput instanceof IFileEditorInput) {
						if (((IFileEditorInput) editorInput).getFile().equals(file)) {
							page.bringToTop(editorPart);
							editor[0] = editorPart;
							return;
						}
					}
				}
				if (editor[0] == null) {
					for (IEditorReference refs : page.getEditorReferences()) {
						IEditorPart refEditor = refs.getEditor(false);
						if (refEditor == null)
							continue;
						IEditorInput editorInput = refEditor.getEditorInput();
						if (editorInput instanceof IFileEditorInput) {
							if (((IFileEditorInput) editorInput).getFile().equals(file)) {
								page.bringToTop(refEditor);
								editor[0] = refEditor;
								return;
							}
						}
					}
				}
				try {
					editor[0] = page.openEditor(PDebugUIUtils.getEditorInput(file), PDebugUIUtils.getEditorId(file), false);
				} catch (PartInitException e) {
					//PTPDebugUIPlugin.errorDialog(PTPDebugUIPlugin.getActiveWorkbenchShell(), "Error", "Cannot open editor", e);
				}
			}
		});
		return editor[0];
	}
	
	protected void displaySource(final ISourceLookupResult result) {
		UIJob uiJob = new UIJob(Messages.PAnnotationManager_2) {
			public IStatus runInUIThread(IProgressMonitor monitor) {
				IWorkbenchPage page = PTPDebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
				if (!monitor.isCanceled() && result != null && page != null) {
					DebugUITools.displaySource(result, page);
				}
				return Status.OK_STATUS;
			}
		};
		uiJob.schedule();
	}
	
	/* Find file
	 * @param fileName
	 * @return
	 */
	protected IFile findFile(String filename) {
		return findFile(new Path(filename));
	}
	
	protected IFile findFile(IPath location) {
		IPath normalized = FileBuffers.normalizeLocation(location);
		if (normalized.segmentCount() >= 2) {
			return ResourcesPlugin.getWorkspace().getRoot().getFile(normalized);
		}
		return null;
	}
	
	/* Get text editor
	 * @param editorPart
	 * @return
	 */
	protected ITextEditor getTextEditor(IEditorPart editorPart) {
		if (editorPart instanceof ITextEditor) {
			return (ITextEditor) editorPart;
		}
		return (ITextEditor) editorPart.getAdapter(ITextEditor.class);
	}
	
	/* Get file
	 * @param editorInput
	 * @return
	 */
	protected IFile getFile(IEditorInput editorInput) {
		if (editorInput instanceof IFileEditorInput)
			return ((IFileEditorInput) editorInput).getFile();
		if (editorInput instanceof IStorageEditorInput) {
			try {
				return findFile(((IStorageEditorInput)editorInput).getStorage().getFullPath());
			} catch (CoreException e) {
				return null;
			}
		}
		if (editorInput instanceof IStorage) {
			return findFile(((IStorage)editorInput).getName());
		}
		return null;
	}
	
	/* Create position in the source file
	 * @param lineNumber
	 * @param doc
	 * @return
	 */
	protected Position createPosition(int lineNumber, IDocument doc) {
		if (doc == null)
			return null;
		try {
			IRegion region = doc.getLineInformation(lineNumber - 1);
			int charStart = region.getOffset();
			int length = region.getLength();
			if (charStart < 0)
				return null;
			return new Position(charStart, length);
		} catch (BadLocationException ble) {
			return null;
		}
	}
	
	/* Get tasks from debug target
	 * @param debugTarget
	 * @return
	 */
	protected TaskSet getTasks(IDebugTarget debugTarget) {
		if (debugTarget instanceof IPDebugTarget) {
			return ((IPDebugTarget) debugTarget).getTasks();
		}
		return null;
	}
	
	/* Get tasks from thread
	 * @param thread
	 * @return
	 */
	protected TaskSet getTasks(IThread thread) {
		return getTasks(thread.getDebugTarget());
	}
	
	/* Is given type register type
	 * @param type
	 * @return
	 */
	protected boolean isRegisterType(String type) {
		return (type.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT) || type.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY));
	}
	
	/* Focus to annotation in source editor
	 * @param editorPart
	 * @param stackFrame
	 * @throws CoreException
	 */
	protected void focusAnnotation(IEditorPart editorPart, IStackFrame stackFrame) throws CoreException {
		ITextEditor textEditor = getTextEditor(editorPart);
		int charStart = stackFrame.getCharStart();
		if (charStart > 0) {
			textEditor.selectAndReveal(charStart, 0);
			return;
		}
		int lineNumber = stackFrame.getLineNumber();
		lineNumber--;
		IRegion region= getLineInformation(textEditor, lineNumber);
		if (region != null) {
			textEditor.selectAndReveal(region.getOffset(), 0);
		}
	}
	
	/* Get line region in source editor
	 * @param editor
	 * @param lineNumber
	 * @return
	 */
	protected IRegion getLineInformation(ITextEditor editor, int lineNumber) {
		IDocumentProvider provider= editor.getDocumentProvider();
		IEditorInput input= editor.getEditorInput();
		try {
			provider.connect(input);
		} catch (CoreException e) {
			return null;
		}
		try {
			IDocument document= provider.getDocument(input);
			if (document != null)
				return document.getLineInformation(lineNumber);
		} catch (BadLocationException e) {
		} finally {
			provider.disconnect(input);
		}
		return null;
	}
	
	// called by debug view - PDebugModelPresentation
	/* Add annotation called from Debug View
	 * @param editorPart
	 * @param stackFrame
	 * @throws CoreException
	 */
	public void addAnnotation(IEditorPart editorPart, IPStackFrame stackFrame) throws CoreException {
		IPStackFrame selectedFrame = stackFrame;
		
		TaskSet tasks = getTasks(stackFrame.getDebugTarget());
		if (tasks == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		
		ITextEditor textEditor = getTextEditor(editorPart);
		if (textEditor == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		
		IFile file = getFile(textEditor.getEditorInput());
		if (file == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		
		//try to find the stack frame with line number
		if (selectedFrame.getLineNumber() == 0) {
			IStackFrame[] frames = selectedFrame.getThread().getStackFrames();
			for (IStackFrame frame : frames) {
				if (frame.getLineNumber() > 0) {
					selectedFrame = (IPStackFrame)frame;
					break;
				}
			}
		}
		
		if (selectedFrame.getLineNumber() > 0) {
			String job_id = uiDebugManager.getCurrentJobId();
			synchronized (LOCK) {
				AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
				if (annotationGroup == null) {
					annotationGroup = new AnnotationGroup();
					putAnnotationGroup(job_id, annotationGroup);
				}
				removeAnnotation(annotationGroup, tasks);
				addAnnotation(annotationGroup, textEditor, file, selectedFrame.getLineNumber(), tasks, (selectedFrame.getLevel() > 1) ? IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY : IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT);
			}
		}
	}
	
	/**
	 * Get the source locator for this debug launch
	 * 
	 * @param job_id id of debug job
	 * @return source locator or null if not found
	 */
	private PSourceLookupDirector getSourceLocator(String job_id) {
		IPSession session = uiDebugManager.getDebugSession(job_id);
		if (session != null) {
			ISourceLocator locator = session.getLaunch().getSourceLocator();
			if (locator instanceof PSourceLookupDirector) {
				return (PSourceLookupDirector)locator;
			}
		}
		return null;
	}
	
	private IPath getFilePath(String job_id, String filename) {
		PSourceLookupDirector locator = getSourceLocator(job_id);
		if (locator != null) {
			Object object = locator.getSourceElement(filename);
			if (object instanceof IFile) {
				return ((IFile)object).getFullPath();
			}
			if (object instanceof LocalFileStorage) {
				return ((LocalFileStorage)object).getFullPath();
			}
			if (object instanceof FileStorage) {
				return ((FileStorage)object).getFullPath();
			}
		}
		return new Path(filename);
	}
	
	// called by event
	/*
	 * Add annotation called from debug event
	 */
	protected void addUnregisterAnnotation(String job_id, int level, String filename, int lineNumber, TaskSet tasks) throws CoreException {
		if (tasks.isEmpty())
			return;

		IFile file = findFile(getFilePath(job_id, filename));
		if (file == null)
			throw new CoreException(Status.CANCEL_STATUS);

		IEditorPart editorPart = getEditorPart(file);
		if (editorPart == null)
			throw new CoreException(Status.CANCEL_STATUS);
		ITextEditor textEditor = getTextEditor(editorPart);
		if (textEditor == null)
			throw new CoreException(Status.CANCEL_STATUS);
		
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
			if (annotationGroup == null) {
				annotationGroup = new AnnotationGroup();
				putAnnotationGroup(job_id, annotationGroup);
			}
			addAnnotation(annotationGroup, textEditor, file, lineNumber, tasks, ((level > 1)?IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT:((containsCurrentSet(tasks)) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)));				
		}
	}
	
	/**
	 * Add annotation given filename and line number
	 * 
	 * @param job_id
	 * @param level
	 * @param filename
	 * @param lineNumber
	 * @param rTasks
	 * @param uTasks
	 * @throws CoreException
	 */
	protected void addAnnotation(String job_id, int level, String filename, int lineNumber, TaskSet rTasks, TaskSet uTasks) throws CoreException {
		IFile file = findFile(getFilePath(job_id, filename));
		if (file == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}

		IEditorPart editorPart = getEditorPart(file);
		if (editorPart == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		
		ITextEditor textEditor = getTextEditor(editorPart);
		if (textEditor == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
			if (annotationGroup == null) {
				annotationGroup = new AnnotationGroup();
				putAnnotationGroup(job_id, annotationGroup);
			}
			addAnnotation(annotationGroup, textEditor, file, lineNumber, rTasks, ((level > 1)?IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY: IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT));				
			addAnnotation(annotationGroup, textEditor, file, lineNumber, uTasks, ((level > 1)?IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT:((containsCurrentSet(uTasks)) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)));				
		}
	}
	
	/* Is given tasks in the current set
	 * @param aTasks
	 * @return
	 */
	protected boolean containsCurrentSet(TaskSet aTasks) {
		String set_id = uiDebugManager.getCurrentSetId();
		if (set_id.equals(IElementHandler.SET_ROOT_ID))
			return true;
		try {
			TaskSet tasks = uiDebugManager.getTasks(set_id);
			return (tasks != null && tasks.intersects(aTasks));
		}
		catch (CoreException e) {
			return false;
		}
	}
	
	// generic
	/* Add annotation
	 * @param annotationGroup
	 * @param textEditor
	 * @param file
	 * @param lineNumber
	 * @param tasks
	 * @param type
	 * @throws CoreException
	 */
	protected void addAnnotation(AnnotationGroup annotationGroup, final ITextEditor textEditor, final IFile file, final int lineNumber, final TaskSet tasks, final String type) throws CoreException {
		if (!tasks.isEmpty()) {
			IDocumentProvider docProvider = textEditor.getDocumentProvider();
			IAnnotationModel annotationModel = docProvider.getAnnotationModel(textEditor.getEditorInput());
			if (annotationModel == null)
				throw new CoreException(Status.CANCEL_STATUS);
			final Position position = createPosition(lineNumber, docProvider.getDocument(textEditor.getEditorInput()));
			if (position == null)
				throw new CoreException(Status.CANCEL_STATUS);

			synchronized (LOCK) {
				PInstructionPointerAnnotation2 annotation = findAnnotation(annotationGroup, position, type);
				if (annotation == null) {
					annotation = new PInstructionPointerAnnotation2(file, type, position, annotationModel);
					annotationGroup.addAnnotation(annotation);
				}
				annotation.addTasks(tasks);
				annotation.setMessage(isRegisterType(type));
			}
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					textEditor.selectAndReveal(position.getOffset(), 0);
				}
			});
		}
	}
	
	/* Find annotation
	 * @param annotationGroup
	 * @param position
	 * @param type
	 * @return
	 */
	protected PInstructionPointerAnnotation2 findAnnotation(AnnotationGroup annotationGroup, Position position, String type) {
		synchronized (LOCK) {
			for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
				if (annotation.getPosition().equals(position)) {
					if (annotation.getType().equals(type)) {
						return annotation;
					}
				}
			}
			return null;
		}
	}
	
	// called by debug view
	/* Remove annotation called from Debug View
	 * @param editorPart
	 * @param thread
	 * @throws CoreException
	 */
	protected void removeAnnotation(IEditorPart editorPart, IPThread thread) throws CoreException {
		removeAnnotation(uiDebugManager.getCurrentJobId(), getTasks(thread));
	}
	
	// called by event
	/* Remove annotation called from debug event
	 * @param job_id
	 * @param tasks
	 * @throws CoreException
	 */
	protected void removeAnnotation(String job_id, TaskSet tasks) throws CoreException {
		if (tasks == null || tasks.isEmpty())
			throw new CoreException(Status.CANCEL_STATUS);
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
			if (annotationGroup != null) {
				removeAnnotation(annotationGroup, tasks);
				if (annotationGroup.isEmpty())
					removeAnnotationGroup(job_id);
			}
		}
	}
	
	// generic
	/* Remove annotation
	 * @param annotationGroup
	 * @param tasks
	 * @throws CoreException
	 */
	protected void removeAnnotation(AnnotationGroup annotationGroup, TaskSet tasks) throws CoreException {
		synchronized (LOCK) {
			List<PInstructionPointerAnnotation2> removedList = new ArrayList<PInstructionPointerAnnotation2>(0);
			for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
				annotation.removeTasks(tasks);
				if (annotation.isEmpty()) {
					annotation.removeAnnotation();
					removedList.add(annotation);
				} else {
					annotation.setMessage(isRegisterType(annotation.getType()));
				}
			}
			annotationGroup.removeAnnotations(removedList);
		}
	}
	
	/* Get iterator of stored annotations
	 * @param annotationGroup
	 * @param type
	 * @return
	 */
	public PInstructionPointerAnnotation2[] findAnnotations(AnnotationGroup annotationGroup, String type) {
		synchronized (LOCK) {
			List<PInstructionPointerAnnotation2> foundAnnotations = new ArrayList<PInstructionPointerAnnotation2>();
			for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
				if (annotation.getType().equals(type)) {
					foundAnnotations.add(annotation);
				}
			}
			return foundAnnotations.toArray(new PInstructionPointerAnnotation2[0]);
		}
	}
	
	protected PInstructionPointerAnnotation2[] findAnnotations(AnnotationGroup annotationGroup, TaskSet tasks) {
		synchronized (LOCK) {
			List<PInstructionPointerAnnotation2> foundAnnotations = new ArrayList<PInstructionPointerAnnotation2>();
			if (tasks.isEmpty())
				return new PInstructionPointerAnnotation2[0];

			for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
				if (!annotation.isMarkDeleted() && annotation.contains(tasks)) {
					if (!foundAnnotations.contains(annotation))
						foundAnnotations.add(annotation);
				}
			}
			return foundAnnotations.toArray(new PInstructionPointerAnnotation2[0]);
		}
	}
	
	/* Find other annotation
	 * @param annotationGroup
	 * @param position
	 * @param isRegister
	 * @return
	 */
	protected PInstructionPointerAnnotation2 findOtherTypeAnnotation(AnnotationGroup annotationGroup, Position position, boolean isRegister) {
		synchronized (LOCK) {
			for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
				if (annotation.getPosition().equals(position)) {
					String annotationType = annotation.getType();
					if (isRegister) {
						if (annotationType.equals(IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT) || annotationType.equals(IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT))
							return annotation;
					} else {
						if (annotationType.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT) || annotationType.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY))
							return annotation;
					}
				}
			}
			return null;
		}
	}
	
	/* Change annotation type
	 * @param annotation
	 * @param type
	 */
	protected void changeAnnotationType(PInstructionPointerAnnotation2 annotation, String type) {
		if (!annotation.getType().equals(type)) {			
			annotation.setType(type);
		}
	}
	
	protected void register(String job_id, TaskSet tasks) {
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
			if (annotationGroup != null) {
				for (PInstructionPointerAnnotation2 annotation : findAnnotations(annotationGroup, tasks)) {
					TaskSet cpTasks = tasks.copy();
					cpTasks.and(annotation.getTasks());
					if (cpTasks.isEmpty())
						continue;
					
					updateExistedAnnotation(annotationGroup, annotation, cpTasks, false);
					/*
					boolean isRegister = isRegisterType(annotation.getType());
					if (!isRegister)// unregister annotation
						updateExistedAnnotation(annotationGroup, annotation, cpTasks, isRegister);
					*/
				}
			}
		}
	}
	
	protected void unregister(String job_id, TaskSet tasks) {
		synchronized (LOCK) {
			AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
			if (annotationGroup != null) {
				for (PInstructionPointerAnnotation2 annotation : findAnnotations(annotationGroup, tasks)) {
					TaskSet cpTasks = tasks.copy();
					cpTasks.and(annotation.getTasks());
					if (cpTasks.isEmpty())
						continue;

					updateExistedAnnotation(annotationGroup, annotation, cpTasks, true);
					/*
					boolean isRegister = isRegisterType(annotation.getType());
					if (isRegister)// register annotation
						updateExistedAnnotation(annotationGroup, annotation, cpTasks, isRegister);
					*/
				}
			}
		}
	}
	
	/* Remove tasks from existed annotation
	 * @param annotationGroup
	 * @param annotation
	 * @param tasks Tasks being removed
	 * @param isRegister
	 * @throws CoreException
	 */
	protected void updateExistedAnnotation(AnnotationGroup annotationGroup, PInstructionPointerAnnotation2 annotation, TaskSet tasks, boolean isRegister) {
		synchronized (LOCK) {
			IResource file = annotation.getMakerResource();
			Position position = annotation.getPosition();
			annotation.removeTasks(tasks);
			if (annotation.isEmpty()) {
				annotation.removeAnnotation();
				annotationGroup.removeAnnotation(annotation);
			}
			else {
				annotation.setMessage(isRegister);
			}
	
			PInstructionPointerAnnotation2 oAnnotation = findOtherTypeAnnotation(annotationGroup, position, isRegister);
			if (oAnnotation != null) {
				oAnnotation.addTasks(tasks);
				oAnnotation.setMessage(!isRegister);
			}
			else {
				//String type = isRegister ? ((containsCurrentSet(tasks) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)) : IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT;
				String type = IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT;
				oAnnotation = new PInstructionPointerAnnotation2(file, type, position, annotation.getAnnotationModel());
				annotationGroup.addAnnotation(oAnnotation);
				oAnnotation.addTasks(tasks);
				oAnnotation.setMessage(!isRegister);
			}
		}
	}
	
	/***************************************************************************************************************************************************************************************************
	 * Set Change Event
	 **************************************************************************************************************************************************************************************************/
	/* Update annotation
	 * @param currentSet current set
	 * @param preSet previous set
	 * @throws CoreException
	 */
	public void updateAnnotation(final IElementSet currentSet, final IElementSet preSet) {
		WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
			public IStatus runInUIThread(IProgressMonitor monitor) {
				AnnotationGroup annotationGroup = getAnnotationGroup(uiDebugManager.getCurrentJobId());
				if (annotationGroup != null) {
					try {
						TaskSet tasks = uiDebugManager.getTasks(currentSet.getID());
						synchronized (LOCK) {
							for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
								// change icon for unregistered processes only if the set is changed
								if (!isRegisterType(annotation.getType())) {
									// if all the tasks in current is not match the unregistered tasks, display SET_ANN
									// simply only display SET_ANN when the current set only contain registered tasks
									if (currentSet.isRootSet())
										changeAnnotationType(annotation, IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT);
									else
										changeAnnotationType(annotation, annotation.contains(tasks) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT);
								}
							}
						}
					}
					catch (CoreException e) {
						return e.getStatus();
					}
				}
				return Status.OK_STATUS;
			}
		};
		uiJob.setSystem(true);
		uiJob.setPriority(Job.INTERACTIVE);
		uiJob.schedule();
	}
	
	/***************************************************************************************************************************************************************************************************
	 * Job Change Listener
	 **************************************************************************************************************************************************************************************************/
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.ui.listeners.IJobChangedListener#jobChangedEvent(int, java.lang.String, java.lang.String)
	 */
	public void jobChangedEvent(final int type, final String cur_job_id, final String pre_job_id) {
		WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
			public IStatus runInUIThread(IProgressMonitor monitor) {
				doJobChangedEvent(type, cur_job_id, pre_job_id, monitor);
				monitor.done();
				return Status.OK_STATUS;
			}
		};
		uiJob.setSystem(true);
		uiJob.setPriority(Job.INTERACTIVE);
		uiJob.schedule();
	}
	
	private void doJobChangedEvent(int type, String cur_job_id, String pre_job_id, IProgressMonitor monitor) {
		if (type == IJobChangedListener.REMOVED || (pre_job_id != null && !pre_job_id.equals(IElementManager.EMPTY_ID))) {
			AnnotationGroup preAnnotationGroup = getAnnotationGroup(pre_job_id);
			if (preAnnotationGroup != null) {
				preAnnotationGroup.throwAllAnnotations();
			}
		}
		if (cur_job_id != null) {
			AnnotationGroup curAnnotationGroup = getAnnotationGroup(cur_job_id);
			if (curAnnotationGroup != null) {
				curAnnotationGroup.retrieveAllAnnontations();
			}
		}		
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.debug.core.IPDebugEventListener#handleDebugEvent(org.eclipse.ptp.debug.core.events.IPDebugEvent)
	 */
	public void handleDebugEvent(final IPDebugEvent event) {
		WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
			public IStatus runInUIThread(IProgressMonitor monitor) {
				doHandleDebugEvent(event, monitor);
				monitor.done();
				return Status.OK_STATUS;
			}
		};
		uiJob.setSystem(true);
		uiJob.setPriority(Job.INTERACTIVE);
		uiJob.schedule();
	}
	
	/**
	 * Process the debug event
	 * 
	 * @param event
	 * @param monitor
	 */
	private void doHandleDebugEvent(IPDebugEvent event, IProgressMonitor monitor) {
		IPDebugInfo info = event.getInfo();
		IPJob job = info.getJob();
		switch(event.getKind()) {
			case IPDebugEvent.CREATE:
				switch (event.getDetail()) {
				case IPDebugEvent.REGISTER:
					register(job.getID(), info.getAllTasks());
					break;
				case IPDebugEvent.BREAKPOINT:
					break;
				}
				break;
			case IPDebugEvent.TERMINATE:
				switch (event.getDetail()) {
				case IPDebugEvent.DEBUGGER:
					removeAnnotationGroup(job.getID());
					break;
				case IPDebugEvent.REGISTER:
					unregister(job.getID(), info.getAllTasks());
					break;
				case IPDebugEvent.BREAKPOINT:
					break;
				default:
					removeAnnotationAction(job, info.getAllTasks());
					break;
				}
				break;
			case IPDebugEvent.RESUME:
				removeAnnotationAction(job, info.getAllTasks());
				break;
			case IPDebugEvent.SUSPEND:
				IPDebugSuspendInfo susInfo = (IPDebugSuspendInfo)info;
				try {
					addAnnotation(job, susInfo);
				} catch (final CoreException e) {
					PTPDebugUIPlugin.getDisplay().asyncExec(new Runnable() {
						public void run() {
							PTPDebugUIPlugin.errorDialog(Messages.PAnnotationManager_0, e);
						}
					});
				}
				break;
			case IPDebugEvent.CHANGE:
				break;
			case IPDebugEvent.ERROR:
				//removeAnnotationAction(job, info.getAllTasks());
				break;
		}
	}
	
	/**
	 * Add annotation for a suspend event
	 * 
	 * @param job debug job
	 * @param info suspend event information
	 * @throws CoreException
	 */
	private void addAnnotation(IPJob job, IPDebugSuspendInfo info) throws CoreException {
		int line = info.getLineNumber();
		if (line == 0) {
			//FIXME: this method is only for unreg tasks, reg tasks depends on selection on stack frame on debug view
			addAnnotationWithSourceFound(job, info.getAllUnregisteredTasks(), info.getLevel()+1, info.getDepth());
		}
		else {
			addAnnotation(job.getID(), info.getLevel(), info.getFilename(), line, info.getAllRegisteredTasks(), info.getAllUnregisteredTasks());
		}
	}
	
	private void addAnnotationWithSourceFound(IPJob job, TaskSet tasks, int low, int high) throws CoreException {
		if (tasks.isEmpty())
			return;

		IPSession session = uiDebugManager.getDebugSession(job);
		if (session != null) {
			if (!session.isReady())
				return;
			
			IPDIListStackFramesRequest request = session.getPDISession().getRequestFactory().getListStackFramesRequest(session.getPDISession(), 
					tasks, low, high);
			try {
				session.getPDISession().getEventRequestManager().addEventRequest(request);
				Map<TaskSet, Object> map = request.getResultMap(tasks);
				for (Iterator<TaskSet> i = map.keySet().iterator(); i.hasNext();) {
					TaskSet sTasks = i.next();
					Object value = map.get(sTasks);
					if (value instanceof ProxyDebugStackFrame[]) {
						ProxyDebugStackFrame[] frames = (ProxyDebugStackFrame[])value;
						for (ProxyDebugStackFrame frame : frames) {
							ProxyDebugLocator locator = frame.getLocator();
							if (locator.getLineNumber() > 0) {
								addUnregisterAnnotation(job.getID(), frame.getLevel(), locator.getFile(), locator.getLineNumber(), sTasks);
								break;
							}
						}
					}
				}
			}
			catch (PDIException e) {
				//throw new CoreException(new Status(IStatus.ERROR, PTPDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), null));
			}
		}
	}
	
	private void removeAnnotationAction(IPJob job, TaskSet tasks) {
		try {
			removeAnnotation(job.getID(), tasks);
		}
		catch (final CoreException e) {
			PTPDebugUIPlugin.getDisplay().asyncExec(new Runnable() {
				public void run() {
					PTPDebugUIPlugin.errorDialog(Messages.PAnnotationManager_0, e);
				}
			});
		}
	}
}
