/*******************************************************************************
 * 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.SafeRunner;
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.jsf.common.ui.internal.guiutils.SWTUtils;
import org.eclipse.jst.pagedesigner.PDPlugin;
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.part.EditorPart;
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
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 editor
	 *            the nested editor
	 * @param input
	 *            the input for the nested editor
	 * @exception PartInitException
	 *                if a new page could not be created
	 * @see org.eclipse.ui.part.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);
	}

	/**
	 * @param 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;
	}

	/**
	 * @throws PartInitException
	 */
	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 activeEditor 
	 * 
	 */
	protected void activeEditorChanged(IEditorPart activeEditor) {
		setActiveEditor(activeEditor);
		setFocus();

		IEditorSite site = getEditorSite();
		while (site != null) {
			IEditorActionBarContributor contributor = site
					.getActionBarContributor();
			if (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) {
        SafeRunner.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 part
	 * 
	 */
	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
				PDPlugin
				    .getLogger(getClass()).error("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;
		}
        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 {
            PDPlugin
                .getLogger(getClass()).error("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();
        }
		return false;
	}

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

	/**
	 * @param part
	 */
	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);
			}
		}
	}
}
