/*******************************************************************************
 * 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.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 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);
	}

	/**
	 * @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 != 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) {
        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);
			}
		}
	}
}
