/*******************************************************************************
 * Copyright (c) 2003, 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.wst.server.ui.internal.wizard;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.wst.server.core.TaskModel;
import org.eclipse.wst.server.ui.internal.EclipseUtil;
import org.eclipse.wst.server.ui.internal.ServerUIPlugin;
import org.eclipse.wst.server.ui.internal.Trace;
import org.eclipse.wst.server.ui.internal.wizard.page.WorkspaceRunnableAdapter;
import org.eclipse.wst.server.ui.wizard.WizardFragment;
/**
 * A wizard used to execute tasks.
 */
public class TaskWizard implements IWizard {
	private static final byte FINISH = 2;
	private static final byte CANCEL = 3;

	private List<IWizardPage> pages;
	private boolean addingPages;
	private Map<WizardFragment, TaskWizardPage> fragmentData = new HashMap<WizardFragment, TaskWizardPage>();
	protected TaskModel taskModel;
	
	private IWizardContainer container = null;
	
	private boolean needsProgressMonitor = false;
	
	private boolean forcePreviousAndNextButtons = false;

	private boolean isHelpAvailable = false;
	
	private Image defaultImage = null;
	
	private RGB titleBarColor = null;

	private String windowTitle = null;
	
	private IDialogSettings dialogSettings = null;
	
	private WizardFragment rootFragment;
	private WizardFragment currentFragment;

	/**
	 * Create a new TaskWizard with the given title and root fragment.
	 * 
	 * @param title a title
	 * @param rootFragment a root fragment
	 */
	public TaskWizard(String title, WizardFragment rootFragment) {
		this(title, rootFragment, null);
		setWindowTitle(title);
	}

	/**
	 * Create a new TaskWizard with the given title, root fragment, and task model.
	 * 
	 * @param title a title
	 * @param rootFragment a root fragment
	 * @param taskModel a task model
	 */
	public TaskWizard(String title, WizardFragment rootFragment, TaskModel taskModel) {
		super();
		if (title != null)
			setWindowTitle(title);
		this.rootFragment = rootFragment;
		this.taskModel = taskModel;
		if (taskModel == null)
			this.taskModel = new TaskModel();
		
		setNeedsProgressMonitor(true);
		setForcePreviousAndNextButtons(true);
	}

	public void setTaskModel(TaskModel taskModel) {
		this.taskModel = taskModel;
	}
	
	public TaskModel getTaskModel() {
		return taskModel;
	}

	public void setRootFragment(WizardFragment rootFragment) {
		this.rootFragment = rootFragment;
	}
	
	public WizardFragment getRootFragment() {
		return rootFragment;
	}

