/*******************************************************************************
 * 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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jst.pagedesigner.common.guiutils.SWTUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.INestableKeyBindingService;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageEditorSite;

/**
 * This class emulates the MultiPageEditorPart. But instead of using multipage,
 * it use SashForm to separate the editors.
 * 
 * @author mengbo
 */
public abstract class SashEditorPart extends EditorPart {
	private int _orientation = SWT.VERTICAL;

	private SashForm _sashForm;

	/**
	 * List of nested editors. Element type: IEditorPart. Need to hang onto them
	 * here, in addition to using get/setData on the items, because dispose()
	 * needs to access them, but widgetry has already been disposed at that
	 * point.
	 */
	private ArrayList _nestedEditors = new ArrayList(3);

	private Map _editorToComposite = new HashMap();

	private IEditorPart _activeEditor = null;

	/**
	 * Creates and adds a new page containing the given editor to this
	 * multi-page editor. The page is added at the given index. This also hooks
	 * a property change listener on the nested editor.
	 * 
	 * @param index
	 *            the index at which to add the page (0-based)
	 * @param editor
	 *            the nested editor
	 * @param input
	 *            the input for the nested editor
	 * @exception PartInitException
	 *                if a new page could not be created
	 * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
	 *      property change events from the nested editor
	 */
	public void addPage(final IEditorPart editor, IEditorInput input)
			throws PartInitException {
		IEditorSite site = createSite(editor);
		// call init first so that if an exception is thrown, we have created no
		// new widgets
		editor.init(site, input);
		final Composite parent1 = new Composite(getContainer(), SWT.NONE);
		FillLayout fillLayout = new FillLayout();
		fillLayout.marginWidth = fillLayout.marginHeight = 1;
		parent1.setLayout(fillLayout);

		parent1.addListener(SWT.Activate, new Listener() {
			public void handleEvent(Event event) {
				if (event.type == SWT.Activate) {
					activeEditorChanged(editor);
					parent1.setBackground(ColorConstants.green);
				}
			}
		});
		parent1.addListener(SWT.Deactivate, new Listener() {
			public void handleEvent(Event event) {
				parent1.setBackground(ColorConstants.titleInactiveBackground);
			}
		});
		SWTUtils.workaroundResize(parent1);
		editor.createPartControl(parent1);
		editor.addPropertyListener(new IPropertyListener() {
			public void propertyChanged(Object source, int propertyId) {
				SashEditorPart.this.handlePropertyChange(propertyId);
			}
		});

		_nestedEditors.add(editor);
		_editorToComposite.put(editor, parent1);

		connectPage(editor);
	}

	protected void connectPage(IEditorPart editor) {
		ISelectionProvider editSelectionProvider = editor.getSite()
				.getSelectionProvider();
		if (editSelectionProvider instanceof IPostSelectionProvider) {
			((IPostSelectionProvider) editSelectionProvider)
					.addPostSelectionChangedListener(new ISelectionChangedListener() {
						public void selectionChanged(SelectionChangedEvent event) {
							((SashEditorSelectionProvider) getSite()
									.getSelectionProvider())
									.firePostSelectionChanged(event);
						}
					});
		} else {
			editSelectionProvider
					.addSelectionChangedListener(new ISelectionChangedListener() {

						public void selectionChanged(SelectionChangedEvent event) {
							((SashEditorSelectionProvider) getSite()
									.getSelectionProvider())
									.fireSelectionChanged(event);
						}
					});
		}
	}

	/**
	 * Creates an empty container. Creates a CTabFolder with no style bits set,
	 * and hooks a selection listener which calls <code>pageChange()</code>
	 * whenever the selected tab changes.
	 * 
	 * @param parent
	 *            The composite in which the container tab folder should be
	 *            created; must not be <code>null</code>.
	 * @return a new container
	 */
	private SashForm createContainer(Composite parent) {
		// use SWT.FLAT style so that an extra 1 pixel border is not reserved
		// inside the folder
		SashForm newContainer = new SashForm(parent, SWT.NONE);
		SWTUtils.workaroundResize(newContainer);
		newContainer.setOrientation(_orientation);
		return newContainer;
	}

	abstract protected void createPages() throws PartInitException;

	/**
	 * The <code>MultiPageEditor</code> implementation of this
	 * <code>IWorkbenchPart</code> method creates the control for the
	 * multi-page editor by calling <code>createContainer</code>, then
	 * <code>createPages</code>. Subclasses should implement
	 * <code>createPages</code> rather than overriding this method.
	 * 
	 * @param parent
	 *            The parent in which the editor should be created; must not be
	 *            <code>null</code>.
	 */
	public final void createPartControl(Composite parent) {
		this._sashForm = createContainer(parent);

		try {
			createPages();
		} catch (PartInitException ex) {
			ex.printStackTrace();
		}
		// set the active page (page 0 by default), unless it has already been
		// done
		if (getActiveEditor() == null) {
			if (!_nestedEditors.isEmpty()) {
				setActiveEditor((IEditorPart) _nestedEditors.get(0));
			}
		}
	}

