/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.forms.editor;

import java.util.Vector;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.part.MultiPageSelectionProvider;

/**
 * This class forms a base of multi-page form editors that typically use one or
 * more pages with forms and one page for raw source of the editor input.
 * <p>
 * Pages are added 'lazily' i.e. adding a page reserves a tab for it but does
 * not cause the page control to be created. Page control is created when an
 * attempt is made to select the page in question. This allows editors with
 * several tabs and complex pages to open quickly.
 * <p>
 * Subclasses should extend this class and implement <code>addPages</code>
 * method. One of the two <code>addPage</code> methods should be called to
 * contribute pages to the editor. One adds complete (standalone) editors as
 * nested tabs. These editors will be created right away and will be hooked so
 * that key bindings, selection service etc. is compatible with the one for the
 * standalone case. The other method adds classes that implement
 * <code>IFormPage</code> interface. These pages will be created lazily and
 * they will share the common key binding and selection service. Since 3.1,
 * FormEditor is a page change provider. It allows listeners to attach to it and
 * get notified when pages are changed. This new API in JFace allows dynamic
 * help to update on page changes.
 * 
 * @since 3.0
 */
public abstract class FormEditor extends MultiPageEditorPart implements
		IPageChangeProvider {

	/**
	 * An array of pages currently in the editor. Page objects are not limited
	 * to those that implement <code>IFormPage</code>, hence the size of this
	 * array matches the number of pages as viewed by the user.
	 * <p>
	 * Subclasses can access this field but should not modify it.
	 */
	protected Vector pages = new Vector();

	private FormToolkit toolkit;

	private int currentPage = -1;

	private ListenerList pageListeners = new ListenerList();

	private static class FormEditorSelectionProvider extends
			MultiPageSelectionProvider {
		private ISelection globalSelection;

		/**
		 * @param formEditor the editor
		 */
		public FormEditorSelectionProvider(FormEditor formEditor) {
			super(formEditor);
		}

		public ISelection getSelection() {
			IEditorPart activeEditor = ((FormEditor) getMultiPageEditor())
					.getActiveEditor();
			if (activeEditor != null) {
				ISelectionProvider selectionProvider = activeEditor.getSite()
						.getSelectionProvider();
				if (selectionProvider != null)
					return selectionProvider.getSelection();
			}
			if (globalSelection != null) {
			    return globalSelection;
			}
			return StructuredSelection.EMPTY;
		}

		/*
		 * (non-Javadoc) Method declared on <code> ISelectionProvider </code> .
		 */
		public void setSelection(ISelection selection) {
			IEditorPart activeEditor = ((FormEditor) getMultiPageEditor())
					.getActiveEditor();
			if (activeEditor != null) {
				ISelectionProvider selectionProvider = activeEditor.getSite()
						.getSelectionProvider();
				if (selectionProvider != null)
					selectionProvider.setSelection(selection);
			} else {
				this.globalSelection = selection;
				fireSelectionChanged(new SelectionChangedEvent(this,
						globalSelection));
			}
		}
	}

	/**
	 * The constructor.
	 */
	public FormEditor() {
	}

	/**
	 * Overrides super to plug in a different selection provider.
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		site.setSelectionProvider(new FormEditorSelectionProvider(this));
	}

	/**
	 * Creates the common toolkit for this editor and adds pages to the editor.
	 * 
	 * @see #addPages
	 */
	protected void createPages() {
		addPages();
	}

	/*
	 * @see org.eclipse.ui.part.MultiPageEditorPart#createPageContainer(org.eclipse.swt.widgets.Composite)
	 */
	protected Composite createPageContainer(Composite parent) {
		parent = super.createPageContainer(parent);
		toolkit = createToolkit(parent.getDisplay());
		return parent;
	}

	/**
	 * Creates the form toolkit. The method can be implemented to substitute a
	 * subclass of the toolkit that should be used for this editor. A typical
	 * use of this method would be to create the form toolkit using one shared
	 * <code>FormColors</code> object to share resources across the multiple
	 * editor instances.
	 * 
	 * @param display
	 *            the display to use when creating the toolkit
	 * @return the newly created toolkit instance
	 */
	protected FormToolkit createToolkit(Display display) {
		return new FormToolkit(display);
	}

	/**
	 * Subclass should implement this method to add pages to the editor using
	 * 'addPage(IFormPage)' method.
	 */
	protected abstract void addPages();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IPageChangeProvider#addPageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
	 */
	public void addPageChangedListener(IPageChangedListener listener) {
		pageListeners.add(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IPageChangeProvider#removePageChangedListener(org.eclipse.jface.dialogs.IPageChangedListener)
	 */
	public void removePageChangedListener(IPageChangedListener listener) {
		pageListeners.remove(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
	 */
	public Object getSelectedPage() {
		return getActivePageInstance();
	}

	/**
	 * Adds the form page to this editor. Form page will be loaded lazily. Its
	 * part control will not be created until it is activated for the first
	 * time.
	 * 
	 * @param page
	 *            the form page to add
	 */
	public int addPage(IFormPage page) throws PartInitException {
		int i = super.addPage(page.getPartControl());
		configurePage(i, page);
		return i;
	}

	/**
	 * Adds the form page to this editor at the specified index (0-based). Form
	 * page will be loaded lazily. Its part control will not be created until it
	 * is activated for the first time.
	 * 
	 * @param index
	 *            the position to add the page at (0-based)
	 * @param page
	 *            the form page to add
	 * @since 3.1
	 */
	public void addPage(int index, IFormPage page) throws PartInitException {
		super.addPage(index, page.getPartControl());
		configurePage(index, page);
	}

	/**
	 * Adds a simple SWT control as a page. Overrides superclass implementation
	 * to keep track of pages.
	 * 
	 * @param control
	 *            the page control to add
	 * @return the 0-based index of the newly added page
	 */
	public int addPage(Control control) {
		int i = super.addPage(control);
		try {
			registerPage(-1, control);
		} catch (PartInitException e) {
			// cannot happen for controls
		}
		return i;
	}

	/**
	 * Adds a simple SWT control as a page. Overrides superclass implementation
	 * to keep track of pages.
	 * 
	 * @param control
	 *            the page control to add
	 * @param index
	 *            the index at which to add the page (0-based)
	 * @since 3.1
	 */
	public void addPage(int index, Control control) {
		super.addPage(index, control);
		try {
			registerPage(index, control);
		} catch (PartInitException e) {
			// cannot happen for controls
		}
	}

	/**
	 * Tests whether the editor is dirty by checking all the pages that
	 * implement <code>IFormPage</code>. If none of them is dirty, the method
	 * delegates further processing to <code>super.isDirty()</code>.
	 * 
	 * @return <code>true</code> if any of the pages in the editor are dirty,
	 *         <code>false</code> otherwise.
	 * @since 3.1
	 */

	public boolean isDirty() {
		if (pages != null) {
			for (int i = 0; i < pages.size(); i++) {
				Object page = pages.get(i);
				if (page instanceof IFormPage) {
					IFormPage fpage = (IFormPage) page;
					if (fpage.isDirty())
						return true;
				}
			}
		}
		return super.isDirty();
	}
	
	/**
	 * Commits all dirty pages in the editor. This method should
	 * be called as a first step of a 'save' operation.
	 * @param onSave <code>true</code> if commit is performed as part
	 * of the 'save' operation, <code>false</code> otherwise.
	 * @since 3.3
	 */

	protected void commitPages(boolean onSave) {
		if (pages != null) {
			for (int i = 0; i < pages.size(); i++) {
				Object page = pages.get(i);
				if (page instanceof IFormPage) {
					IFormPage fpage = (IFormPage)page;
					IManagedForm mform = fpage.getManagedForm();
					if (mform != null && mform.isDirty())
						mform.commit(onSave);
				}
			}
		}	
	}

	/**
	 * Adds a complete editor part to the multi-page editor.
	 * 
	 * @see MultiPageEditorPart#addPage(IEditorPart, IEditorInput)
	 */
	public int addPage(IEditorPart editor, IEditorInput input)
			throws PartInitException {
		int index = super.addPage(editor, input);
		if (editor instanceof IFormPage)
			configurePage(index, (IFormPage) editor);
		else
			registerPage(-1, editor);
		return index;
	}

	/**
	 * Adds a complete editor part to the multi-page editor at the specified
	 * position.
	 * 
	 * @see MultiPageEditorPart#addPage(int, IEditorPart, IEditorInput)
	 * @since 3.1
	 */
	public void addPage(int index, IEditorPart editor, IEditorInput input)
			throws PartInitException {
		super.addPage(index, editor, input);
		if (editor instanceof IFormPage)
			configurePage(index, (IFormPage) editor);
		else
			registerPage(index, editor);
	}

	/**
	 * Configures the form page.
	 * 
	 * @param index
	 *            the page index
	 * @param page
	 *            the page to configure
	 * @throws PartInitException
	 *             if there are problems in configuring the page
	 */
	protected void configurePage(int index, IFormPage page)
			throws PartInitException {
		setPageText(index, page.getTitle());
		// setPageImage(index, page.getTitleImage());
		page.setIndex(index);
		registerPage(index, page);
	}

	/**
	 * Overrides the superclass to remove the page from the page table.
	 * 
	 * @param pageIndex
	 *            the 0-based index of the page in the editor
	 */
	public void removePage(int pageIndex) {
		if (pageIndex >= 0 && pageIndex < pages.size()) {
			Object page = pages.get(pageIndex);
			pages.remove(page);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				if (!fpage.isEditor())
					fpage.dispose();
				updatePageIndices();
			}
		}
		super.removePage(pageIndex);
	}

	// fix the page indices after the removal
	private void updatePageIndices() {
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				fpage.setIndex(i);
			}
		}
	}

	/**
	 * Called to indicate that the editor has been made dirty or the changes
	 * have been saved.
	 */
	public void editorDirtyStateChanged() {
		firePropertyChange(PROP_DIRTY);
	}

	/**
	 * Disposes the pages and the toolkit after disposing the editor itself.
	 * Subclasses must call 'super' when reimplementing the method.
	 */
	public void dispose() {
		super.dispose();
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				// don't dispose source pages because they will
				// be disposed as nested editors by the superclass
				if (!fpage.isEditor())
					fpage.dispose();
			}
		}
		pages = null;
		// toolkit may be null if editor has been instantiated
		// but never created - see defect #62190
		if (toolkit != null) {
			toolkit.dispose();
			toolkit = null;
		}
	}

	/**
	 * Returns the toolkit owned by this editor.
	 * 
	 * @return the toolkit object
	 */
	public FormToolkit getToolkit() {
		return toolkit;
	}

	/**
	 * Widens the visibility of the method in the superclass.
	 * 
	 * @return the active nested editor
	 */
	public IEditorPart getActiveEditor() {
		return super.getActiveEditor();
	}

	/**
	 * Returns the current page index. The value is identical to the value of
	 * 'getActivePage()' except during the page switch, when this method still
	 * has the old active page index.
	 * <p>
	 * Another important difference is during the editor closing. When the tab
	 * folder is disposed, 'getActivePage()' will return -1, while this method
	 * will still return the last active page.
	 * 
	 * @see #getActivePage
	 * @return the currently selected page or -1 if no page is currently
	 *         selected
	 */
	protected int getCurrentPage() {
		return currentPage;
	}

	/**
	 * @see MultiPageEditorPart#pageChange(int)
	 */
	protected void pageChange(int newPageIndex) {
		// fix for windows handles
		int oldPageIndex = getCurrentPage();
		if (oldPageIndex != -1 && pages.size() > oldPageIndex
				&& pages.get(oldPageIndex) instanceof IFormPage
				&& oldPageIndex != newPageIndex) {
			// Check the old page
			IFormPage oldFormPage = (IFormPage) pages.get(oldPageIndex);
			if (oldFormPage.canLeaveThePage() == false) {
				setActivePage(oldPageIndex);
				return;
			}
		}
		// Now is the absolute last moment to create the page control.
		Object page = pages.get(newPageIndex);
		if (page instanceof IFormPage) {
			IFormPage fpage = (IFormPage) page;
			if (fpage.getPartControl() == null) {
				fpage.createPartControl(getContainer());
				setControl(newPageIndex, fpage.getPartControl());
				fpage.getPartControl().setMenu(getContainer().getMenu());
			}
		}
		if (oldPageIndex != -1 && pages.size() > oldPageIndex
				&& pages.get(oldPageIndex) instanceof IFormPage) {
			// Commit old page before activating the new one
			IFormPage oldFormPage = (IFormPage) pages.get(oldPageIndex);
			IManagedForm mform = oldFormPage.getManagedForm();
			if (mform != null)
				mform.commit(false);
		}
		if (pages.size() > newPageIndex
				&& pages.get(newPageIndex) instanceof IFormPage)
			((IFormPage) pages.get(newPageIndex)).setActive(true);
		if (oldPageIndex != -1 && pages.size() > oldPageIndex
				&& newPageIndex != oldPageIndex && 
				pages.get(oldPageIndex) instanceof IFormPage)
			((IFormPage) pages.get(oldPageIndex)).setActive(false);
		// Call super - this will cause pages to switch
		super.pageChange(newPageIndex);
		this.currentPage = newPageIndex;
		IFormPage newPage = getActivePageInstance();
		if (newPage != null)
			firePageChanged(new PageChangedEvent(this, newPage));
	}

	/**
	 * Sets the active page using the unique page identifier.
	 * 
	 * @param pageId
	 *            the id of the page to switch to
	 * @return page that was set active or <samp>null </samp> if not found.
	 */
	public IFormPage setActivePage(String pageId) {
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				if (fpage.getId().equals(pageId)) {
					setActivePage(i);
					return fpage;
				}
			}
		}
		return null;
	}

	/**
	 * Finds the page instance that has the provided id.
	 * 
	 * @param pageId
	 *            the id of the page to find
	 * @return page with the matching id or <code>null</code> if not found.
	 */
	public IFormPage findPage(String pageId) {
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) pages.get(i);
				if (fpage.getId().equals(pageId))
					return fpage;
			}
		}
		return null;
	}

	/**
	 * Sets the active page using the unique page identifier and sets its input
	 * to the provided object.
	 * 
	 * @param pageId
	 *            the id of the page to switch to
	 * @param pageInput
	 *            the page input
	 * @return page that was set active or <samp>null </samp> if not found.
	 */
	public IFormPage setActivePage(String pageId, Object pageInput) {
		IFormPage page = setActivePage(pageId);
		if (page != null) {
			IManagedForm mform = page.getManagedForm();
			if (mform != null)
				mform.setInput(pageInput);
		}
		return page;
	}

	/**
	 * Iterates through the pages calling similar method until a page is found
	 * that contains the desired page input.
	 * 
	 * @param pageInput
	 *            the object to select and reveal
	 * @return the page that accepted the request or <code>null</code> if no
	 *         page has the desired object.
	 * @see #setActivePage(String, Object)
	 */
	public IFormPage selectReveal(Object pageInput) {
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				if (fpage.selectReveal(pageInput))
					return fpage;
			}
		}
		return null;
	}

	/**
	 * Returns active page instance if the currently selected page index is not
	 * -1, or <code>null</code> if it is.
	 * 
	 * @return active page instance if selected, or <code>null</code> if no
	 *         page is currently active.
	 */
	public IFormPage getActivePageInstance() {
		int index = getActivePage();
		if (index != -1) {
			Object page = pages.get(index);
			if (page instanceof IFormPage)
				return (IFormPage) page;
		}
		return null;
	}

	/**
	 * @see MultiPageEditorPart#setActivePage(int)
	 */
	protected void setActivePage(int pageIndex) {
		// fix for window handles problem
		// this should be called only when the editor is first opened
		if (pages.size() > pageIndex
				&& pages.get(pageIndex) instanceof IFormPage) {
			super.setActivePage(pageIndex);
			IFormPage activePage = (IFormPage) pages.get(pageIndex);
			activePage.setActive(true);
		} else
			super.setActivePage(pageIndex);
		updateActionBarContributor(pageIndex);
	}

	/**
	 * Notifies action bar contributor about page change.
	 * 
	 * @param pageIndex
	 *            the index of the new page
	 */
	protected void updateActionBarContributor(int pageIndex) {
		// this is to enable the undo/redo actions before a page change has
		// occurred
		IEditorActionBarContributor contributor = getEditorSite()
				.getActionBarContributor();
		if (contributor != null
				&& contributor instanceof MultiPageEditorActionBarContributor) {
			((MultiPageEditorActionBarContributor) contributor)
					.setActivePage(getEditor(pageIndex));
		}
	}

	/**
	 * Closes the editor programmatically.
	 * 
	 * @param save
	 *            if <code>true</code>, the content should be saved before
	 *            closing.
	 */
	public void close(final boolean save) {
		Display display = getSite().getShell().getDisplay();
		display.asyncExec(new Runnable() {
			public void run() {
				if (toolkit != null) {
					getSite().getPage().closeEditor(FormEditor.this, save);
				}
			}
		});
	}

	private void registerPage(int index, Object page) throws PartInitException {
		if (!pages.contains(page)) {
			if (index == -1)
				pages.add(page);
			else
				pages.add(index, page);
		}
		if (page instanceof IFormPage) {
			IFormPage fpage = (IFormPage) page;
			if (fpage.isEditor() == false)
				fpage.init(getEditorSite(), getEditorInput());
		}
	}

	private void firePageChanged(final PageChangedEvent event) {
		Object[] listeners = pageListeners.getListeners();
		for (int i = 0; i < listeners.length; ++i) {
			final IPageChangedListener l = (IPageChangedListener) listeners[i];
			SafeRunnable.run(new SafeRunnable() {
				public void run() {
					l.pageChanged(event);
				}
			});
		}
	}
}
