/*******************************************************************************
 * 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 java.util.ArrayList;

import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.util.Assert;
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.
	 */
	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;
	}

}