	/**
	 * Creates the site for the given nested editor. The
	 * <code>MultiPageEditorPart</code> implementation of this method creates
	 * an instance of <code>MultiPageEditorSite</code>. Subclasses may
	 * reimplement to create more specialized sites.
	 * 
	 * @param editor
	 *            the nested editor
	 * @return the editor site
	 */
	protected IEditorSite createSite(IEditorPart editor) {
		return new SashEditorSite(this, editor);
	}

	/**
	 * The <code>MultiPageEditorPart</code> implementation of this
	 * <code>IWorkbenchPart</code> method disposes all nested editors.
	 * Subclasses may extend.
	 */
	public void dispose() {
		_activeEditor = null;
		for (int i = 0; i < _nestedEditors.size(); ++i) {
			IEditorPart editor = (IEditorPart) _nestedEditors.get(i);
			disposePart(editor);
		}
		_nestedEditors.clear();
		_editorToComposite.clear();
	}

	/**
	 * Returns the active nested editor if there is one.
	 * <p>
	 * Subclasses should not override this method
	 * </p>
	 * 
	 * @return the active nested editor, or <code>null</code> if none
	 */
	public IEditorPart getActiveEditor() {
		return _activeEditor;
	}

	/**
	 * Returns the composite control containing this multi-page editor's pages.
	 * This should be used as the parent when creating controls for the
	 * individual pages. That is, when calling <code>addPage(Control)</code>,
	 * the passed control should be a child of this container.
	 * <p>
	 * Warning: Clients should not assume that the container is any particular
	 * subclass of Composite. The actual class used may change in order to
	 * improve the look and feel of multi-page editors. Any code making
	 * assumptions on the particular subclass would thus be broken.
	 * </p>
	 * <p>
	 * Subclasses should not override this method
	 * </p>
	 * 
	 * @return the composite, or <code>null</code> if
	 *         <code>createPartControl</code> has not been called yet
	 */
	protected Composite getContainer() {
		return _sashForm;
	}

	/**
	 * Returns the editor for the given page index. The page index must be
	 * valid.
	 * 
	 * @param pageIndex
	 *            the index of the page
	 * @return the editor for the specified page, or <code>null</code> if the
	 *         specified page was not created with
	 *         <code>addPage(IEditorPart,IEditorInput)</code>
	 */
	protected IEditorPart getEditor(int pageIndex) {
		return (IEditorPart) _nestedEditors.get(pageIndex);
	}

	/**
	 * Handles a property change notification from a nested editor. The default
	 * implementation simply forwards the change to listeners on this multi-page
	 * editor by calling <code>firePropertyChange</code> with the same
	 * property id. For example, if the dirty state of a nested editor changes
	 * (property id <code>IEditorPart.PROP_DIRTY</code>), this method handles
	 * it by firing a property change event for
	 * <code>IEditorPart.PROP_DIRTY</code> to property listeners on this
	 * multi-page editor.
	 * <p>
	 * Subclasses may extend or reimplement this method.
	 * </p>
	 * 
	 * @param propertyId
	 *            the id of the property that changed
	 */
	protected void handlePropertyChange(int propertyId) {
		firePropertyChange(propertyId);
	}