	/**
	 * Cancel the client selection.
	 *
	 * @return boolean
	 */
	public boolean performCancel() {
		final List list = getAllWizardFragments();
		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				try {
					Iterator iterator = list.iterator();
					while (iterator.hasNext())
						executeTask((WizardFragment) iterator.next(), CANCEL, monitor);
				} catch (CoreException ce) {
					throw new InvocationTargetException(ce);
				}
			}
		};
		
		Throwable t = null;
		try {
			if (getContainer() != null)
				getContainer().run(true, true, runnable);
			else
				runnable.run(new NullProgressMonitor());
			return true;
		} catch (InvocationTargetException te) {
			t = te.getCause();
		} catch (Exception e) {
			t = e;
		}
		Trace.trace(Trace.SEVERE, "Error cancelling task wizard", t);
		
		if (t instanceof CoreException) {
			EclipseUtil.openError(t.getLocalizedMessage(), ((CoreException)t).getStatus());
		} else
			EclipseUtil.openError(t.getLocalizedMessage());
		
		return false;
		
	}

	public boolean performFinish() {
		if (currentFragment != null)
			currentFragment.exit();
		
		final WizardFragment cFragment = currentFragment;

		final List list = getAllWizardFragments();
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				// enter & exit the remaining pages
				int index = list.indexOf(cFragment);
				while (index > 0 && index < list.size() - 1) {
					final WizardFragment fragment = (WizardFragment) list.get(++index);
					try {
						Display.getDefault().syncExec(new Runnable() {
							public void run() {
								fragment.enter();
								fragment.exit();
							}
						});
					} catch (Exception e) {
						Trace.trace(Trace.WARNING, "Could not enter/exit page", e);
					}
				}
				
				if (useJob()) {
					class FinishWizardJob extends Job {
						public FinishWizardJob() {
							super(getJobTitle());
						}
						
						public boolean belongsTo(Object family) {
							return "org.eclipse.wst.server.ui.family".equals(family);
						}

						public IStatus run(IProgressMonitor monitor2) {
							try {
								Iterator iterator = list.iterator();
								while (iterator.hasNext())
									executeTask((WizardFragment) iterator.next(), FINISH, monitor2);
							} catch (CoreException ce) {
								Trace.trace(Trace.SEVERE, "Error finishing wizard job", ce);
								return new Status(IStatus.ERROR, ServerUIPlugin.PLUGIN_ID, 0, ce.getLocalizedMessage(), null);
							}
							return Status.OK_STATUS;
						}
					}
					
					FinishWizardJob job = new FinishWizardJob();
					job.setUser(true);
					job.schedule();
				} else {
					Iterator iterator = list.iterator();
					while (iterator.hasNext())
						executeTask((WizardFragment) iterator.next(), FINISH, monitor);
				}
			}
		};
		
		Throwable t = null;
		try {
			if (getContainer() != null)
				getContainer().run(true, true, new WorkspaceRunnableAdapter(runnable));
			else
				runnable.run(new NullProgressMonitor());
			return true;
		} catch (InvocationTargetException te) {
			Trace.trace(Trace.SEVERE, "Error finishing task wizard", te);
			t = te.getCause();
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error finishing task wizard 2", e);
			t = e;
		}
		
		// TODO: show better error dialog, e.g. when Tomcat config is corrupt while doing Add/Remove
		// it currently displays the error message twice
		Trace.trace(Trace.WARNING, "Error completing wizard", t);
		if (t instanceof CoreException) {
			EclipseUtil.openError(t.getLocalizedMessage(), ((CoreException)t).getStatus());
		} else if (t instanceof NullPointerException)
			EclipseUtil.openError("NullPointerException");
		else
			EclipseUtil.openError(t.getLocalizedMessage());
		
		return false;
	}
	
	public void addPage(IWizardPage page) {
		pages.add(page);
		page.setWizard(this);
	}
	
	protected void executeTask(WizardFragment fragment, byte type, IProgressMonitor monitor) throws CoreException {
		if (fragment == null)
			return;
		
		if (type == FINISH)
			fragment.performFinish(monitor);
		else if (type == CANCEL)
			fragment.performCancel(monitor);
	}
	
	protected WizardFragment getCurrentWizardFragment() {
		return currentFragment;
	}
	
	protected void switchWizardFragment(WizardFragment newFragment) {
		List list = getAllWizardFragments();
		int oldIndex = list.indexOf(currentFragment);
		int newIndex = list.indexOf(newFragment);
		if (oldIndex == newIndex)
			return;
		
		//safeExecuteTask(currentFragment, DEPARTURE);
		if (currentFragment != null)
			currentFragment.exit();
		
		if (oldIndex < newIndex)
			oldIndex ++;
		else
			oldIndex --;
		
		while (oldIndex != newIndex) {
			WizardFragment fragment = (WizardFragment) list.get(oldIndex);
			//safeExecuteTask(fragment, ARRIVAL);
			//safeExecuteTask(fragment, DEPARTURE);
			fragment.enter();
			fragment.exit();
			if (oldIndex < newIndex)
				oldIndex ++;
			else
				oldIndex --;
		}
		
		currentFragment = newFragment;
		//safeExecuteTask(currentFragment, ARRIVAL);
		currentFragment.enter();
	}
	
	private List<WizardFragment> getAllWizardFragments() {
		List<WizardFragment> list = new ArrayList<WizardFragment>();
		list.add(rootFragment);
		addSubWizardFragments(rootFragment, list);
		
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			WizardFragment fragment = (WizardFragment) iterator.next();
			if (!taskModel.equals(fragment.getTaskModel()))
				fragment.setTaskModel(taskModel);
		}
		return list;
	}

	private void addSubWizardFragments(WizardFragment fragment, List<WizardFragment> list) {
		Iterator iterator = fragment.getChildFragments().iterator();
		while (iterator.hasNext()) {
			WizardFragment child = (WizardFragment) iterator.next();
			list.add(child);
			addSubWizardFragments(child, list);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#addPages()
	 */
	public void addPages() {
		if (addingPages)
			return;
		
		try {
			addingPages = true;
			pages = new ArrayList<IWizardPage>();
			Iterator<WizardFragment> iterator = getAllWizardFragments().iterator();
			while (iterator.hasNext()) {
				WizardFragment fragment = iterator.next();
				TaskWizardPage page = getFragmentData(fragment);
				if (fragment.hasComposite()) {
					if (page != null)
						addPage(page);
					else {
						TaskWizardPage page2 = new TaskWizardPage(fragment);
						fragmentData.put(fragment, page2);
						addPage(page2);
					}
				}
			}
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error adding fragments to wizard", e);
		} finally {
			addingPages = false;
		}
	}

	/*private static void updateWizardPages() {
		try {
			current.updatePages();
			current.getContainer().updateButtons();
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error updating wizard pages", e);
		}
	}*/

	private TaskWizardPage getFragmentData(WizardFragment fragment) {
		try {
			TaskWizardPage page = fragmentData.get(fragment);
			if (page != null)
				return page;
		} catch (Exception e) {
			Trace.trace(Trace.SEVERE, "Error getting fragment data", e);
		}
		
		return null;
	}

	protected void updatePages() {
		addPages();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#canFinish()
	 */
	public boolean canFinish() {
		// Default implementation is to check if all pages are complete.
		for (int i= 0; i < pages.size(); i++) {
			if (!(pages.get(i)).isPageComplete())
				return false;
		}
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#createPageControls(org.eclipse.swt.widgets.Composite)
	 */
	public void createPageControls(Composite pageContainer) {
		// the default behavior is to create all the pages controls
		for (int i = 0; i < pages.size(); i++){
			IWizardPage page = pages.get(i);
			page.createControl(pageContainer);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#dispose()
	 */
	public void dispose() {
		// notify pages
		for (int i = 0; i < pages.size(); i++) {
			pages.get(i).dispose();
		}

		// dispose of image
		if (defaultImage != null) {
			defaultImage.dispose();
			defaultImage = null;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getContainer()
	 */
	public IWizardContainer getContainer() {
		return container;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getDefaultPageImage()
	 */
	public Image getDefaultPageImage() {
		return defaultImage;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getDialogSettings()
	 */
	public IDialogSettings getDialogSettings() {
		return dialogSettings;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getNextPage(org.eclipse.jface.wizard.IWizardPage)
	 */
	public IWizardPage getNextPage(IWizardPage page) {
		int index = pages.indexOf(page);
		if (index == pages.size() - 1 || index == -1)
			// last page or page not found
			return null;
		
		return pages.get(index + 1);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getPage(java.lang.String)
	 */
	public IWizardPage getPage(String name) {
		for (int i= 0; i < pages.size(); i++) {
			IWizardPage page = pages.get(i);
			String pageName = page.getName();
			if (pageName.equals(name))
				return page;
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getPageCount()
	 */
	public int getPageCount() {
		return pages.size();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getPages()
	 */
	public IWizardPage[] getPages() {
		return pages.toArray(new IWizardPage[pages.size()]);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getPreviousPage(org.eclipse.jface.wizard.IWizardPage)
	 */
	public IWizardPage getPreviousPage(IWizardPage page) {
		int index = pages.indexOf(page);
		if (index == 0 || index == -1)
			// first page or page not found
			return null;
		return pages.get(index - 1);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getStartingPage()
	 */
	public IWizardPage getStartingPage() {
		if (pages.size() == 0)
			return null;
		
		return pages.get(0);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getTitleBarColor()
	 */
	public RGB getTitleBarColor() {
		return titleBarColor;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#getWindowTitle()
	 */
	public String getWindowTitle() {
		return windowTitle;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#isHelpAvailable()
	 */
	public boolean isHelpAvailable() {
		return isHelpAvailable;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#needsPreviousAndNextButtons()
	 */
	public boolean needsPreviousAndNextButtons() {
		return forcePreviousAndNextButtons || pages.size() > 1;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#needsProgressMonitor()
	 */
	public boolean needsProgressMonitor() {
		return needsProgressMonitor;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.wizard.IWizard#setContainer(org.eclipse.jface.wizard.IWizardContainer)
	 */
	public void setContainer(IWizardContainer wizardContainer) {
		this.container = wizardContainer;
	}
	
	public void setDialogSettings(IDialogSettings settings) {
		dialogSettings = settings;
	}
	
	public void setNeedsProgressMonitor(boolean b) {
		needsProgressMonitor = b;
	}
	
	public void setForcePreviousAndNextButtons(boolean b) {
		forcePreviousAndNextButtons = b;
	}
	
	public void setWindowTitle(String title) {
		windowTitle = title;
	}

	protected boolean useJob() {
		return false;
	}

	protected String getJobTitle() {
		return getWindowTitle();
	}
}