/*******************************************************************************
 * Copyright (c) 2000, 2005 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;

import java.util.Vector;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.widgets.*;

/**
 * Managed form wraps a form widget and adds life cycle methods for form parts.
 * A form part is a portion of the form that participates in form life cycle
 * events.
 * <p>
 * There is requirement for 1/1 mapping between widgets and form parts. A widget
 * like Section can be a part by itself, but a number of widgets can join around
 * one form part.
 * <p>
 * Note to developers: this class is left public to allow its use beyond the
 * original intention (inside a multi-page editor's page). You should limit the
 * use of this class to make new instances inside a form container (wizard page,
 * dialog etc.). Clients that need access to the class should not do it
 * directly. Instead, they should do it through IManagedForm interface as much
 * as possible.
 * 
 * @since 3.0
 */
public class ManagedForm implements IManagedForm {
	private Object input;

	private ScrolledForm form;

	private FormToolkit toolkit;

	private Object container;

	private boolean ownsToolkit;

	private boolean initialized;

	private Vector parts = new Vector();

	/**
	 * Creates a managed form in the provided parent. Form toolkit and widget
	 * will be created and owned by this object.
	 * 
	 * @param parent
	 *            the parent widget
	 */
	public ManagedForm(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());
		ownsToolkit = true;
		form = toolkit.createScrolledForm(parent);
	}

	/**
	 * Creates a managed form that will use the provided toolkit and
	 * 
	 * @param toolkit
	 * @param form
	 */
	public ManagedForm(FormToolkit toolkit, ScrolledForm form) {
		this.form = form;
		this.toolkit = toolkit;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#addPart(org.eclipse.ui.forms.IFormPart)
	 */
	public void addPart(IFormPart part) {
		parts.add(part);
		part.initialize(this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#removePart(org.eclipse.ui.forms.IFormPart)
	 */
	public void removePart(IFormPart part) {
		parts.remove(part);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#getParts()
	 */
	public IFormPart[] getParts() {
		return (IFormPart[]) parts.toArray(new IFormPart[parts.size()]);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#getToolkit()
	 */
	public FormToolkit getToolkit() {
		return toolkit;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#getForm()
	 */
	public ScrolledForm getForm() {
		return form;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#reflow(boolean)
	 */
	public void reflow(boolean changed) {
		form.reflow(changed);
	}

	/**
	 * A part can use this method to notify other parts that implement
	 * IPartSelectionListener about selection changes.
	 * 
	 * @param part
	 *            the part that broadcasts the selection
	 * @param selection
	 *            the selection in the part
	 * @see IPartSelectionListener
	 */
	public void fireSelectionChanged(IFormPart part, ISelection selection) {
		for (int i = 0; i < parts.size(); i++) {
			IFormPart cpart = (IFormPart) parts.get(i);
			if (part.equals(cpart))
				continue;
			if (cpart instanceof IPartSelectionListener) {
				((IPartSelectionListener) cpart).selectionChanged(part,
						selection);
			}
		}
	}

	/**
	 * Initializes the form by looping through the managed parts and
	 * initializing them. Has no effect if already called once.
	 */
	public void initialize() {
		if (initialized)
			return;
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			part.initialize(this);
		}
		initialized = true;
	}

	/**
	 * Disposes all the parts in this form.
	 */
	public void dispose() {
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			part.dispose();
		}
		if (ownsToolkit) {
			toolkit.dispose();
		}
	}

	/**
	 * Refreshes the form by refreshes all the stale parts. Since 3.1, this
	 * method is performed on a UI thread when called from another thread so it
	 * is not needed to wrap the call in <code>Display.syncExec</code> or
	 * <code>asyncExec</code>.
	 */
	public void refresh() {
		Thread t = Thread.currentThread();
		Thread dt = toolkit.getColors().getDisplay().getThread();
		if (t.equals(dt))
			doRefresh();
		else {
			toolkit.getColors().getDisplay().asyncExec(new Runnable() {
				public void run() {
					doRefresh();
				}
			});
		}
	}

	private void doRefresh() {
		int nrefreshed = 0;
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			if (part.isStale()) {
				part.refresh();
				nrefreshed++;
			}
		}
		if (nrefreshed > 0)
			form.reflow(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#commit(boolean)
	 */
	public void commit(boolean onSave) {
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			if (part.isDirty())
				part.commit(onSave);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#setInput(java.lang.Object)
	 */
	public boolean setInput(Object input) {
		boolean pageResult = false;

		this.input = input;
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			boolean result = part.setFormInput(input);
			if (result)
				pageResult = true;
		}
		return pageResult;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#getInput()
	 */
	public Object getInput() {
		return input;
	}

	/**
	 * Transfers the focus to the first form part.
	 */
	public void setFocus() {
		if (parts.size() > 0) {
			IFormPart part = (IFormPart) parts.get(0);
			part.setFocus();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#isDirty()
	 */
	public boolean isDirty() {
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			if (part.isDirty())
				return true;
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#isStale()
	 */
	public boolean isStale() {
		for (int i = 0; i < parts.size(); i++) {
			IFormPart part = (IFormPart) parts.get(i);
			if (part.isStale())
				return true;
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#dirtyStateChanged()
	 */
	public void dirtyStateChanged() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#staleStateChanged()
	 */
	public void staleStateChanged() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#getContainer()
	 */
	public Object getContainer() {
		return container;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IManagedForm#setContainer(java.lang.Object)
	 */
	public void setContainer(Object container) {
		this.container = container;
	}
}
