/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.ui.common.sash;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.INestableKeyBindingService;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
//import org.eclipse.ui.internal.PopupMenuExtender;

/**
 * @author mengbo
 */
public class SashEditorSite implements IEditorSite {

	/**
	 * The nested editor.
	 */
	private IEditorPart _editor;

	/**
	 * The multi-page editor.
	 */
	private SashEditorPart _sashEditor;

	/**
	 * The selection provider; <code>null</code> if none.
	 * 
	 * @see SashEditorSite#setSelectionProvider(ISelectionProvider)
	 */
	private ISelectionProvider _selectionProvider = null;

	/**
	 * The selection change listener, initialized lazily; <code>null</code> if
	 * not yet created.
	 */
	private ISelectionChangedListener _selectionChangedListener = null;

	/**
	 * The cached copy of the key binding service specific to this sash editor
	 * site. This value is <code>null</code> if it is not yet initialized.
	 */
	private IKeyBindingService _service = null;

	/**
	 * The list of popup menu extenders; <code>null</code> if none registered.
	 */
	// TODO: dead? private ArrayList _menuExtenders;

	/**
	 * Creates a site for the given editor nested within the given multi-page
	 * editor.
	 * 
	 * @param _sashEditor
	 *            the multi-page editor
	 * @param _editor
	 *            the nested editor
	 */
	public SashEditorSite(SashEditorPart sashEditor, IEditorPart editor) {
		Assert.isNotNull(sashEditor);
		Assert.isNotNull(editor);
		this._sashEditor = sashEditor;
		this._editor = editor;
	}

