package org.eclipse.ui.part;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
 
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;

import org.eclipse.ui.*;

/**
 * A multi-page editor is an editor with multiple pages, each of which may
 * contain an editor or an arbitrary SWT control.
 * <p>
 * Subclasses must implement the following methods:
 * <ul>
 *   <li><code>createPages</code> - to create the required pages by calling one
 *     of the <code>addPage</code> methods</li>
 *   <li><code>IEditorPart.doSave</code> - to save contents of editor</li>
 *   <li><code>IEditorPart.doSaveAs</code> - to save contents of editor</li>
 *   <li><code>IEditorPart.isSaveAsAllowed</code> - to enable Save As</li>
 *   <li><code>IEditorPart.gotoMarker</code> - to scroll to a marker</li>
 * </ul>
 * </p>
 * <p>
 * Multi-page editors have a single action bar contributor, which manages 
 * contributions for all the pages. The contributor must be a subclass of
 * <code>AbstractMultiPageEditorActionBarContributor</code>.
 * Note that since any nested editors are created directly in code by callers of 
 * <code>addPage(IEditorPart,IEditorInput)</code>, nested editors do not have 
 * their own contributors.
 * </p>
 *
 * @see AbstractMultiPageEditorActionBarContributor
 */
public abstract class MultiPageEditorPart extends EditorPart {
	/**
	 * The container widget.
	 */
	private CTabFolder container;

	/**
	 * 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);
/**
 * Creates an empty multi-page editor with no pages.
 */
protected MultiPageEditorPart() {
	super();
}
/**
 * Creates and adds a new page containing the given control to this multi-page 
 * editor.  The control may be <code>null</code>, allowing it to be created
 * and set later using <code>setControl</code>.
 *
 * @param control the control, or <code>null</code>
 * @return the index of the new page
 *
 * @see #setControl
 */
public int addPage(Control control) {
	createItem(control);
	return getPageCount() - 1;
}
/**
 * Creates and adds a new page containing the given editor to this multi-page 
 * editor. This also hooks a property change listener on the nested editor.
 *
 * @param editor the nested editor
 * @param input the input for the nested editor
 * @return the index of the new page
 * @exception PartInitException if a new page could not be created
 *
 * @see #handlePropertyChange the handler for property change events from the nested editor
 */
public int addPage(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);
	Composite parent2 = new Composite(getContainer(), SWT.NONE);
	parent2.setLayout(new FillLayout());
	editor.createPartControl(parent2);
	editor.addPropertyListener(
		new IPropertyListener() {
			public void propertyChanged(Object source, int propertyId) {
				MultiPageEditorPart.this.handlePropertyChange(propertyId);
			}
		});
	// create item for page only after createPartControl has succeeded
	Item item = createItem(parent2);
	// remember the editor, as both data on the item, and in the list of editors (see field comment)
	item.setData(editor);
	nestedEditors.add(editor);
	return getPageCount() - 1;
}
/**
 * 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.
 * 
 * @return a new container
 */
private CTabFolder createContainer(Composite parent) {
	final CTabFolder container = new CTabFolder(parent, SWT.BOTTOM);
	container.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
			int newPageIndex = container.indexOf((CTabItem) e.item);
			pageChange(newPageIndex);
		}
	});
	container.addMouseListener(new MouseAdapter() {
		public void mouseDown(MouseEvent e) {
			container.setFocus();
		}
	});
	return container;
}
/**
 * Creates a tab item and places control in the new item.
 * The item is a CTabItem with no style bits set.
 *
 * @param control is the control to be placed in an item
 * @return a new item
 */
private CTabItem createItem(Control control) {
	CTabItem item = new CTabItem(getTabFolder(), SWT.NONE);
	item.setControl(control);
	return item;
}
/**
 * Creates the pages of this multi-page editor.
 * <p>
 * Subclasses must implement this method.
 * </p>
 */
protected abstract void createPages();
/**
 * 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.
 */