	/**
	 * The <code>MultiPageEditorPart</code> implementation of this
	 * <code>IEditorPart</code> method sets its site to the given site, its
	 * input to the given input, and the site's selection provider to a
	 * <code>MultiPageSelectionProvider</code>. Subclasses may extend this
	 * method.
	 * 
	 * @param site
	 *            The site for which this part is being created; must not be
	 *            <code>null</code>.
	 * @param input
	 *            The input on which this editor should be created; must not be
	 *            <code>null</code>.
	 * @throws PartInitException
	 *             If the initialization of the part fails -- currently never.
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		site.setSelectionProvider(new SashEditorSelectionProvider(this));
	}

	/**
	 * The <code>MultiPageEditorPart</code> implementation of this
	 * <code>IEditorPart</code> method returns whether the contents of any of
	 * this multi-page editor's nested editors have changed since the last save.
	 * Pages created with <code>addPage(Control)</code> are ignored.
	 * <p>
	 * Subclasses may extend or reimplement this method.
	 * </p>
	 * 
	 * @return <code>true</code> if any of the nested editors are dirty;
	 *         <code>false</code> otherwise.
	 */
	public boolean isDirty() {
		// use nestedEditors to avoid SWT requests; see bug 12996
		for (Iterator i = _nestedEditors.iterator(); i.hasNext();) {
			IEditorPart editor = (IEditorPart) i.next();
			if (editor.isDirty()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Notifies this multi-page editor that the page with the given id has been
	 * activated. This method is called when the user selects a different tab.
	 * <p>
	 * The <code>MultiPageEditorPart</code> implementation of this method sets
	 * focus to the new page, and notifies the action bar contributor (if there
	 * is one). This checks whether the action bar contributor is an instance of
	 * <code>MultiPageEditorActionBarContributor</code>, and, if so, calls
	 * <code>setActivePage</code> with the active nested editor. This also
	 * fires a selection change event if required.
	 * </p>
	 * <p>
	 * Subclasses may extend this method.
	 * </p>
	 * 
	 * @param newPageIndex
	 *            the index of the activated page
	 */
	protected void activeEditorChanged(IEditorPart activeEditor) {
		setActiveEditor(activeEditor);
		setFocus();

		IEditorSite site = getEditorSite();
		while (site != null) {
			IEditorActionBarContributor contributor = site
					.getActionBarContributor();
			if (contributor != null
					&& contributor instanceof MultiPageEditorActionBarContributor) {
				((MultiPageEditorActionBarContributor) contributor)
						.setActivePage(activeEditor);
			}
			if (site instanceof MultiPageEditorSite) {
				site = (IEditorSite) ((MultiPageEditorSite) site)
						.getMultiPageEditor().getSite();
			} else if (site instanceof SashEditorSite) {
				site = (IEditorSite) ((SashEditorSite) site).getSashEditor()
						.getSite();
			} else {
				site = null;
			}
		}

		if (activeEditor != null) {
			// Workaround for 1GAUS7C: ITPUI:ALL - Editor not activated when
			// restored from previous session
			// do not need second if once fixed
			ISelectionProvider selectionProvider = activeEditor.getSite()
					.getSelectionProvider();
			if (selectionProvider != null) {
				SelectionChangedEvent event = new SelectionChangedEvent(
						selectionProvider, selectionProvider.getSelection());
				((SashEditorSelectionProvider) getSite().getSelectionProvider())
						.fireSelectionChanged(event);
			}
		}
	}

	/**
	 * Disposes the given part and its site.
	 * 
	 * @param part
	 *            The part to dispose; must not be <code>null</code>.
	 */
	private void disposePart(final IWorkbenchPart part) {
		Platform.run(new SafeRunnable() {
			public void run() {
				if (part.getSite() instanceof SashEditorSite) {
					SashEditorSite partSite = (SashEditorSite) part.getSite();
					partSite.dispose();
				}
				part.dispose();
			}

			public void handleException(Throwable e) {
				// Exception has already being logged by Core. Do nothing.
			}
		});
	}

	/**
	 * Sets the currently active page.
	 * 
	 * @param pageIndex
	 *            the index of the page to be activated; the index must be valid
	 */
	protected void setActiveEditor(IEditorPart part) {
		_activeEditor = part;
	}

	/**
	 * The <code>MultiPageEditor</code> implementation of this
	 * <code>IWorkbenchPart</code> method sets focus on the active nested
	 * editor, if there is one.
	 * <p>
	 * Subclasses may extend or reimplement.
	 * </p>
	 */
	public void setFocus() {
		setFocus(getActiveEditor());
	}

	/**
	 * Sets focus to the control for the given page. If the page has an editor,
	 * this calls its <code>setFocus()</code> method. Otherwise, this calls
	 * <code>setFocus</code> on the control for the page.
	 * 
	 * @param pageIndex
	 *            the index of the page
	 */
	private void setFocus(IEditorPart editor) {
		final IKeyBindingService service = getSite().getKeyBindingService();

		if (editor == null) {
			// There is no selected page, so deactivate the active service.
			if (service instanceof INestableKeyBindingService) {
				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
				nestableService.activateKeyBindingService(null);
			} else {
				WorkbenchPlugin
						.log("MultiPageEditorPart.setFocus()   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;
		} else {
			editor.setFocus();
			// There is no selected page, so deactivate the active service.
			if (service instanceof INestableKeyBindingService) {
				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
				if (editor != null) {
					nestableService.activateKeyBindingService(editor
							.getEditorSite());
				} else {
					nestableService.activateKeyBindingService(null);
				}
			} else {
				WorkbenchPlugin
						.log("MultiPageEditorPart.setFocus()   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$
			}
		}
	}

	public void doSave(IProgressMonitor monitor) {
		if (_activeEditor != null) {
			_activeEditor.doSave(monitor);
		}
	}

	public void doSaveAs() {
		if (_activeEditor != null) {
			_activeEditor.doSaveAs();
		}

	}

	public boolean isSaveAsAllowed() {
		if (_activeEditor != null)
			return _activeEditor.isSaveAsAllowed();
		else
			return false;
	}

	public void setOrientation(int orientation) {
		this._orientation = orientation;
		if (_sashForm != null && !_sashForm.isDisposed()) {
			_sashForm.setMaximizedControl(null);
			_sashForm.setOrientation(_orientation);
		}
	}

	public void setMaximizedEditor(IEditorPart part) {
		if (part != null) {
			Composite c = (Composite) _editorToComposite.get(part);
			if (c != null && _sashForm != null && !_sashForm.isDisposed()) {
				_sashForm.setMaximizedControl(c);
				part.setFocus();
			}
		} else {
			if (_sashForm != null && !_sashForm.isDisposed()) {
				_sashForm.setMaximizedControl(null);
			}
		}
	}
}