	/**
	 * Dispose the contributions.
	 */
	public void dispose() {
//		if (_menuExtenders != null) {
//			for (int i = 0, size = _menuExtenders.size(); i < size; i++) {
//				((PopupMenuExtender) _menuExtenders.get(i)).dispose();
//			}
//			_menuExtenders = null;
//		}

		// Remove myself from the list of nested key binding services.
		if (_service != null) {
			IKeyBindingService parentService = getEditor().getSite()
					.getKeyBindingService();
			if (parentService instanceof INestableKeyBindingService) {
				INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
				nestableParent.removeKeyBindingService(this);
			}
			_service = null;
		}
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IEditorSite</code> method returns <code>null</code>, since
	 * nested editors do not have their own action bar contributor.
	 * 
	 * @return <code>null</code>
	 */
	public IEditorActionBarContributor getActionBarContributor() {
		return null;
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IEditorSite</code> method forwards to the multi-page editor to
	 * return the action bars.
	 * 
	 * @return The action bars from the parent multi-page editor.
	 */
	public IActionBars getActionBars() {
		return _sashEditor.getEditorSite().getActionBars();
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor to return the decorator manager.
	 * 
	 * @return The decorator from the workbench window.
	 * @deprecated use IWorkbench.getDecoratorManager()
	 */
	public ILabelDecorator getDecoratorManager() {
		return getWorkbenchWindow().getWorkbench().getDecoratorManager()
				.getLabelDecorator();
	}

	/**
	 * Returns the nested editor.
	 * 
	 * @return the nested editor
	 */
	public IEditorPart getEditor() {
		return _editor;
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method returns an empty string since
	 * the nested editor is not created from the registry.
	 * 
	 * @return An empty string.
	 */
	public String getId() {
		return ""; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc) Method declared on IEditorSite.
	 */
	public IKeyBindingService getKeyBindingService() {
		if (_service == null) {
			_service = getSashEditor().getEditorSite().getKeyBindingService();
			if (_service instanceof INestableKeyBindingService) {
				INestableKeyBindingService nestableService = (INestableKeyBindingService) _service;
				_service = nestableService.getKeyBindingService(this);

			} else {
				/*
				 * This is an internal reference, and should not be copied by
				 * client code. If you are thinking of copying this, DON'T DO
				 * IT.
				 */
				PDPlugin
						.getLogger(SashEditorSite.class)
						.info(
								"MultiPageEditorSite.getKeyBindingService()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + _service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		return _service;
	}

	/**
	 * Returns the sash editor.
	 * 
	 * @return the sash editor
	 */
	public SashEditorPart getSashEditor() {
		return _sashEditor;
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor to return the workbench page.
	 * 
	 * @return The workbench page in which this editor site resides.
	 */
	public IWorkbenchPage getPage() {
		return getSashEditor().getSite().getPage();
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method returns an empty string since
	 * the nested editor is not created from the registry.
	 * 
	 * @return An empty string.
	 */
	public String getPluginId() {
		return ""; //$NON-NLS-1$
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method returns an empty string since
	 * the nested editor is not created from the registry.
	 * 
	 * @return An empty string.
	 */
	public String getRegisteredName() {
		return ""; //$NON-NLS-1$
	}

	/**
	 * Returns the selection changed listener which listens to the nested
	 * editor's selection changes, and calls <code>handleSelectionChanged</code>.
	 * 
	 * @return the selection changed listener
	 */
	private ISelectionChangedListener getSelectionChangedListener() {
		if (_selectionChangedListener == null) {
			_selectionChangedListener = new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					SashEditorSite.this.handleSelectionChanged(event);
				}
			};
		}
		return _selectionChangedListener;
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method returns the selection provider
	 * set by <code>setSelectionProvider</code>.
	 * 
	 * @return The current selection provider.
	 */
	public ISelectionProvider getSelectionProvider() {
		return _selectionProvider;
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor to return the shell.
	 * 
	 * @return The shell in which this editor site resides.
	 */
	public Shell getShell() {
		return getSashEditor().getSite().getShell();
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor to return the workbench window.
	 * 
	 * @return The workbench window in which this editor site resides.
	 */
	public IWorkbenchWindow getWorkbenchWindow() {
		return getSashEditor().getSite().getWorkbenchWindow();
	}

	/**
	 * Handles a selection changed event from the nested editor. The default
	 * implementation gets the selection provider from the multi-page editor's
	 * site, and calls <code>fireSelectionChanged</code> on it (only if it is
	 * an instance of <code>SashSelectionProvider</code>), passing a new
	 * event object.
	 * <p>
	 * Subclasses may extend or reimplement this method.
	 * </p>
	 * 
	 * @param event
	 *            the event
	 */
	public void handleSelectionChanged(SelectionChangedEvent event) {
		// we'll only make the parent editor site fire the selection change
		// event
		// when we (the sasheditorsite) is the active editor in the parent site.
		if (getSashEditor().getActiveEditor() == this.getPart()) {
			ISelectionProvider parentProvider = getSashEditor().getSite()
					.getSelectionProvider();
			if (parentProvider instanceof SashEditorSelectionProvider) {
				SelectionChangedEvent newEvent = new SelectionChangedEvent(
						parentProvider, event.getSelection());
				((SashEditorSelectionProvider) parentProvider)
						.fireSelectionChanged(newEvent);
			}
		}
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor for registration.
	 * 
	 * @param menuID
	 *            The identifier for the menu.
	 * @param menuMgr
	 *            The menu manager
	 * @param selProvider
	 *            The selection provider.
	 */
	public void registerContextMenu(String menuID, MenuManager menuMgr,
			ISelectionProvider selProvider) {
//		if (_menuExtenders == null) {
//			_menuExtenders = new ArrayList(1);
//		}
		// cancel the registration of PopupMenuExtender since the
		// PopupMenuExtender's behavior
		// is different between eclipse 3.0 and eclipse 3.1,and we always have
		// one context
		// menu listener,no need add PopupMenuExtender as the second
		// listener(workaroud for bug 408295-1)
		// _menuExtenders.add(new PopupMenuExtender(menuID, menuMgr,
		// selProvider,
		// _editor));
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page
	 * editor for registration.
	 * 
	 * @param menuManager
	 *            The menu manager
	 * @param selProvider
	 *            The selection provider.
	 */
	public void registerContextMenu(MenuManager menuManager,
			ISelectionProvider selProvider) {
		getSashEditor().getSite().registerContextMenu(menuManager, selProvider);
	}

	/**
	 * The <code>SashEditorSite</code> implementation of this
	 * <code>IWorkbenchPartSite</code> method remembers the selection
	 * provider, and also hooks a listener on it, which calls
	 * <code>handleSelectionChanged</code> when a selection changed event
	 * occurs.
	 * 
	 * @param provider
	 *            The selection provider.
	 * @see SashEditorSite#handleSelectionChanged(SelectionChangedEvent)
	 */
	public void setSelectionProvider(ISelectionProvider provider) {
		ISelectionProvider oldSelectionProvider = _selectionProvider;
		_selectionProvider = provider;
		if (oldSelectionProvider != null) {
			oldSelectionProvider
					.removeSelectionChangedListener(getSelectionChangedListener());
		}
		if (_selectionProvider != null) {
			_selectionProvider
					.addSelectionChangedListener(getSelectionChangedListener());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPartSite#progressEnd()
	 */
	public void progressEnd(Job job) {
		// Do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPartSite#progressStart()
	 */
	public void progressStart(Job job) {
		// Do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
	 */
	public IWorkbenchPart getPart() {
		return _editor;
	}

	public void registerContextMenu(MenuManager menuManager,
			ISelectionProvider selectionProvider, boolean includeEditorInput) {
		// TODO Auto-generated method stub

	}

	public void registerContextMenu(String menuId, MenuManager menuManager,
			ISelectionProvider selectionProvider, boolean includeEditorInput) {
		// TODO Auto-generated method stub

	}

	public Object getService(Class api) {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean hasService(Class api) {
		// TODO Auto-generated method stub
		return false;
	}

}
