//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.export.msp.ui.wizards;

import java.util.List;
import java.util.Map;

import org.eclipse.epf.export.msp.ExportMSPPlugin;
import org.eclipse.epf.export.msp.ExportMSPResources;
import org.eclipse.epf.export.msp.ExportMSPUtil;
import org.eclipse.epf.export.msp.ExportOptions;
import org.eclipse.epf.export.msp.ui.preferences.ExportMSPPreferences;
import org.eclipse.epf.uma.Process;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;

/**
 * A wizard page that prompts the user to select a process to export.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class SelectProcessPage extends WizardPage implements Listener {

	public static final String PAGE_NAME = SelectProcessPage.class.getName();

	private static final String[] EMPTY_ARRAY = new String[0];

	private ExportOptions exportOptions;

	private Button capabilityPatternRadioButton;

	private Button deliveryProcessRadioButton;

	private Combo processCombo;

	private Combo contextCombo;

	private Button publishConfigurationCheckBox;

	private Button exportOnlyPlannedElementsCheckBox;

	private Button[] exportOptionCheckBoxes;

	private Map capabilityPatterns;

	private Map deliveryProcesses;

	private ModifyListener modifyListener = new ModifyListener() {
		public void modifyText(ModifyEvent e) {
			setPageComplete(isPageComplete());
		}
	};

	/**
	 * Creates a new instance.
	 */
	public SelectProcessPage(ExportOptions exportOptions) {
		super(PAGE_NAME);
		this.exportOptions = exportOptions;
		setTitle(ExportMSPResources.selectProcessWizardPage_title);
		setDescription(ExportMSPResources.selectProcessWizardPage_text);
		setImageDescriptor(ExportMSPPlugin.getDefault().getImageDescriptor(
				"full/wizban/ExportMSProject.gif")); //$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		// Create the composite to hold the widgets.
		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout(1, false));

		// Create the Process group.
		Group processGroup = new Group(composite, SWT.NULL);
		processGroup.setLayout(new GridLayout(1, false));
		processGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		processGroup.setText(ExportMSPResources.processGroup_text);

		Composite buttonComposite = new Composite(processGroup, SWT.NULL);
		buttonComposite.setLayout(new GridLayout(2, false));

		capabilityPatternRadioButton = new Button(buttonComposite, SWT.RADIO);
		capabilityPatternRadioButton
				.setText(ExportMSPResources.capabilityPatternRadioButton_text);
		capabilityPatternRadioButton
				.addSelectionListener(new SelectionListener() {
					public void widgetSelected(SelectionEvent event) {
						updateProcessCombo(capabilityPatterns);
					}

					public void widgetDefaultSelected(SelectionEvent event) {
					}
				});

		deliveryProcessRadioButton = new Button(buttonComposite, SWT.RADIO);
		deliveryProcessRadioButton
				.setText(ExportMSPResources.deliveryProcessRadioButton_text);
		deliveryProcessRadioButton
				.addSelectionListener(new SelectionListener() {
					public void widgetSelected(SelectionEvent event) {
						updateProcessCombo(deliveryProcesses);
					}

					public void widgetDefaultSelected(SelectionEvent event) {
					}
				});

		Composite processComposite = new Composite(processGroup, SWT.NULL);
		processComposite.setLayout(new GridLayout(2, false));
		processComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		Label processNameLabel = new Label(processComposite, SWT.NONE);
		processNameLabel.setText(ExportMSPResources.processNameLabel_text);

		processCombo = new Combo(processComposite, SWT.BORDER | SWT.READ_ONLY);
		processCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		processCombo.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent event) {
				updateContextCombo(getProcess());
			}

			public void widgetDefaultSelected(SelectionEvent event) {
			}
		});

		Label contextNameLabel = new Label(processComposite, SWT.NONE);
		contextNameLabel.setText(ExportMSPResources.contextNameLabel_text);

		contextCombo = new Combo(processComposite, SWT.BORDER | SWT.READ_ONLY);
		contextCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		contextCombo.addModifyListener(modifyListener);

		capabilityPatterns = ExportMSPUtil.getCapabilityPatterns();
		deliveryProcesses = ExportMSPUtil.getDeliveryProcesses();
		String savedProcessType = ExportMSPPlugin.getDefault()
				.getPreferenceStore().getString(
						ExportMSPPreferences.PROCESS_TYPE);
		if (savedProcessType != null
				&& savedProcessType.equals("DeliveryProcess") && deliveryProcesses.size() > 0) { //$NON-NLS-1$
			deliveryProcessRadioButton.setSelection(true);
			updateProcessCombo(deliveryProcesses);
		} else if (savedProcessType != null && capabilityPatterns.size() > 0) {
			capabilityPatternRadioButton.setSelection(true);
			updateProcessCombo(capabilityPatterns);
		} else if (capabilityPatterns.size() > 0) {
			capabilityPatternRadioButton.setSelection(true);
			updateProcessCombo(capabilityPatterns);
		} else {
			deliveryProcessRadioButton.setSelection(true);
			updateProcessCombo(deliveryProcesses);
		}

		// Create the Export options group.
		Group optionsGroup = new Group(composite, SWT.NULL);
		optionsGroup.setLayout(new GridLayout(1, false));
		optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		optionsGroup.setText(ExportMSPResources.optionsGroup_text);

		Composite checkBoxComposite = new Composite(optionsGroup, SWT.NULL);
		checkBoxComposite.setLayout(new GridLayout(1, false));

		publishConfigurationCheckBox = new Button(checkBoxComposite, SWT.CHECK);
		publishConfigurationCheckBox
				.setText(ExportMSPResources.publishConfigurationCheckBox_text);
		publishConfigurationCheckBox
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent event) {
						exportOptions.remove(ExportOptions.PUBLISH_CONFIG);
						exportOptions.put(ExportOptions.PUBLISH_CONFIG,
								new Boolean(publishConfigurationCheckBox
										.getSelection()));
						setPageComplete(isPageComplete());
					}
				});

		exportOnlyPlannedElementsCheckBox = new Button(checkBoxComposite,
				SWT.CHECK);
		exportOnlyPlannedElementsCheckBox
				.setText(ExportMSPResources.exportOnlyPlannedElementsCheckBox_text);
		exportOnlyPlannedElementsCheckBox
				.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent event) {
						exportOptions
								.remove(ExportOptions.EXPORT_ONLY_PLANNED_ELEMENTS);
						exportOptions.put(
								ExportOptions.EXPORT_ONLY_PLANNED_ELEMENTS,
								new Boolean(exportOnlyPlannedElementsCheckBox
										.getSelection()));
						setPageComplete(isPageComplete());
					}
				});

		ExportMSPWizard wizard = (ExportMSPWizard) getWizard();
		IExportMSPWizardExtender wizardExtender = wizard.getWizardExtender();
		if (wizardExtender != null) {
			List exportOptionContributions = wizardExtender
					.getExportOptionContributions();
			int size = exportOptionContributions.size();
			exportOptionCheckBoxes = new Button[size];
			for (int i = 0; i < size; i++) {
				ExportOptionContribution exportOptionContribution = (ExportOptionContribution) exportOptionContributions
						.get(i);
				exportOptionCheckBoxes[i] = new Button(checkBoxComposite,
						SWT.CHECK);
				exportOptionCheckBoxes[i].setText(exportOptionContribution
						.getDescription());
				final String optionName = exportOptionContribution.getName();
				exportOptionCheckBoxes[i]
						.addSelectionListener(new SelectionAdapter() {
							public void widgetSelected(SelectionEvent event) {
								exportOptions.remove(optionName);
								Button button = (Button) event.getSource();
								exportOptions.put(optionName, new Boolean(
										button.getSelection()));
							}
						});

				exportOptionCheckBoxes[i].setSelection(exportOptionContribution
						.getDefaultSelection());
			}
		}

		setControl(composite);
	}

	/**
	 * @see org.eclipse.swt.widgets.Listener#handleEvent(Event)
	 */
	public void handleEvent(Event event) {
		setPageComplete(isPageComplete());
		getWizard().getContainer().updateButtons();
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#isCompleted()
	 */
	public boolean isPageComplete() {
		return processCombo.getText().trim().length() > 0
				&& contextCombo.getText().trim().length() > 0;
	}

	/**
	 * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
	 */
	public IWizardPage getNextPage() {
		ExportMSPWizard wizard = (ExportMSPWizard) getWizard();
		IExportMSPWizardExtender wizardExtender = wizard.getWizardExtender();
		if (wizardExtender != null) {
			IWizardPage page = wizardExtender.getNextPage(this);
			if (page != null) {
				return page;
			}
		}

		if (getPublishedConfiguration()) {
			return super.getNextPage();
		} else {
			return wizard.getSelectExportDirectoryPage();
		}
	}

	/**
	 * Returns the selected Process.
	 */
	public Process getProcess() {
		if (capabilityPatternRadioButton.getSelection()) {
			String name = processCombo.getText();
			return (Process) capabilityPatterns.get(name);
		} else {
			String name = processCombo.getText();
			return (Process) deliveryProcesses.get(name);
		}
	}

	/**
	 * Returns the user specified export options.
	 * 
	 * @return the user specified export options
	 */
	public ExportOptions getExportOptions() {
		return exportOptions;
	}

	/**
	 * Returns the selected Process context.
	 */
	public String getProcessContextName() {
		return (String) contextCombo.getText();
	}

	/**
	 * Returns the export only workbreakdown elements that have are planned.
	 */
	public boolean getExportOnlyPlannedElements() {
		return exportOnlyPlannedElementsCheckBox.getSelection();
	}

	/**
	 * Returns the publish Configuration selection.
	 */
	public boolean getPublishedConfiguration() {
		return publishConfigurationCheckBox.getSelection();
	}

	/**
	 * Updates the Process Combo.
	 */
	protected void updateProcessCombo(Map processes) {
		if (processes != null && processes.size() > 0) {
			String[] names = new String[processes.size()];
			processes.keySet().toArray(names);
			processCombo.setItems(names);
			String savedProcess = ExportMSPPlugin.getDefault()
					.getPreferenceStore().getString(
							ExportMSPPreferences.PROCESS_NAME);
			if (savedProcess != null && processes.containsKey(savedProcess)) {
				processCombo.setText(savedProcess);
			} else {
				processCombo.setText(processCombo.getItem(0));
			}
			updateContextCombo(getProcess());
		}
	}

	/**
	 * Updates the Context Combo.
	 */
	protected void updateContextCombo(Process process) {
		try {
			Map contexts = ExportMSPUtil.getContexts(process);
			if (contexts != null && contexts.size() > 0) {
				String[] names = new String[contexts.size()];
				contexts.keySet().toArray(names);
				contextCombo.setItems(names);
				String savedContext = ExportMSPPlugin.getDefault()
						.getPreferenceStore().getString(
								ExportMSPPreferences.PROCESS_CONTEXT);
				if (savedContext != null && contexts.containsKey(savedContext)) {
					contextCombo.setText(savedContext);
				} else {
					String defaultContext = process.getDefaultContext()
							.getName();
					contextCombo.setText(defaultContext);
				}
			} else {
				contextCombo.setItems(EMPTY_ARRAY);
			}
		} catch (Exception e) {
		}
	}

}