/*******************************************************************************
 * Copyright (c) 2003, 2007 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.ui.navigator;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.Saveable;
import org.eclipse.ui.SaveablesLifecycleEvent;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.internal.navigator.CommonNavigatorActionGroup;
import org.eclipse.ui.internal.navigator.CommonNavigatorManager;
import org.eclipse.ui.internal.navigator.NavigatorContentService;
import org.eclipse.ui.internal.navigator.NavigatorPlugin;
import org.eclipse.ui.internal.navigator.extensions.LinkHelperService;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;

/**
 * <p>
 * This class provides the IViewPart for the Common Navigator framework in the
 * Eclipse workbench. This class also serves as the backbone for navigational
 * viewers. The following types are used by this class to render the Common
 * Navigator:
 * <ul>
 * <li>
 * <p>
 * {@link org.eclipse.ui.navigator.CommonViewer}: The viewer that renders the
 * extensible tree. Creates and manages the lifecylce of the Navigator Content
 * Service (described below).
 * </p>
 * </li>
 * <li>
 * <p>
 * {@link org.eclipse.ui.navigator.NavigatorActionService}: Manages instances
 * of {@link org.eclipse.ui.navigator.CommonActionProvider}s provided by
 * individual extensions and content extensions.
 * </p>
 * </li>
 * <li>
 * <p>
 * {@link org.eclipse.ui.navigator.INavigatorContentService}: Manages instances
 * of Navigator Content Extensions. Instances are created as needed, and
 * disposed of upon the disposal of the Navigator Content Service.
 * </p>
 * </li>
 * </ul>
 * <p>
 * Clients are not expected to subclass CommonNavigator. Clients that wish to
 * define their own custom extensible navigator view need to specify an instance
 * of the <b>org.eclipse.ui.views</b> extension point:
 * 
 * <pre>
 *   
 *          &lt;extension
 *          		point=&quot;org.eclipse.ui.views&quot;&gt;
 *          	&lt;view
 *          		name=&quot;My Custom View&quot;
 *          		icon=&quot;relative/path/to/icon.gif&quot;
 *          		category=&quot;org.acme.mycategory&quot;
 *          		class=&quot;org.eclipse.ui.navigator.CommonNavigator&quot;
 *          		id=&quot;org.acme.MyCustomNavigatorID&quot;&gt;
 *          	&lt;/view&gt;
 *          &lt;/extension&gt; 
 *    
 * </pre>
 * 
 * </p> 
 * Clients that wish to extend the view menu provided via the
 * <b>org.eclipse.ui.popupMenu</b>s extension may specify the the <i>popupMenuId</i>
 * specified by <b>org.eclipse.ui.navigator.viewer</b> (or a nested <b>popupMenu</b> element) of their target viewer
 * as their target menu id.
 * 
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 * @noextend This class is not intended to be subclassed by clients.
 *  
 * @since 3.2
 */
public class CommonNavigator extends ViewPart implements ISetSelectionTarget, ISaveablePart, ISaveablesSource, IShowInTarget {
 
	private static final Class INAVIGATOR_CONTENT_SERVICE = INavigatorContentService.class;
	private static final Class COMMON_VIEWER_CLASS = CommonViewer.class;
	private static final Class ISHOW_IN_TARGET_CLASS = IShowInTarget.class;
	
	private static final String HELP_CONTEXT =  NavigatorPlugin.PLUGIN_ID + ".common_navigator"; //$NON-NLS-1$

	/**
	 * <p>
	 * Used to track changes to the {@link #isLinkingEnabled}&nbsp;property.
	 * </p>
	 */
	public static final int IS_LINKING_ENABLED_PROPERTY = 1;

	private CommonViewer commonViewer;

	private CommonNavigatorManager commonManager;

	private ActionGroup commonActionGroup;

	private IMemento memento;

	private boolean isLinkingEnabled = false;

	private String LINKING_ENABLED = "CommonNavigator.LINKING_ENABLED"; //$NON-NLS-1$ 

	private LinkHelperService linkService;
	
	/**
	 * 
	 */
	public CommonNavigator() {
		super();
	}

	/**
	 * <p>
	 * Create the CommonViewer part control and setup the default providers as
	 * necessary.
	 * </p>
	 * 
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite aParent) {

		commonViewer = createCommonViewer(aParent);	

		try {
			commonViewer.getControl().setRedraw(false);
			
			INavigatorFilterService filterService = commonViewer
					.getNavigatorContentService().getFilterService();
			ViewerFilter[] visibleFilters = filterService.getVisibleFilters(true);
			for (int i = 0; i < visibleFilters.length; i++) {
				commonViewer.addFilter(visibleFilters[i]);
			}
	
			commonViewer.setSorter(new CommonViewerSorter());
	
			/*
			 * make sure input is set after sorters and filters to avoid unnecessary
			 * refreshes
			 */
			commonViewer.setInput(getInitialInput()); 
	
