/*******************************************************************************
 * Copyright (c) 2000, 2011 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:
 *   Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation
 * 			(report 36180: Callers/Callees view)
 *   Stephan Herrmann (stephan@cs.tu-berlin.de):
 *          - bug 75800: [call hierarchy] should allow searches for fields
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.callhierarchy;

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

import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;

import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;

import org.eclipse.ui.texteditor.ITextEditor;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy;
import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation;
import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaUI;

import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;

public class CallHierarchyUI {
    private static final int DEFAULT_MAX_CALL_DEPTH= 10;
    private static final String PREF_MAX_CALL_DEPTH = "PREF_MAX_CALL_DEPTH"; //$NON-NLS-1$

    private static CallHierarchyUI fgInstance;
    private int fViewCount= 0;
    private final List<IMember[]> fMethodHistory= new ArrayList<IMember[]>();

	/**
	 * List of the Call Hierarchy views in LRU order, where the most recently used view is at index 0.
	 * @since 3.7
	 */
	private List<CallHierarchyViewPart> fLRUCallHierarchyViews= new ArrayList<CallHierarchyViewPart>();

    private CallHierarchyUI() {
        // Do nothing
    }

    public static CallHierarchyUI getDefault() {
        if (fgInstance == null) {
            fgInstance = new CallHierarchyUI();
        }

        return fgInstance;
    }

    /**
     * Returns the maximum tree level allowed
     * @return int
     */
    public int getMaxCallDepth() {
        int maxCallDepth;

        IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore();
        maxCallDepth = settings.getInt(PREF_MAX_CALL_DEPTH);
        if (maxCallDepth < 1 || maxCallDepth > 99) {
            maxCallDepth= DEFAULT_MAX_CALL_DEPTH;
        }

        return maxCallDepth;
    }

    public void setMaxCallDepth(int maxCallDepth) {
        IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore();
        settings.setValue(PREF_MAX_CALL_DEPTH, maxCallDepth);
    }

    public static void jumpToMember(IJavaElement element) {
        if (element != null) {
            try {
                JavaUI.openInEditor(element, true, true);
            } catch (JavaModelException e) {
                JavaPlugin.log(e);
            } catch (PartInitException e) {
                JavaPlugin.log(e);
            }
        }
    }

    public static void jumpToLocation(CallLocation callLocation) {
        try {
            IEditorPart methodEditor = JavaUI.openInEditor(callLocation.getMember(), false, false);
            if (methodEditor instanceof ITextEditor) {
                ITextEditor editor = (ITextEditor) methodEditor;
                editor.selectAndReveal(callLocation.getStart(),
                    (callLocation.getEnd() - callLocation.getStart()));
            }
        } catch (JavaModelException e) {
            JavaPlugin.log(e);
        } catch (PartInitException e) {
            JavaPlugin.log(e);
        }
    }

	/**
	 * Opens the element in the editor or shows an error dialog if that fails.
	 *
	 * @param element the element to open
	 * @param shell parent shell for error dialog
	 * @param activateOnOpen <code>true</code> if the editor should be activated
	 * @return <code>true</code> iff no error occurred while trying to open the editor,
	 *         <code>false</code> iff an error dialog was raised.
	 */
	public static boolean openInEditor(Object element, Shell shell, boolean activateOnOpen) {
        CallLocation callLocation= CallHierarchy.getCallLocation(element);

        try {
	        IMember enclosingMember;
	        int selectionStart;
			int selectionLength;

	        if (callLocation != null) {
				enclosingMember= callLocation.getMember();
				selectionStart= callLocation.getStart();
				selectionLength= callLocation.getEnd() - selectionStart;
	        } else if (element instanceof MethodWrapper) {
	        	enclosingMember= ((MethodWrapper) element).getMember();
	        	ISourceRange selectionRange= enclosingMember.getNameRange();
	        	if (selectionRange == null)
	        		selectionRange= enclosingMember.getSourceRange();
	        	if (selectionRange == null)
	        		return true;
	        	selectionStart= selectionRange.getOffset();
	        	selectionLength= selectionRange.getLength();
	        } else {
	            return true;
	        }

			IEditorPart methodEditor = JavaUI.openInEditor(enclosingMember, activateOnOpen, false);
            if (methodEditor instanceof ITextEditor) {
                ITextEditor editor = (ITextEditor) methodEditor;
				editor.selectAndReveal(selectionStart, selectionLength);
            }
            return true;
        } catch (JavaModelException e) {
            JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),
                    IJavaStatusConstants.INTERNAL_ERROR,
                    CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message, e));

            ErrorDialog.openError(shell, CallHierarchyMessages.OpenLocationAction_error_title,
                CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_message,
                e.getStatus());
            return false;
        } catch (PartInitException x) {
            String name;
        	if (callLocation != null)
        		name= callLocation.getCalledMember().getElementName();
        	else if (element instanceof MethodWrapper)
        		name= ((MethodWrapper) element).getName();
        	else
        		name= "";  //$NON-NLS-1$
            MessageDialog.openError(shell, CallHierarchyMessages.OpenLocationAction_error_title,
                Messages.format(
                    CallHierarchyMessages.CallHierarchyUI_open_in_editor_error_messageArgs,
                    new String[] { name, x.getMessage() }));
            return false;
        }
    }

    public static IEditorPart isOpenInEditor(Object elem) {
        IJavaElement javaElement= null;
        if (elem instanceof MethodWrapper) {
            javaElement= ((MethodWrapper) elem).getMember();
        } else if (elem instanceof CallLocation) {
            javaElement= ((CallLocation) elem).getCalledMember();
        }
        if (javaElement != null) {
            return EditorUtility.isOpenInEditor(javaElement);
        }
        return null;
    }

    public static CallHierarchyViewPart openSelectionDialog(IMember[] candidates, IWorkbenchWindow window) {
        Assert.isTrue(candidates != null);

        IMember input= null;
        if (candidates.length > 1) {
            String title= CallHierarchyMessages.CallHierarchyUI_selectionDialog_title;
            String message= CallHierarchyMessages.CallHierarchyUI_selectionDialog_message;
            input= (IMember) SelectionConverter.selectJavaElement(candidates, window.getShell(), title, message);
        } else if (candidates.length == 1) {
            input= candidates[0];
        }
        if (input == null)
            return openView(new IMember[] {}, window);

        return openView(new IMember[] { input }, window);
    }

    public static CallHierarchyViewPart openView(IMember[] input, IWorkbenchWindow window) {
    	if (input.length == 0) {
			MessageDialog.openInformation(window.getShell(), CallHierarchyMessages.CallHierarchyUI_selectionDialog_title,
					CallHierarchyMessages.CallHierarchyUI_open_operation_unavialable);
			return null;
		}
        IWorkbenchPage page= window.getActivePage();
		try {
			CallHierarchyViewPart viewPart= getDefault().findLRUCallHierarchyViewPart(page); //find the first view which is not pinned
			String secondaryId= null;
			if (viewPart == null) {
				if (page.findViewReference(CallHierarchyViewPart.ID_CALL_HIERARCHY) != null) //all the current views are pinned, open a new instance
					secondaryId= String.valueOf(++getDefault().fViewCount);
			} else
				secondaryId= viewPart.getViewSite().getSecondaryId();
			viewPart= (CallHierarchyViewPart)page.showView(CallHierarchyViewPart.ID_CALL_HIERARCHY, secondaryId, IWorkbenchPage.VIEW_ACTIVATE);
			viewPart.setInputElements(input);
			return viewPart;
        } catch (CoreException e) {
            ExceptionHandler.handle(e, window.getShell(),
                CallHierarchyMessages.CallHierarchyUI_error_open_view, e.getMessage());
        }
        return null;
    }

	/**
	 * Finds the first Call Hierarchy view part instance that is not pinned.
	 * 
	 * @param page the active page
	 * @return the Call Hierarchy view part to open or <code>null</code> if none found
	 * @since 3.7
	 */
	private CallHierarchyViewPart findLRUCallHierarchyViewPart(IWorkbenchPage page) {
		boolean viewFoundInPage= false;
		for (Iterator<CallHierarchyViewPart> iter= fLRUCallHierarchyViews.iterator(); iter.hasNext();) {
			CallHierarchyViewPart view= iter.next();
			if (page.equals(view.getSite().getPage())) {
				if (!view.isPinned()) {
					return view;
				}
				viewFoundInPage= true;
			}
		}
		if (!viewFoundInPage) {
			// find unresolved views
			IViewReference[] viewReferences= page.getViewReferences();
			for (int i= 0; i < viewReferences.length; i++) {
				IViewReference curr= viewReferences[i];
				if (CallHierarchyViewPart.ID_CALL_HIERARCHY.equals(curr.getId()) && page.equals(curr.getPage())) {
					CallHierarchyViewPart view= (CallHierarchyViewPart)curr.getView(true);
					if (view != null && !view.isPinned()) {
						return view;
					}
				}
			}
		}
		return null;
	}

	/**
	 * Adds the activated view part to the head of the list.
	 * 
	 * @param view the Call Hierarchy view part
	 * @since 3.7
	 */
	void callHierarchyViewActivated(CallHierarchyViewPart view) {
		fLRUCallHierarchyViews.remove(view);
		fLRUCallHierarchyViews.add(0, view);
	}

	/**
	 * Removes the closed view part from the list.
	 * 
	 * @param view the closed view part
	 * @since 3.7
	 */
	void callHierarchyViewClosed(CallHierarchyViewPart view) {
		fLRUCallHierarchyViews.remove(view);
	}

    /**
     * Converts an ISelection (containing MethodWrapper instances) to an ISelection
     * with the MethodWrapper's replaced by their corresponding IMembers. If the selection
     * contains elements which are not MethodWrapper instances or not already IMember instances
     * they are discarded.
     * @param selection The selection to convert.
     * @return An ISelection containing IMember's in place of MethodWrapper instances.
     */
    static ISelection convertSelection(ISelection selection) {
        if (selection.isEmpty()) {
            return selection;
        }

        if (selection instanceof IStructuredSelection) {
            IStructuredSelection structuredSelection= (IStructuredSelection) selection;
            List<IMember> javaElements= new ArrayList<IMember>();
            for (Iterator<?> iter= structuredSelection.iterator(); iter.hasNext();) {
                Object element= iter.next();
                if (element instanceof MethodWrapper) {
                    IMember member= ((MethodWrapper)element).getMember();
                    if (member != null) {
                        javaElements.add(member);
                    }
                } else if (element instanceof IMember) {
                    javaElements.add((IMember) element);
                } else if (element instanceof CallLocation) {
                    IMember member = ((CallLocation) element).getMember();
                    javaElements.add(member);
                }
            }
            return new StructuredSelection(javaElements);
        }
        return StructuredSelection.EMPTY;
    }

	/**
	 * Clears the history and updates all the open views.
	 * 
	 * @since 3.7
	 */
	void clearHistory() {
		for (Iterator<CallHierarchyViewPart> iter= fLRUCallHierarchyViews.iterator(); iter.hasNext();) {
			CallHierarchyViewPart part= iter.next();
			part.setHistoryEntries(new IMember[0][]);
			part.setInputElements(null);
		}
	}

	/**
	 * Returns the method history.
	 * 
	 * @return the method history
	 * @since 3.7
	 */
	List<IMember[]> getMethodHistory() {
		return fMethodHistory;
	}
}
