/*******************************************************************************
 * Copyright (c) 2006, 2012 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.heapwalking;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugView;
import org.eclipse.debug.ui.InspectPopupDialog;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIAllInstancesValue;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIReferenceType;
import org.eclipse.jdt.internal.debug.ui.DebugWorkingCopyManager;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JavaWordFinder;
import org.eclipse.jdt.internal.debug.ui.actions.ObjectActionDelegate;
import org.eclipse.jdt.internal.debug.ui.actions.PopupInspectAction;
import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorActionDelegate;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.PageBookView;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * Class to provide new function of viewing all live objects of the selected type in the current VM
 * Feature of 1.6 VMs
 * 
 * @since 3.3
 */
public class AllInstancesActionDelegate  extends ObjectActionDelegate implements IEditorActionDelegate, IWorkbenchWindowActionDelegate {

	private IWorkbenchWindow fWindow;
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	public void run(IAction action) {
		if (getPart() != null){
			ISelectionProvider provider = getPart().getSite().getSelectionProvider();
			if (provider != null){
				ISelection selection = provider.getSelection();

				// If in an editor, get the text selection and check if a type is selected
				if (getPart() instanceof IEditorPart && selection instanceof ITextSelection){
					ITextEditor editor = getTextEditor(getPart());
					IDocumentProvider documentProvider = editor.getDocumentProvider();
					if (documentProvider != null) {
					    IDocument document = documentProvider.getDocument(editor.getEditorInput());
					    IRegion selectedWord = JavaWordFinder.findWord(document,((ITextSelection)selection).getOffset());
					    if (selectedWord != null){
					    	IJavaElement element = getJavaElement(editor.getEditorInput());
					    	if (element instanceof ICodeAssist){
					    		try{
						    		IJavaElement[] selectedTypes = ((ICodeAssist)element).codeSelect(selectedWord.getOffset(), selectedWord.getLength());
						    		// findWord() will only return one element, so only check the first element
						    		if (selectedTypes.length > 0){
						    			runForSelection(selectedTypes[0]);  
						    			return;
						    		}
								} catch (JavaModelException e){
									JDIDebugUIPlugin.log(e.getStatus());
									report(Messages.AllInstancesActionDelegate_0,getPart());
					    		}
					    	}
					    }
					}
					
				// Otherwise, get the first selected element and check if it is a type
				} else if (selection instanceof IStructuredSelection){
					runForSelection(((IStructuredSelection)selection).getFirstElement());
					return;
				}
			}
		}
		report(Messages.AllInstancesActionDelegate_3,getPart());
	}
	
	/**
	 * Resolves a debug reference type for the selected element and then
	 * runs the action.
	 * 
	 * @param selectedElement a method, type, or variable
	 */
	protected void runForSelection(Object selectedElement){
		if (selectedElement != null){
						
			IJavaType type = null;
			try {
				// If the element is a constructor, get instances of its declaring type
				if (selectedElement instanceof IMethod){
					if (((IMethod)selectedElement).isConstructor()){
						selectedElement = ((IMethod)selectedElement).getDeclaringType();
					}
				}
				// If the element is an IType, get the corresponding java variable from the VM
				if(selectedElement instanceof IType) {
					IAdaptable adapt = DebugUITools.getDebugContext();
					if(adapt != null) {
						IJavaDebugTarget target = (IJavaDebugTarget) adapt.getAdapter(IJavaDebugTarget.class);
						if(target != null) {
							IType itype = (IType) selectedElement;
							IJavaType[] types = target.getJavaTypes(itype.getFullyQualifiedName());
							if(types != null && types.length > 0) {
								type = types[0];
							} else {
								// If the type is not known the the VM, open a pop-up dialog with 0 instances
								displayNoInstances(target, itype.getFullyQualifiedName());
								return;
							}
						}
					}
				}
				// If the selected element is a java variable, just get the type
				if (selectedElement instanceof IJavaVariable) {
					IJavaVariable var = (IJavaVariable) selectedElement;
					IValue val = var.getValue();
					if (val instanceof IJavaValue){
						type = ((IJavaValue)val).getJavaType();
					}
					if (type == null){
						type = var.getJavaType();
					}
				}
				
			} catch (JavaModelException e){
				JDIDebugUIPlugin.log(e.getStatus());
			} catch (DebugException e) {
				JDIDebugUIPlugin.log(e.getStatus());
			}
					
			if(type instanceof JDIReferenceType) {
				JDIReferenceType rtype = (JDIReferenceType) type;
				displayInstaces((JDIDebugTarget)rtype.getDebugTarget(), rtype);
				return;
			}
		}
		report(Messages.AllInstancesActionDelegate_3,getPart());
	}
	
	/**
	 * No types are loaded in the given target with the specified type name. Displays the result.
	 * 
	 * @param target target
	 * @param typeName resolve type name
	 */
	protected void displayNoInstances(IJavaDebugTarget target, String typeName) {
		JDIAllInstancesValue aiv = new JDIAllInstancesValue((JDIDebugTarget)target, null);
		InspectPopupDialog ipd = new InspectPopupDialog(getShell(), 
				getAnchor(), 
				PopupInspectAction.ACTION_DEFININITION_ID,
				new JavaInspectExpression(NLS.bind(Messages.AllInstancesActionDelegate_2, new String[]{typeName}), aiv));
		ipd.open();
	}
	