public final void createPartControl(Composite parent) {
	this.container = createContainer(parent);
	createPages();
	// set the active page (page 0 by default), unless it has already been done
	if (getTabFolder().getSelectionIndex() == -1)
		setActivePage(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 MultiPageEditorSite(this, editor);
}
/**
 * The <code>MultiPageEditorPart</code> implementation of this 
 * <code>IWorkbenchPart</code> method disposes all nested editors.
 * Subclasses may extend.
 */
public void dispose() {
	for (int i = 0; i < nestedEditors.size(); ++i) {
		IEditorPart editor = (IEditorPart) nestedEditors.get(i);
		editor.dispose();
	}
	nestedEditors.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
 */
protected IEditorPart getActiveEditor() {
	int index = getActivePage();
	if (index != -1)
		return getEditor(index);
	return null;
}
/**
 * Returns the index of the currently active page,
 * or -1 if there is no active page.
 * <p>
 * Subclasses should not override this method
 * </p>
 *
 * @return the index of the active page, or -1 if there is no active page
 */
protected int getActivePage() {
	// May not have been created yet.
	if (getTabFolder() != null)
		return getTabFolder().getSelectionIndex();
	return -1;
}
/**
 * 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 container;
}
/**
 * Returns the control for the given page index, or <code>null</code>
 * if no control has been set for the page.
 * The page index must be valid.
 * <p>
 * Subclasses should not override this method
 * </p>
 *
 * @param pageIndex the index of the page
 * @return the control for the specified page, or <code>null</code> if none has been set
 */
protected Control getControl(int pageIndex) {
	return getItem(pageIndex).getControl();
}
/**
 * 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) {
	Item item = getItem(pageIndex);
	if (item != null) {
		Object data = item.getData();
		if (data instanceof IEditorPart) {
			return (IEditorPart) data;
		}
	}
	return null;
}
/**
 * Returns the tab item for the given page index (page index is 0-based).
 * The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @return the tab item for the given page index
 */
private CTabItem getItem(int pageIndex) {
	return getTabFolder().getItem(pageIndex);
}
/**
 * Returns the number of pages in this multi-page editor.
 *
 * @return the number of pages
 */
protected int getPageCount() {
	CTabFolder folder = getTabFolder();
	// May not have been created yet, or may have been disposed.
	if (folder != null && !folder.isDisposed())
		return folder.getItemCount();
	return 0;
}
/**
 * Returns the image for the page with the given index,
 * or <code>null</code> if no image has been set for the page.
 * The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @return the image, or <code>null</code> if none
 */
protected Image getPageImage(int pageIndex) {
	return getItem(pageIndex).getImage();
}
/**
 * Returns the text label for the page with the given index.
 * Returns the empty string if no text label has been set for the page.
 * The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @return the text label for the page
 */
protected String getPageText(int pageIndex) {
	return getItem(pageIndex).getText();
}
/**
 * Returns the tab folder containing this multi-page editor's pages.
 *
 * @return the tab folder, or <code>null</code> if <code>createPartControl</code>
 *   has not been called yet
 */
private CTabFolder getTabFolder() {
	return container;
}
/**
 * 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.
 */
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
	setSite(site);
	setInput(input);
	site.setSelectionProvider(new MultiPageSelectionProvider(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>
 */
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 pageChange(int newPageIndex) {
	// XXX: Workaround for 1GCN531: SWT:WIN2000 - CTabFolder child's visibility is false on notification
	Control control = getControl(newPageIndex);
	if (control != null) {
		control.setVisible(true);
	}
	// XXX: End workaround
	setFocus();
	IEditorPart activeEditor = getEditor(newPageIndex);
	IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
	if (contributor != null && contributor instanceof MultiPageEditorActionBarContributor) {
		((MultiPageEditorActionBarContributor) contributor).setActivePage(activeEditor);
	}
	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());
			((MultiPageSelectionProvider) getSite().getSelectionProvider()).fireSelectionChanged(event);
		}
	}
}
/**
 * Removes the page with the given index from this multi-page editor.
 * The controls for the page are disposed of; if the page has an editor, 
 * it is disposed of too. The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @see #addPage
 */
public void removePage(int pageIndex) {
	Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
	// get editor (if any) before disposing item
	IEditorPart editor = getEditor(pageIndex);
	// dispose item before disposing editor, in case there's an exception in editor's dispose
	getItem(pageIndex).dispose();
	// dispose editor (if any)
	if (editor != null) {
		nestedEditors.remove(editor);
		editor.dispose();
	}
}
/**
 * Sets the currently active page.
 *
 * @param pageIndex the index of the page to be activated; the index must be valid
 */
protected void setActivePage(int pageIndex) {
	Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
	getTabFolder().setSelection(pageIndex);
}
/**
 * Sets the control for the given page index.
 * The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @param control the control for the specified page, or <code>null</code> to clear the control
 */
protected void setControl(int pageIndex, Control control) {
	getItem(pageIndex).setControl(control);
}
/**
 * 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() {
	int index = getActivePage();
	if (index != -1)
		setFocus(index);
}
/**
 * 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.
 *
 * @pageIndex the index of the page
 */
private void setFocus(int pageIndex) {
	if (pageIndex < 0 || pageIndex >= getPageCount())
		return;
	IEditorPart editor = getEditor(pageIndex);
	if (editor != null) {
		editor.setFocus();
	} else {
		Control control = getControl(pageIndex);
		if (control != null) {
			control.setFocus();
		}
	}
}
/**
 * Sets the image for the page with the given index, or <code>null</code>
 * to clear the image for the page.
 * The page index must be valid.
 *
 * @param pageIndex the index of the page
 * @param image the image, or <code>null</code>
 */
protected void setPageImage(int pageIndex, Image image) {
	getItem(pageIndex).setImage(image);
}
/**
 * Sets the text label for the page with the given index.
 * The page index must be valid.
 * The text label must not be null.
 *
 * @param pageIndex the index of the page
 * @param text the text label
 */
protected void setPageText(int pageIndex, String text) {
	getItem(pageIndex).setText(text);
}
}