			getSite().setSelectionProvider(commonViewer);
	
			updateTitle();
		} finally { 
			commonViewer.getControl().setRedraw(true);
		}

		/*
		 * Create the CommonNavigatorManager last because information about the
		 * state of the CommonNavigator is required for the initialization of
		 * the CommonNavigatorManager
		 */
		commonManager = createCommonManager();
		if (memento != null) {			
			commonViewer.getNavigatorContentService().restoreState(memento);
		}

		commonActionGroup = createCommonActionGroup();
		commonActionGroup.fillActionBars(getViewSite().getActionBars());
		
		ISaveablesLifecycleListener saveablesLifecycleListener = new ISaveablesLifecycleListener() {
			ISaveablesLifecycleListener siteSaveablesLifecycleListener = (ISaveablesLifecycleListener) getSite()
					.getService(ISaveablesLifecycleListener.class);

			public void handleLifecycleEvent(SaveablesLifecycleEvent event) {
				if (event.getEventType() == SaveablesLifecycleEvent.DIRTY_CHANGED) {
					firePropertyChange(PROP_DIRTY);
				}
				siteSaveablesLifecycleListener.handleLifecycleEvent(event);
			}
		};
		commonViewer.getNavigatorContentService()
				.getSaveablesService().init(this, getCommonViewer(),
						saveablesLifecycleListener);
		
		commonViewer.addSelectionChangedListener(new ISelectionChangedListener() {

			public void selectionChanged(SelectionChangedEvent event) {
				firePropertyChange(PROP_DIRTY);
			}});
		
	      PlatformUI.getWorkbench().getHelpSystem().setHelp(commonViewer.getControl(),  HELP_CONTEXT);
	}

	/**
	 * <p>
	 * Note: This method is for internal use only. Clients should not call this
	 * method.
	 * </p>
	 * <p>
	 * This method will be invoked when the DisposeListener is notified of the
	 * disposal of the Eclipse view part.
	 * </p>
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
	 */
	public void dispose() {
		if (commonManager != null) {
			commonManager.dispose();
		}
		if(commonActionGroup != null) {
			commonActionGroup.dispose();
		}
		super.dispose();
	}

	/**
	 * <p>
	 * Note: This method is for internal use only. Clients should not call this
	 * method.
	 * </p>
	 * 
	 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite,
	 *      org.eclipse.ui.IMemento)
	 */
	public void init(IViewSite aSite, IMemento aMemento)
			throws PartInitException {
		super.init(aSite, aMemento);
		memento = aMemento;
		if (memento != null) {
			Integer linkingEnabledInteger = memento.getInteger(LINKING_ENABLED);
			setLinkingEnabled(((linkingEnabledInteger != null) ? linkingEnabledInteger
					.intValue() == 1
					: false));
		}

	}

	/**
	 * 
	 * <p>
	 * Note: This method is for internal use only. Clients should not call this
	 * method.
	 * </p>
	 * 
	 * @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
	 */
	public void saveState(IMemento aMemento) {
		aMemento.putInteger(LINKING_ENABLED, (isLinkingEnabled) ? 1 : 0);
		super.saveState(aMemento);
		commonManager.saveState(aMemento);
		commonViewer.getNavigatorContentService().saveState(aMemento);
	}

	/**
	 * <p>
	 * Force the workbench to focus on the Common Navigator tree.
	 * </p>
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	public void setFocus() {
		if (commonViewer != null) {
			commonViewer.getTree().setFocus();
		}
	}

	/**
	 * <p>
	 * Set the selection to the Common Navigator tree, and expand nodes if
	 * necessary. Use caution when invoking this method as it can cause
	 * Navigator Content Extensions to load, thus causing plugin activation.
	 * </p>
	 * 
	 * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
	 */
	public void selectReveal(ISelection selection) {
		if (commonViewer != null) {
			if(selection instanceof IStructuredSelection) {
				Object[] newSelection = ((IStructuredSelection)selection).toArray();
				Object[] expandedElements = commonViewer.getExpandedElements();
				Object[] newExpandedElements = new Object[newSelection.length + expandedElements.length];
				System.arraycopy(expandedElements, 0, newExpandedElements, 0, expandedElements.length);
				System.arraycopy(newSelection, 0, newExpandedElements, expandedElements.length, newSelection.length);
 				commonViewer.setExpandedElements(newExpandedElements);
			}
			commonViewer.setSelection(selection, true);
		}
	}

	/**
	 * <p>
	 * Linking is handled by an action which listens for
	 * changes to the {@link CommonNavigator#IS_LINKING_ENABLED_PROPERTY}.
	 * Custom implementations that wish to override this functionality, need to
	 * override the action used by the default ActionGroup and listen for
	 * changes to the above property.
	 * 
	 * @param toEnableLinking
	 *            True enables linking the current selection with open editors
	 */
	public final void setLinkingEnabled(boolean toEnableLinking) {
		isLinkingEnabled = toEnableLinking;
		firePropertyChange(IS_LINKING_ENABLED_PROPERTY);
	}

	/**
	 * @return Whether linking the current selection with open editors is
	 *         enabled.
	 */
	public final boolean isLinkingEnabled() {
		return isLinkingEnabled;
	}

	/**
	 * <p>
	 * Provides access to the commonViewer used by the current CommonNavigator.
	 * The field will not be valid until after
	 * {@link #init(IViewSite, IMemento)}&nbsp;has been called by the
	 * Workbench.
	 * </p>
	 *  
	 * @return The (already created) instance of Common Viewer.
	 */
	public CommonViewer getCommonViewer() {
		return commonViewer;
	}

	/**
	 * @return The Navigator Content Service which populates this instance of
	 *         Common Navigator
	 */
	public INavigatorContentService getNavigatorContentService() {
		return getCommonViewer().getNavigatorContentService();
	}

	/**
	 * Returns an object which is an instance of the given class
	 * associated with this object. Returns <code>null</code> if
	 * no such object can be found.
	 *
	 * @param adapter the adapter class to look up
	 * @return a object castable to the given class, 
	 *    or <code>null</code> if this object does not
	 *    have an adapter for the given class
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == COMMON_VIEWER_CLASS) {
			return getCommonViewer();
		} else if (adapter == INAVIGATOR_CONTENT_SERVICE) {
			return getCommonViewer().getNavigatorContentService();
		} else if ( adapter == ISHOW_IN_TARGET_CLASS) {
			return this;
		}
		return super.getAdapter(adapter);
	}

	/**
	 * @return The Navigator Content Service which populates this instance of
	 *         Common Navigator
	 */
	public NavigatorActionService getNavigatorActionService() {
		return commonManager.getNavigatorActionService();
	}

	/**
	 * <p>
	 * Constructs and returns an instance of {@link CommonViewer}. The ID of
	 * the Eclipse view part will be used to create the viewer. The ID is
	 * important as some extensions indicate they should only be used with a
	 * particular viewer ID.
	 * <p>
	 * 
	 * @param aParent
	 *            A composite parent to contain the Common Viewer
	 * @return An initialized instance of CommonViewer
	 */
	protected CommonViewer createCommonViewer(Composite aParent) {
		CommonViewer aViewer = new CommonViewer(getViewSite().getId(), aParent,
				SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		initListeners(aViewer);
		aViewer.getNavigatorContentService().restoreState(memento);
		return aViewer;
	}

	/**
	 * <p>
	 * Adds the listeners to the Common Viewer.
	 * </p>
	 * 
	 * @param viewer
	 *            The viewer
	 * @since 2.0
	 */
	protected void initListeners(TreeViewer viewer) {

		viewer.addDoubleClickListener(new IDoubleClickListener() {

			public void doubleClick(DoubleClickEvent event) {
				try {
					handleDoubleClick(event);
				} catch (RuntimeException re) {
					re.printStackTrace();
				}
			}
		});
	}

	/**
	 * <p>
	 * Note: This method is for internal use only. Clients should not call this
	 * method.
	 * </p>
	 * 
	 * @param anEvent
	 *            Supplied by the DoubleClick listener.
	 */
	protected void handleDoubleClick(DoubleClickEvent anEvent) {

		IAction openHandler = getViewSite().getActionBars().getGlobalActionHandler(ICommonActionConstants.OPEN);
		
		if(openHandler == null) {
			IStructuredSelection selection = (IStructuredSelection) anEvent
					.getSelection();
			Object element = selection.getFirstElement();
	
			TreeViewer viewer = getCommonViewer();
			if (viewer.isExpandable(element)) {
				viewer.setExpandedState(element, !viewer.getExpandedState(element));
			}
		}
	}

	/**
	 * <p>
	 * The Common Navigator Manager handles the setup of the Common Navigator
	 * Menu, manages updates to the ActionBars from
	 * {@link CommonActionProvider}&nbsp; extensions as the user's selection
	 * changes, and also updates the status bar based on the current selection.
	 * 
	 * @return The Common Navigator Manager class which handles menu population
	 *         and ActionBars
	 */
	protected CommonNavigatorManager createCommonManager() {
		return new CommonNavigatorManager(this, memento);
	}

	/**
	 * <p>
	 * The ActionGroup is used to populate the ActionBars of Common Navigator
	 * View Part, and the returned implementation will have an opportunity to
	 * fill the ActionBars of the view as soon as it is created. ({@link ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)}.
	 * </p>
	 * <p>
	 * The default implementation returns an action group which will add the
	 * following actions:
	 * <ul>
	 * <li>
	 * <p>
	 * Link with editor support. Allows the user to toggling linking the current
	 * selection with the active editors.
	 * </p>
	 * <li>
	 * <p>
	 * Collapse all. Collapses all expanded nodes.
	 * </p>
	 * <li>
	 * <p>
	 * Select Filters. Provides access to the "Select Filters" dialog that
	 * allows users to enable/disable filters and also the Content Extension
	 * activations.
	 * </p>
	 * </ul>
	 * 
	 * @return The Action Group to be associated with the Common Navigator View
	 *         Part.
	 */
	protected ActionGroup createCommonActionGroup() {
		return new CommonNavigatorActionGroup(this, commonViewer, getLinkHelperService());
	}

	/**
	 * @return The initial input for the viewer. Defaults to
	 *         getSite().getPage().getInput()
	 */
	protected IAdaptable getInitialInput() {
		return getSite().getPage().getInput();
	}

	/**
	 * <p>
	 * Updates the title text and title tool tip. Called whenever the input of
	 * the viewer changes.
	 * </p>
	 */
	protected void updateTitle() {

		if (commonViewer == null) {
			return;
		}

		Object input = commonViewer.getInput();
		String viewName = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$ 
		// IWorkingSet workingSet = workingSetFilter.getWorkingSet();

		if (input == null) {
			setPartName(viewName);
			setTitleToolTip(""); //$NON-NLS-1$ 
		} else {
			String inputToolTip = getFrameToolTipText(input);

			setPartName(viewName);
			setTitleToolTip(inputToolTip);
		}
	}

	/**
	 * <p>
	 * Returns the tool tip text for the given element. Used as the tool tip
	 * text for the current frame, and for the view title tooltip.
	 * </p>
	 */
	protected String getFrameToolTipText(Object anElement) {
		if (commonViewer != null) {
			return ((ILabelProvider) commonViewer.getLabelProvider())
					.getText(anElement);
		}
		return ""; //$NON-NLS-1$
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablesSource#getSaveables()
	 */
	public Saveable[] getSaveables() {
		return getNavigatorContentService().getSaveablesService().getSaveables();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablesSource#getActiveSaveables()
	 */
	public Saveable[] getActiveSaveables() {
		return getNavigatorContentService().getSaveablesService().getActiveSaveables();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		// Ignore. This method is not called because CommonNavigator implements
		// ISaveablesSource. All saves will go through the ISaveablesSource /
		// Saveable protocol.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#doSaveAs()
	 */
	public void doSaveAs() {
		// ignore
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#isDirty()
	 */
	public boolean isDirty() {
		Saveable[] saveables = getSaveables();
		for (int i = 0; i < saveables.length; i++) {
			if(saveables[i].isDirty()) {
				return true;
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
	 */
	public boolean isSaveAsAllowed() {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
	 */
	public boolean isSaveOnCloseNeeded() {
		return isDirty();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext)
	 */
	public boolean show(ShowInContext context) {
		IStructuredSelection selection = getSelection(context);
		if (selection != null && !selection.isEmpty()) {
			selectReveal(selection);
			return true;
		} 
		return false;
	}

	private IStructuredSelection getSelection(ShowInContext context) {
		if (context == null)
			return StructuredSelection.EMPTY;
		ISelection selection = context.getSelection();
		if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection)
			return (IStructuredSelection)selection;
		Object input = context.getInput();
		if (input instanceof IEditorInput) {
			LinkHelperService lhs = getLinkHelperService();
			return lhs.getSelectionFor((IEditorInput) input);
		}
		if (input != null) {
			return new StructuredSelection(input);
		}
		return StructuredSelection.EMPTY;
	}

	private synchronized LinkHelperService getLinkHelperService() {
		if (linkService == null)
			linkService = new LinkHelperService((NavigatorContentService)getCommonViewer().getNavigatorContentService());
		return linkService;
	}
 
}