	/**
	 * Display instances of the given resolved type.
	 * 
	 * @param target target
	 * @param rtype resolved reference type
	 */
	protected void displayInstaces(IJavaDebugTarget target, JDIReferenceType rtype) {
		try{
			JDIAllInstancesValue aiv = new JDIAllInstancesValue((JDIDebugTarget)rtype.getDebugTarget(), rtype);
			InspectPopupDialog ipd = new InspectPopupDialog(getShell(), 
					getAnchor(), 
					PopupInspectAction.ACTION_DEFININITION_ID,
					new JavaInspectExpression(NLS.bind(Messages.AllInstancesActionDelegate_2, new String[]{rtype.getName()}), aiv));
			ipd.open();
		} catch (DebugException e) {
			JDIDebugUIPlugin.log(e);
			report(Messages.AllInstancesActionDelegate_0,getPart());
		}
	}
	
	 /**
     * Convenience method for printing messages to the status line
     * @param message the message to be displayed
     * @param part the currently active workbench part
     */
    protected void report(final String message, final IWorkbenchPart part) {
        JDIDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
            public void run() {
                IEditorStatusLine statusLine = (IEditorStatusLine) part.getAdapter(IEditorStatusLine.class);
                if (statusLine != null) {
                    if (message != null) {
                        statusLine.setMessage(true, message, null);
                    } else {
                        statusLine.setMessage(true, null, null);
                    }
                }
            }
        });
    }

	/**
	 * Compute an anchor based on selected item in the tree.
	 * 
	 * @return anchor point or <code>null</code> if one could not be obtained
	 */
    protected Point getAnchor() {
    	
    	// If it's a debug view (variables or expressions), get the location of the selected item
    	IDebugView debugView = (IDebugView)getPart().getAdapter(IDebugView.class);
		if (debugView != null){
			Control control = debugView.getViewer().getControl();
			if (control instanceof Tree) {
				Tree tree = (Tree) control;
				TreeItem[] selection = tree.getSelection();
				if (selection.length > 0) {
					Rectangle bounds = selection[0].getBounds();
					return tree.toDisplay(new Point(bounds.x, bounds.y + bounds.height));
				}
			}
		}
		
		//resolve the current control
    	Control widget = (Control)getPart().getAdapter(Control.class);
    	if (widget == null){
    		if(getPart() instanceof PageBookView) {
	    		//could be the outline view
	    		PageBookView view = (PageBookView) getPart();
	    		IPage page = view.getCurrentPage();
	    		if(page != null) {
	    			widget = page.getControl();
	    		}
	    	}
    	}
    	if (widget instanceof StyledText){
			StyledText textWidget = (StyledText)widget;
			Point docRange = textWidget.getSelectionRange();
	        int midOffset = docRange.x + (docRange.y / 2);
	        Point point = textWidget.getLocationAtOffset(midOffset);
	        point = textWidget.toDisplay(point);
	
	        GC gc = new GC(textWidget);
	        gc.setFont(textWidget.getFont());
	        int height = gc.getFontMetrics().getHeight();
	        gc.dispose();
	        point.y += height;
	        return point;
		}
		if (widget instanceof Tree) {
			Tree tree = (Tree) widget;
			TreeItem[] selection = tree.getSelection();
			if (selection.length > 0) {
				Rectangle bounds = selection[0].getBounds();
				return tree.toDisplay(new Point(bounds.x, bounds.y + bounds.height));
			}
		}
		return null;    	
    }
    	
    /**
     * Gets the <code>IJavaElement</code> from the editor input
     * @param input the current editor input
     * @return the corresponding <code>IJavaElement</code>
     */
    private IJavaElement getJavaElement(IEditorInput input) {
    	IJavaElement je = JavaUI.getEditorInputJavaElement(input);
    	if(je != null) {
    		return je;
    	}
    	//try to get from the working copy manager
    	return DebugWorkingCopyManager.getWorkingCopy(input, false);
    }
	
	
    /**
     * Returns the text editor associated with the given part or <code>null</code>
     * if none. In case of a multi-page editor, this method should be used to retrieve
     * the correct editor to perform the operation on.
     * 
     * @param part workbench part
     * @return text editor part or <code>null</code>
     */
    private ITextEditor getTextEditor(IWorkbenchPart part) {
    	if (part instanceof ITextEditor) {
    		return (ITextEditor) part;
    	}
    	return (ITextEditor) part.getAdapter(ITextEditor.class);
    }	
    
    /* (non-Javadoc)
	 * @see org.eclipse.ui.IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
	 */
	public void setActiveEditor(IAction action, IEditorPart targetEditor) {
		setActivePart(action, targetEditor);	
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
	 */
	public void init(IWorkbenchWindow window) {
		fWindow = window;
	}
	
	/**
	 * @return the shell to use for new popups or <code>null</code>
	 */
	protected Shell getShell(){
		if (fWindow != null){
			return fWindow.getShell();
		}
		if (getWorkbenchWindow() != null){
			return getWorkbenchWindow().getShell();
		}
		return null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.internal.debug.ui.actions.ObjectActionDelegate#getPart()
	 */
	@Override
	protected IWorkbenchPart getPart() {
		IWorkbenchPart part = super.getPart();
		if (part != null){
			return part;
		} else if (fWindow != null){
			IWorkbenchPage page = fWindow.getActivePage();
			if(page != null) {
				return page.getActivePart();
			}
		}
		return null;
	}
	
}
