/*******************************************************************************
 * Copyright (c) 2003, 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 API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.wizard;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jst.j2ee.internal.actions.IJ2EEUIContextIds;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIPlugin;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.FileSystemElement;
import org.eclipse.ui.dialogs.WizardResourceImportPage;
import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;


/**
 * Page 1 of the base resource import-from-file-system Wizard
 */
/* package */
class WizardClassesImportPage1 extends WizardResourceImportPage implements Listener {

	// widgets
	protected Combo sourceNameField;
	protected Button overwriteExistingResourcesCheckbox;
	protected Button createContainerStructureButton;
	protected Button createOnlySelectedButton;
	protected Button sourceBrowseButton;
	//protected Button selectTypesButton;
	protected Button selectAllButton;
	protected Button deselectAllButton;
	//A boolean to indicate if the user has typed anything
	private boolean entryChanged = false;

	// dialog store id constants
	private final static String STORE_SOURCE_NAMES_ID = "WizardFileSystemResourceImportPage1.STORE_SOURCE_NAMES_ID"; //$NON-NLS-1$
	//$NON-NLS-1$
	//private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID =
	// "WizardFileSystemResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID"; //$NON-NLS-1$
	//$NON-NLS-1$
	//private final static String STORE_CREATE_CONTAINER_STRUCTURE_ID =
	// "WizardFileSystemResourceImportPage1.STORE_CREATE_CONTAINER_STRUCTURE_ID"; //$NON-NLS-1$
	//$NON-NLS-1$

	//private static final String SELECT_TYPES_TITLE = "DataTransfer.selectTypes"; //$NON-NLS-1$
	private static final String SELECT_ALL_TITLE = J2EEUIMessages.getResourceString("DataTransfer.selectAll"); //$NON-NLS-1$
	private static final String DESELECT_ALL_TITLE = J2EEUIMessages.getResourceString("DataTransfer.deselectAll"); //$NON-NLS-1$
	private static final String SELECT_SOURCE_MESSAGE = J2EEUIMessages.getResourceString("FileImport.selectSource"); //$NON-NLS-1$
	protected static final String SOURCE_EMPTY_MESSAGE = J2EEUIMessages.getResourceString("FileImport.sourceEmpty"); //$NON-NLS-1$

	private IPath importedClassesPath;
	//protected Button importFromDir;
	//protected Button importFromZip;


	private ZipFileStructureProvider providerCache;
	ZipFileStructureProvider currentProvider;

	private static final String FILE_IMPORT_MASK = "*.jar;*.zip"; //$NON-NLS-1$

	private List dragAndDropFileNames = null;

	boolean createFullStructure = false;
	private String packageBaseDirName = null;

	//private MinimizedFileSystemElement test = null;

	//private Composite dummyParent = null;

	//private final static int SIZING_SELECTION_WIDGET_WIDTH = 400;
	//private final static int SIZING_SELECTION_WIDGET_HEIGHT = 150;

	private String packageDirStruc = null;

	/**
	 * Creates an instance of this class
	 */
	protected WizardClassesImportPage1(String name, IWorkbench aWorkbench, IStructuredSelection selection) {
		super(name, selection);
	}

	/**
	 * Creates an instance of this class
	 * 
	 * @param aWorkbench
	 *            IWorkbench
	 * @param selection
	 *            IStructuredSelection
	 */
	public WizardClassesImportPage1(IWorkbench aWorkbench, IStructuredSelection selection, IPath importedClassesPath, List fileNames) {
		this("fileSystemImportPage1", aWorkbench, selection); //$NON-NLS-1$
		setTitle(J2EEUIMessages.getResourceString("DataTransfer.fileSystemTitle")); //$NON-NLS-1$
		setDescription(J2EEUIMessages.getResourceString("FileImport.importFileSystem")); //$NON-NLS-1$
		setImageDescriptor(J2EEUIPlugin.getDefault().getImageDescriptor("import_class_file_wiz_ban")); //$NON-NLS-1$
		this.importedClassesPath = importedClassesPath;
		if (fileNames != null && fileNames.size() != 0) {
			dragAndDropFileNames = fileNames;
		}
	}

	public void blankPage() {
		if (this.selectionGroup != null)
			this.selectionGroup.setRoot(null);
		if (sourceNameField != null)
			sourceNameField.setText(""); //$NON-NLS-1$
	}


	/**
	 * Creates a new button with the given id.
	 * <p>
	 * The <code>Dialog</code> implementation of this framework method creates a standard push
	 * button, registers for selection events including button presses and registers default buttons
	 * with its shell. The button id is stored as the buttons client data. Note that the parent's
	 * layout is assumed to be a GridLayout and the number of columns in this layout is incremented.
	 * Subclasses may override.
	 * </p>
	 * 
	 * @param parent
	 *            the parent composite
	 * @param id
	 *            the id of the button (see <code>IDialogConstants.*_ID</code> constants for
	 *            standard dialog button ids)
	 * @param label
	 *            the label from the button
	 * @param defaultButton
	 *            <code>true</code> if the button is to be the default button, and
	 *            <code>false</code> otherwise
	 */
	protected Button createButton(Composite parent, int id, String label, boolean defaultButton) {
		// increment the number of columns in the button bar
		((GridLayout) parent.getLayout()).numColumns++;

		Button button = new Button(parent, SWT.PUSH);

		GridData buttonData = new GridData(GridData.FILL_HORIZONTAL);
		button.setLayoutData(buttonData);

		button.setData(new Integer(id));
		button.setText(label);

		if (defaultButton) {
			Shell shell = parent.getShell();
			if (shell != null) {
				shell.setDefaultButton(button);
			}
			button.setFocus();
		}
		return button;
	}

	/**
	 * Creates the buttons for selecting specific types or selecting all or none of the elements.
	 * 
	 * @param parent
	 *            the parent control
	 */
	protected final void createButtonsGroup(Composite parent) {
		// top level group
		Composite buttonComposite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;

		layout.makeColumnsEqualWidth = true;
		buttonComposite.setLayout(layout);
		buttonComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));

		// types edit button
		//		selectTypesButton = createButton(buttonComposite, IDialogConstants.SELECT_TYPES_ID,
		// SELECT_TYPES_TITLE, false);

		SelectionListener listener = new SelectionAdapter() {
			//			public void widgetSelected(SelectionEvent e) {
			//				handleTypesEditButtonPressed();
			//			}
		};
		//		selectTypesButton.addSelectionListener(listener);

		selectAllButton = createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, SELECT_ALL_TITLE, false);

		listener = new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				setAllSelections(true);
			}
		};
		selectAllButton.addSelectionListener(listener);

		deselectAllButton = createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, DESELECT_ALL_TITLE, false);

		listener = new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				setAllSelections(false);
			}
		};
		deselectAllButton.addSelectionListener(listener);

	}

	/**
	 * (non-Javadoc) Method declared on IDialogPage.
	 */
	public void createControl(Composite parent) {
		//super.createControl(parent);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IJ2EEUIContextIds.IMPORT_CLASS_WIZARD_P2);
		initializeDialogUnits(parent);

		Composite composite = new Composite(parent, SWT.NULL);
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
		composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
		composite.setFont(parent.getFont());

		//dummyParent = composite;

		createSourceGroup(composite);

		//createSpacer(composite);

		//createPlainLabel(composite,
		// WorkbenchMessages.getString("WizardImportPage.destinationLabel")); //$NON-NLS-1$
		//createDestinationGroup(composite);

		createOptionsGroup(composite);

		restoreWidgetValues();
		updateWidgetEnablements();
		setPageComplete(determinePageCompletion());

		setControl(composite);

		validateSourceGroup();
		//WorkbenchHelp.setHelp(getControl(),
		// IDataTransferHelpContextIds.FILE_SYSTEM_IMPORT_WIZARD_PAGE);
	}

	protected void createOptionsGroup(Composite parent) {
		Composite optionsGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		optionsGroup.setLayout(layout);
		optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		createOptionsGroupButtons(optionsGroup);

	}

	/**
	 * Create the import options specification widgets.
	 */
	protected void createOptionsGroupButtons(Composite optionsGroup) {

		// overwrite... checkbox
		overwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK);
		overwriteExistingResourcesCheckbox.setText(J2EEUIMessages.getResourceString("FileImport.overwriteExisting")); //$NON-NLS-1$
	}

	protected boolean isSetImportFromDir() {
		ClassesImportWizard ciw = (ClassesImportWizard) getWizard();
		return ciw.mainPage.isSetImportFromDir();
	}

	public String getClassFileDirectory(String s) {
		int index = s.lastIndexOf(File.separatorChar);
		return s.substring(0, index + 1);
	}

	/**
	 * Create the group for creating the root directory
	 */
	protected void createRootDirectoryGroup(Composite parent) {
		Composite sourceContainerGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		sourceContainerGroup.setLayout(layout);
		sourceContainerGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		new Label(sourceContainerGroup, SWT.NONE).setText(getSourceLabel());

		// source name entry field
		sourceNameField = new Combo(sourceContainerGroup, SWT.BORDER);
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		data.widthHint = SIZING_TEXT_FIELD_WIDTH;
		sourceNameField.setLayoutData(data);

		setSourceNameFieldForDragAndDrop();

		sourceNameField.addListener(SWT.Modify, this);

		sourceNameField.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateFromSourceField();

			}
		});

		sourceNameField.addKeyListener(new KeyListener() {
			/*
			 * @see KeyListener.keyPressed
			 */
			public void keyPressed(KeyEvent e) {
				//If there has been a key pressed then mark as dirty
				entryChanged = true;

			}

			/*
			 * @see KeyListener.keyReleased
			 */
			public void keyReleased(KeyEvent e) {
				//do nothing
			}
		});

		sourceNameField.addFocusListener(new FocusListener() {
			/*
			 * @see FocusListener.focusGained(FocusEvent)
			 */
			public void focusGained(FocusEvent e) {
				//Do nothing when getting focus
				if (dragAndDropFileNames != null) {
					sourceNameField.setEnabled(false);
				}

			}

			/*
			 * @see FocusListener.focusLost(FocusEvent)
			 */
			public void focusLost(FocusEvent e) {
				//Clear the flag to prevent constant update
				if (entryChanged) {

					entryChanged = false;
					updateFromSourceField();
				}

			}
		});

		// source browse button
		sourceBrowseButton = new Button(sourceContainerGroup, SWT.PUSH);
		sourceBrowseButton.setText(J2EEUIMessages.getResourceString("DataTransfer.browse")); //$NON-NLS-1$
		sourceBrowseButton.addListener(SWT.Selection, this);
		sourceBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));

		if (dragAndDropFileNames != null) {
			sourceBrowseButton.setEnabled(false);
		}

	}

	private void setSourceNameFieldForDragAndDrop() {
		if (dragAndDropFileNames != null) {
			String fileName = (String) (dragAndDropFileNames.get(0));
			sourceNameField.setText(fileName);
			File f = new File(fileName);
			if (f.isFile()) {
				if (ImportUtil.getExtension(f).equals("zip") || ImportUtil.getExtension(f).equals("jar")) { //$NON-NLS-1$ //$NON-NLS-2$
					//importFromZip.setSelection(true);
					//importFromDir.setSelection(false);
				} else if (ImportUtil.getExtension(f).equals("class")) { //$NON-NLS-1$
					sourceNameField.setText(getClassFileDirectory(fileName));

					//get com.ibm.abc.ClassName
					PackageNameResolver nameResolver = new PackageNameResolver();
					String qualifiedClassName = nameResolver.getClassName(fileName);
					if (qualifiedClassName != null) {

						//get com
						int index = qualifiedClassName.indexOf('.');
						if (index == -1) {
							String textToSet = fileName.substring(0, 1 + fileName.lastIndexOf(File.separatorChar));
							sourceNameField.setText(textToSet);
							return;
						}
						String baseDir = qualifiedClassName.substring(0, index);

						//get com.ibm.abc
						index = qualifiedClassName.lastIndexOf('.');
						String packageName = qualifiedClassName.substring(0, index);
						//get com/ibm/abc
						packageDirStruc = packageName.replace('.', File.separatorChar);

						//get C:\com
						index = fileName.indexOf(baseDir);
						//if packageDirStuc exists then set the sourceDir to com, else
						//set the directory to the parent directory of the class
						if (fileName.indexOf(packageDirStruc) != -1) {
							int baseDirLength = baseDir.length();
							String textToSet = fileName.substring(0, index + baseDirLength);
							index = packageName.indexOf('.');
							if (index == -1)
								packageBaseDirName = packageName;
							else
								packageBaseDirName = packageName.substring(0, index);

							f = new File(textToSet);
							if (f.getParent() != null)
								f = new File(f.getParent());
							textToSet = f.getAbsolutePath(); //want to set the root directory to
							// com's parent
							sourceNameField.setText(textToSet);
						}
					}

				}
			}
		}
	}

	/**
	 * Update the receiver from the source name field.
	 */

	private void updateFromSourceField() {

		setSourceName(sourceNameField.getText());
		//Update enablements when this is selected
		updateWidgetEnablements();
	}

	/**
	 * Creates and returns a <code>FileSystemElement</code> if the specified file system object
	 * merits one. The criteria for this are: Also create the children.
	 */
	protected MinimizedFileSystemElement createRootElement(Object fileSystemObject, IImportStructureProvider provider) {
		boolean isContainer = provider.isFolder(fileSystemObject);
		String elementLabel = provider.getLabel(fileSystemObject);

		// Use an empty label so that display of the element's full name
		// doesn't include a confusing label
		MinimizedFileSystemElement dummyParent = new MinimizedFileSystemElement("", null, true); //$NON-NLS-1$
		dummyParent.setPopulated();
		MinimizedFileSystemElement result = new MinimizedFileSystemElement(elementLabel, dummyParent, isContainer);

		result.setPackageBaseDirName(packageBaseDirName);
		result.setFileSystemObject(fileSystemObject);

		//Get the files for the element so as to build the first level
		result.getFiles(provider);

		return dummyParent;
	}

	/**
	 * Create the import source specification widgets
	 */
	protected void createSourceGroup(Composite parent) {
		//createImportTypeGroup(parent);
		createRootDirectoryGroup(parent);
		createFileSelectionGroup(parent);

		createButtonsGroup(parent);
	}

	/**
	 * Enable or disable the button group.
	 */
	protected void enableButtonGroup(boolean enable) {
		//		selectTypesButton.setEnabled(enable);
		selectAllButton.setEnabled(enable);
		deselectAllButton.setEnabled(enable);
	}

	/**
	 * Answer a boolean indicating whether the specified source currently exists and is valid
	 */
	protected boolean ensureSourceIsValid() {
		if (isSetImportFromDir()) {
			if (getSourceDirectory() != null && new File(getSourceDirectoryName()).isDirectory())
				return true;
			displayErrorDialog(getString("FileImport.invalidSource")); //$NON-NLS-1$
			sourceNameField.setFocus();
			return false;
		}
		ZipFile specifiedFile = getSpecifiedSourceFile();

		if (specifiedFile == null) {
			displayErrorDialog(getString("FileImport.invalidSource")); //$NON-NLS-1$
			sourceNameField.setFocus();
			return false;
		}
		return closeZipFile(specifiedFile);
	}

	/**
	 * Execute the passed import operation. Answer a boolean indicating success.
	 */
	protected boolean executeImportOperation(ImportOperation op) {
		initializeOperation(op);
		if (createFullStructure) {
			op.setCreateContainerStructure(true);
		} else {
			op.setCreateContainerStructure(false);
		}

		try {
			getContainer().run(true, true, op);
		} catch (InterruptedException e) {
			return false;
		} catch (InvocationTargetException e) {
			displayErrorDialog(e.getTargetException());
			return false;
		}

		IStatus status = op.getStatus();
		if (!status.isOK()) {
			ErrorDialog.openError(getContainer().getShell(), getString("FileImport.importProblems"), //$NON-NLS-1$
						null, // no special message
						status);
			return false;
		}

		return true;
	}

	// need the following private stuff just because the DataTransferMessages class is not public!
	//private static final String RESOURCE_BUNDLE = "org.eclipse.ui.wizards.datatransfer.messages";
	// //$NON-NLS-1$
	//private static ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);

	private static String getString(String key) {
		try {
			return J2EEUIMessages.getResourceString(key);
		} catch (MissingResourceException e) {
			return key;
		}
	}

	/**
	 * The Finish button was pressed. Try to do the required work now and answer a boolean
	 * indicating success. If false is returned then the wizard will not close.
	 * 
	 * @return boolean
	 */
	public boolean finish() {
		if (!ensureSourceIsValid())
			return false;

		clearProviderCache();

		saveWidgetValues();

		Iterator resourcesEnum = getSelectedResources().iterator();
		List fileSystemObjects = new ArrayList();
		while (resourcesEnum.hasNext()) {
			fileSystemObjects.add(((FileSystemElement) resourcesEnum.next()).getFileSystemObject());
		}

		if (fileSystemObjects.size() > 0) {
			if (getSourceDirectory() != null) {
				return importResources(fileSystemObjects);
			}
			return importResourcesFromZip(fileSystemObjects);
		}

		MessageDialog.openInformation(getContainer().getShell(), getString("DataTransfer.information"), //$NON-NLS-1$
					getString("FileImport.noneSelected")); //$NON-NLS-1$

		return false;
	}

	/**
	 * Returns a content provider for <code>FileSystemElement</code> s that returns only files as
	 * children.
	 */

	protected ITreeContentProvider getFileProvider() {
		return new WorkbenchContentProvider() {
			public Object[] getChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					if (currentProvider != null) {
						return element.getFiles(currentProvider).getChildren(element);
					}
					return element.getFiles(FileSystemStructureProvider.INSTANCE).getChildren(element);
				}
				return new Object[0];
			}

			public Object[] getElements(Object element) {
				Object[] superObjects = super.getElements(element);
				if (dragAndDropFileNames != null && getSourceDirectory() != null) {
					MinimizedFileSystemElement anElement = null;
					int newObjectsIndex = 0;
					for (int i = 0; i < superObjects.length; i++) {
						anElement = (MinimizedFileSystemElement) superObjects[i];

						File file = (File) anElement.getFileSystemObject();

						for (int k = 0; k < dragAndDropFileNames.size(); k++) {
							if (file.getAbsolutePath().equals(dragAndDropFileNames.get(k))) {
								newObjectsIndex++;
							}
						}
					}
					if (newObjectsIndex > 0) {
						Object[] newObjects = new Object[newObjectsIndex];
						newObjectsIndex = 0;

						for (int i = 0; i < superObjects.length; i++) {
							anElement = (MinimizedFileSystemElement) superObjects[i];

							File file = (File) anElement.getFileSystemObject();

							for (int k = 0; k < dragAndDropFileNames.size(); k++) {
								if (file.getAbsolutePath().equals(dragAndDropFileNames.get(k))) {

									newObjects[newObjectsIndex++] = anElement;

								}
							}

						}
						return newObjects;
					}
				}
				return superObjects;
			}
		};
	}

	/**
	 * Answer the root FileSystemElement that represents the contents of the currently-specified
	 * source. If this FileSystemElement is not currently defined then create and return it.
	 */
	protected MinimizedFileSystemElement getFileSystemTree() {
		if (isSetImportFromDir()) {
			File sourceDirectory = getSourceDirectory();
			if (sourceDirectory != null) {
				return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE);
			}
			if (sourceNameField.getText().length() > 0) {
				displayErrorDialog(getString("FileImport.invalidSource")); //$NON-NLS-1$
				sourceNameField.setFocus();
			}
			return null;
		}
		ZipFile sourceFile = getSpecifiedSourceFile();
		if (sourceFile == null) {
			//Clear out the provider as well
			this.currentProvider = null;
			if (sourceNameField.getText().length() > 0) {
				displayErrorDialog(getString("FileImport.invalidSource")); //$NON-NLS-1$
				sourceNameField.setFocus();
			}
			return null;
		}

		ZipFileStructureProvider provider = getStructureProvider(sourceFile);
		this.currentProvider = provider;
		return selectFiles(provider.getRoot(), provider);
	}

	/**
	 * Returns a content provider for <code>FileSystemElement</code> s that returns only folders
	 * as children.
	 */
	protected ITreeContentProvider getFolderProvider() {
		return new WorkbenchContentProvider() {
			public Object[] getChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					if (currentProvider != null) {
						return element.getFolders(currentProvider).getChildren(element);
					}
					return element.getFolders(FileSystemStructureProvider.INSTANCE).getChildren(element);
				}
				return new Object[0];
			}

			public boolean hasChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					if (element.isPopulated())
						return getChildren(element).length > 0;
					//If we have not populated then wait until asked
					return true;
				}
				return false;
			}

		};
	}

	/**
	 * Returns a File object representing the currently-named source directory iff it exists as a
	 * valid directory, or <code>null</code> otherwise.
	 */
	protected File getSourceDirectory() {
		return getSourceDirectory(this.sourceNameField.getText());
	}

	/**
	 * Returns a File object representing the currently-named source directory iff it exists as a
	 * valid directory, or <code>null</code> otherwise.
	 * 
	 * @param path
	 *            a String not yet formatted for java.io.File compatability
	 */
	private File getSourceDirectory(String path) {
		if (isSetImportFromDir()) {
			File sourceDirectory = new File(getSourceDirectoryName(path));
			if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
				return null;
			}

			return sourceDirectory;
		}
		return null;
	}

	/**
	 * Answer the directory name specified as being the import source. Note that if it ends with a
	 * separator then the separator is first removed so that java treats it as a proper directory
	 */
	private String getSourceDirectoryName() {
		return getSourceDirectoryName(this.sourceNameField.getText());
	}

	/**
	 * Answer the directory name specified as being the import source. Note that if it ends with a
	 * separator then the separator is first removed so that java treats it as a proper directory
	 */
	private String getSourceDirectoryName(String sourceName) {
		IPath result = new Path(sourceName.trim());

		if (result.getDevice() != null && result.segmentCount() == 0) // something like "c:"
			result = result.addTrailingSeparator();
		else
			result = result.removeTrailingSeparator();

		return result.toOSString();
	}

	/**
	 * Answer the string to display as the label for the source specification field
	 */
	protected String getSourceLabel() {
		return J2EEUIMessages.getResourceString("DataTransfer.directory"); //$NON-NLS-1$
	}

	/**
	 * Handle all events and enablements for widgets in this dialog
	 * 
	 * @param event
	 *            Event
	 */
	public void handleEvent(Event event) {
		if (event.widget == sourceBrowseButton) {
			if (isSetImportFromDir()) {
				handleSourceBrowseButtonPressed();
			} else {
				handleSourceBrowseButtonPressedForZip();
			}
		}

		super.handleEvent(event);

	}

	/**
	 * Open an appropriate source browser so that the user can specify a source to import from
	 */
	protected void handleSourceBrowseButtonPressed() {
		String currentSource = this.sourceNameField.getText();
		DirectoryDialog dialog = new DirectoryDialog(sourceNameField.getShell(), SWT.SAVE);
		dialog.setMessage(SELECT_SOURCE_MESSAGE);
		dialog.setFilterPath(getSourceDirectoryName(currentSource));

		String selectedDirectory = dialog.open();
		if (selectedDirectory != null) {
			//Just quit if the directory is not valid
			if ((getSourceDirectory(selectedDirectory) == null) || selectedDirectory.equals(currentSource))
				return;
			//If it is valid then proceed to populate
			setErrorMessage(null);
			setSourceName(selectedDirectory);
			selectionGroup.setFocus();
		}
	}

	/**
	 * Open a registered type selection dialog and note the selections in the receivers
	 * types-to-export field., Added here so that inner classes can have access
	 */
	protected void handleTypesEditButtonPressed() {

		super.handleTypesEditButtonPressed();
	}

	/**
	 * Import the resources with extensions as specified by the user
	 */
	protected boolean importResources(List fileSystemObjects) {
		Iterator i = fileSystemObjects.iterator();
		while (i.hasNext()) {
			File f = (File) i.next();
			List singleItemList = new ArrayList();
			singleItemList.add(f);
			String textToSet = getPackageName(f);
			if (textToSet != null) {
				File newSource = new File(textToSet);
				executeImportOperation(new ImportOperation(getContainerFullPath(), newSource, FileSystemStructureProvider.INSTANCE, this, singleItemList));
			} else {
				executeImportOperation(new ImportOperation(getContainerFullPath(), getSourceDirectory(), FileSystemStructureProvider.INSTANCE, this, singleItemList));

			}
		}
		return true;

	}

	protected String getPackageName(File f) {
		if (ImportUtil.getExtension(f).equals("class")) { //$NON-NLS-1$
			String fileName = f.getAbsolutePath();
			//get com.ibm.abc.ClassName
			PackageNameResolver nameResolver = new PackageNameResolver();
			String qualifiedClassName = nameResolver.getClassName(fileName);
			if (qualifiedClassName != null) {

				//get com
				int index = qualifiedClassName.indexOf('.');
				if (index == -1) {
					return fileName.substring(0, 1 + fileName.lastIndexOf(File.separatorChar));
				}
				String baseDir = qualifiedClassName.substring(0, index);

				//get com.ibm.abc
				index = qualifiedClassName.lastIndexOf('.');
				String packageName = qualifiedClassName.substring(0, index);

				//get com/ibm/abc
				packageDirStruc = packageName.replace('.', File.separatorChar);

				//get C:\com
				index = fileName.indexOf(baseDir);
				//if packageDirStuc exists then set the sourceDir to com, else
				//set the directory to the parent directory of the class
				if (fileName.indexOf(packageDirStruc) != -1) {
					int baseDirLength = baseDir.length();
					String textToSet = fileName.substring(0, index + baseDirLength);
					index = packageName.indexOf('.');
					if (index == -1)
						packageBaseDirName = packageName;
					else
						packageBaseDirName = packageName.substring(0, index);

					f = new File(textToSet);
					if (f.getParent() != null)
						f = new File(f.getParent());
					textToSet = f.getAbsolutePath(); //want to set the root directory to com's
					// parent
					//sourceNameField.setText(textToSet);
					return textToSet;
				}
			}
		}
		return null;
	}

	/**
	 * Initializes the specified operation appropriately.
	 */
	protected void initializeOperation(ImportOperation op) {

		/*
		 * op.setCreateContainerStructure( createContainerStructureButton.getSelection());
		 */
		op.setOverwriteResources(overwriteExistingResourcesCheckbox.getSelection());
	}

	/**
	 * Returns whether the extension provided is an extension that has been specified for export by
	 * the user.
	 * 
	 * @param extension
	 *            the resource name
	 * @return <code>true</code> if the resource name is suitable for export based upon its
	 *         extension
	 */
	protected boolean isExportableExtension(String extension) {
		if (selectedTypes == null) // ie.- all extensions are acceptable
			return true;

		Iterator aenum = selectedTypes.iterator();
		while (aenum.hasNext()) {
			if (extension.equalsIgnoreCase((String) aenum.next()))
				return true;
		}

		return false;
	}

	/**
	 * Repopulate the view based on the currently entered directory.
	 */
	protected void resetSelection() {

		MinimizedFileSystemElement currentRoot = getFileSystemTree();
		this.selectionGroup.setRoot(currentRoot);
		if (dragAndDropFileNames != null) {

			if (dragAndDropFileNames.get(0).toString().endsWith(".zip") == false && dragAndDropFileNames.get(0).toString().endsWith(".jar") == false) { //$NON-NLS-1$ //$NON-NLS-2$
				this.selectionGroup.expandAll();
			}

			MinimizedFileSystemElement temp = (MinimizedFileSystemElement) currentRoot.getFolders().getChildren()[0];

			List dirList = pathToArray();

			for (int i = 0; i < dirList.size(); i++) {
				String s = (String) dirList.get(i);
				Object[] folders = temp.getFolders().getChildren();
				for (int k = 0; k < folders.length; k++) {
					if (((File) ((MinimizedFileSystemElement) folders[k]).getFileSystemObject()).getName().equals(s)) {
						temp = (MinimizedFileSystemElement) temp.getFolders().getChildren()[k];
						break;
					}
				}

			}

			if (dragAndDropFileNames.get(0).toString().endsWith(".zip") == false && dragAndDropFileNames.get(0).toString().endsWith(".jar") == false) { //$NON-NLS-1$ //$NON-NLS-2$
				this.selectionGroup.initialCheckTreeItem(temp);
			}

			//If can figure out how to pre-highlight dir, then use following code
			//to check dragged files only. Also need to show all files in tree.
			/*
			 * String fileName = null; MinimizedFileSystemElement name = null; int numFiles =
			 * temp.getFiles().getChildren().length; Object[] files = temp.getFiles().getChildren();
			 * for(int i = 0; i < dragAndDropFileNames.size(); i++) { fileName = (new
			 * File((String)dragAndDropFileNames.get(i))).getName(); for(int k = 0; k < numFiles;
			 * k++) { if(fileName.equals(((File) ((MinimizedFileSystemElement)
			 * files[0]).getFileSystemObject()).getName())) {
			 * this.selectionGroup.initialCheckTreeItem(temp); break; } } }
			 */

			//this.selectionGroup.setAllSelections(true);
		}
	}

	private List pathToArray() {
		String s = (String) dragAndDropFileNames.get(0);

		PackageNameResolver nameResolver = new PackageNameResolver();
		String qualifiedClassName = nameResolver.getClassName(s);

		int slashCounts = 0;
		if (qualifiedClassName != null) {
			int index = qualifiedClassName.indexOf('.');
			if (index == -1) {
				return Collections.EMPTY_LIST;
			}
			String baseDir = qualifiedClassName.substring(0, index);
			for (int i = s.indexOf(baseDir); i < s.lastIndexOf(File.separatorChar); i++) {
				if (s.charAt(i) == File.separatorChar)
					slashCounts++;
			}
		}

		List dirNamesArray = new ArrayList(slashCounts);
		if (s.endsWith(".zip") || s.endsWith(".jar")) { //$NON-NLS-1$ //$NON-NLS-2$
			return dirNamesArray;
		}
		int startIndex = 0;
		int endIndex;
		for (int i = 0; i <= slashCounts; i++) {
			endIndex = qualifiedClassName.indexOf('.', startIndex);
			dirNamesArray.add(qualifiedClassName.substring(startIndex, endIndex));
			startIndex = endIndex + 1;
		}
		return dirNamesArray;
	}

	/**
	 * Use the dialog store to restore widget values to the values that they held last time this
	 * wizard was used to completion
	 */
	protected void restoreWidgetValues() {
		IDialogSettings settings = getDialogSettings();
		if (settings != null) {
			String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID);
			if (sourceNames == null)
				return; // ie.- no values stored, so stop

			// set filenames history
			for (int i = 0; i < sourceNames.length; i++)
				sourceNameField.add(sourceNames[i]);
		}
	}

	/**
	 * Since Finish was pressed, write widget values to the dialog store so that they will persist
	 * into the next invocation of this wizard page
	 */
	protected void saveWidgetValues() {
		IDialogSettings settings = getDialogSettings();
		if (settings != null) {
			// update source names history
			String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID);
			if (sourceNames == null)
				sourceNames = new String[0];

			sourceNames = addToHistory(sourceNames, getSourceDirectoryName());
			settings.put(STORE_SOURCE_NAMES_ID, sourceNames);

		}
	}

	/**
	 * Invokes a file selection operation using the specified file system and structure provider. If
	 * the user specifies files to be imported then this selection is cached for later retrieval and
	 * is returned.
	 */
	protected MinimizedFileSystemElement selectFiles(final Object rootFileSystemObject, final IImportStructureProvider structureProvider) {

		final MinimizedFileSystemElement[] results = new MinimizedFileSystemElement[1];

		BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
			public void run() {
				//Create the root element from the supplied file system object
				results[0] = createRootElement(rootFileSystemObject, structureProvider);
			}
		});

		return results[0];
	}

	/**
	 * Set all of the selections in the selection group to value. Implemented here to provide access
	 * for inner classes.
	 * 
	 * @param value
	 *            boolean
	 */
	protected void setAllSelections(boolean value) {
		super.setAllSelections(value);
	}

	/**
	 * Sets the source name of the import to be the supplied path. Adds the name of the path to the
	 * list of items in the source combo and selects it.
	 * 
	 * @param path
	 *            the path to be added
	 */
	protected void setSourceName(String path) {

		if (path.length() > 0) {

			String[] currentItems = this.sourceNameField.getItems();
			int selectionIndex = -1;
			for (int i = 0; i < currentItems.length; i++) {
				if (currentItems[i].equals(path))
					selectionIndex = i;
			}
			if (selectionIndex < 0) {
				int oldLength = currentItems.length;
				String[] newItems = new String[oldLength + 1];
				System.arraycopy(currentItems, 0, newItems, 0, oldLength);
				newItems[oldLength] = path;
				this.sourceNameField.setItems(newItems);
				selectionIndex = oldLength;
			}
			this.sourceNameField.select(selectionIndex);

			resetSelection();
		}
	}

	/**
	 * Update the tree to only select those elements that match the selected types
	 */
	protected void setupSelectionsBasedOnSelectedTypes() {
		ProgressMonitorDialog dialog = new ProgressMonitorDialog(getContainer().getShell());
		final Map selectionMap = new Hashtable();

		final IElementFilter filter = new IElementFilter() {

			public void filterElements(Collection files, IProgressMonitor monitor) throws InterruptedException {
				if (files == null) {
					throw new InterruptedException();
				}
				Iterator filesList = files.iterator();
				while (filesList.hasNext()) {
					if (monitor.isCanceled())
						throw new InterruptedException();
					checkFile(filesList.next());
				}
			}

			public void filterElements(Object[] files, IProgressMonitor monitor) throws InterruptedException {
				if (files == null) {
					throw new InterruptedException();
				}
				for (int i = 0; i < files.length; i++) {
					if (monitor.isCanceled())
						throw new InterruptedException();
					checkFile(files[i]);
				}
			}

			private void checkFile(Object fileElement) {
				MinimizedFileSystemElement file = (MinimizedFileSystemElement) fileElement;
				if (isExportableExtension(file.getFileNameExtension())) {
					List elements = new ArrayList();
					FileSystemElement parent = file.getParent();
					if (selectionMap.containsKey(parent))
						elements = (List) selectionMap.get(parent);
					elements.add(file);
					selectionMap.put(parent, elements);
				}
			}

		};

		IRunnableWithProgress runnable = new IRunnableWithProgress() {
			public void run(final IProgressMonitor monitor) throws InterruptedException {
				monitor.beginTask("ImportPage.filterSelections", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
				getSelectedResources(filter, monitor);
			}
		};

		try {
			dialog.run(true, true, runnable);
		} catch (InvocationTargetException exception) {
			//Couldn't start. Do nothing.
			return;
		} catch (InterruptedException exception) {
			//Got interrupted. Do nothing.
			return;
		}
		// make sure that all paint operations caused by closing the progress
		// dialog get flushed, otherwise extra pixels will remain on the screen until
		// updateSelections is completed
		getShell().update();
		// The updateSelections method accesses SWT widgets so cannot be executed
		// as part of the above progress dialog operation since the operation forks
		// a new process.
		if (selectionMap != null) {
			updateSelections(selectionMap);
		}
	}

	/*
	 * (non-Javadoc) Method declared on IDialogPage. Set the selection up when it becomes visible.
	 */
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		resetSelection();
		if (visible)
			this.sourceNameField.setFocus();
	}

	/**
	 * Update the selections with those in map . Implemented here to give inner class visibility
	 * 
	 * @param map
	 *            Map - key tree elements, values Lists of list elements
	 */
	protected void updateSelections(Map map) {
		super.updateSelections(map);
	}

	/**
	 * Check if widgets are enabled or disabled by a change in the dialog. Provided here to give
	 * access to inner classes.
	 * 
	 * @param event
	 *            Event
	 */
	protected void updateWidgetEnablements() {

		super.updateWidgetEnablements();
	}

	/**
	 * Answer a boolean indicating whether self's source specification widgets currently all contain
	 * valid values.
	 */
	protected boolean validateSourceGroup() {
		if (getSourceDirectory() != null) {
			File sourceDirectory = getSourceDirectory();
			if (sourceDirectory == null) {
				setMessage(SOURCE_EMPTY_MESSAGE);
				enableButtonGroup(false);
				return false;
			}

			if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) {
				setErrorMessage(getSourceConflictMessage()); //$NON-NLS-1$
				enableButtonGroup(false);
				return false;
			}

			enableButtonGroup(true);
			return true;
		}
		//If there is nothing being provided to the input then there is a problem
		if (this.currentProvider == null) {
			setMessage(SOURCE_EMPTY_MESSAGE);
			enableButtonGroup(false);
			return false;
		}
		enableButtonGroup(true);
		return true;
	}

	/**
	 * Returns whether the source location conflicts with the destination resource. This will occur
	 * if the source is already under the destination.
	 * 
	 * @param sourcePath
	 *            the path to check
	 * @return <code>true</code> if there is a conflict, <code>false</code> if not
	 */
	protected boolean sourceConflictsWithDestination(IPath sourcePath) {

		IContainer container = getSpecifiedContainer();
		if (container == null)
			return false;
		return getSpecifiedContainer().getLocation().isPrefixOf(sourcePath);
	}

	protected IPath getResourcePath() {
		return importedClassesPath;
	}

	//-------------------------------------------------------------------------------------

	//makesure to call mainpage.cancel()
	public boolean cancel() {
		clearProviderCache();
		return true;
	}

	/**
	 * Clears the cached structure provider after first finalizing it properly.
	 */
	protected void clearProviderCache() {
		if (providerCache != null) {
			closeZipFile(providerCache.getZipFile());
			providerCache = null;
		}
	}

	/**
	 * Attempts to close the passed zip file, and answers a boolean indicating success.
	 */
	protected boolean closeZipFile(ZipFile file) {
		try {
			file.close();
		} catch (IOException e) {
			//displayErrorDialog(DataTransferMessages.format("ZipImport.couldNotClose", new
			// Object[] { file.getName()})); //$NON-NLS-1$
			return false;
		}

		return true;
	}

	/**
	 * Answer a handle to the zip file currently specified as being the source. Return null if this
	 * file does not exist or is not of valid format.
	 */

	protected ZipFile getSpecifiedSourceFile() {
		return getSpecifiedSourceFile(sourceNameField.getText());
	}

	/**
	 * Answer a handle to the zip file currently specified as being the source. Return null if this
	 * file does not exist or is not of valid format.
	 */

	private ZipFile getSpecifiedSourceFile(String fileName) {
		if (fileName.length() == 0)
			return null;

		try {
			return ArchiveUtil.newZipFile(fileName);
		} catch (ZipException e) {
			//displayErrorDialog(DataTransferMessages.getString("ZipImport.badFormat"));
			// //$NON-NLS-1$
		} catch (IOException e) {
			//displayErrorDialog(DataTransferMessages.getString("ZipImport.couldNotRead"));
			// //$NON-NLS-1$
		}

		sourceNameField.setFocus();
		return null;
	}

	/**
	 * Returns a structure provider for the specified zip file.
	 */
	protected ZipFileStructureProvider getStructureProvider(ZipFile targetZip) {
		if (providerCache == null)
			providerCache = new ZipFileStructureProvider(targetZip);
		else if (!providerCache.getZipFile().getName().equals(targetZip.getName())) {
			clearProviderCache(); // ie.- new value, so finalize&remove old value
			providerCache = new ZipFileStructureProvider(targetZip);
		} else if (!providerCache.getZipFile().equals(targetZip))
			closeZipFile(targetZip); // ie.- duplicate handle to same .zip

		return providerCache;
	}

	/**
	 * Open a FileDialog so that the user can specify the source file to import from
	 */
	protected void handleSourceBrowseButtonPressedForZip() {
		String selectedFile = queryZipFileToImport();
		if (selectedFile != null) {
			if (!selectedFile.equals(sourceNameField.getText())) {
				//Be sure it is valid before we go setting any names
				ZipFile sourceFile = getSpecifiedSourceFile(selectedFile);
				if (sourceFile != null) {
					closeZipFile(sourceFile);
					setSourceName(selectedFile);
					selectionGroup.setFocus();
				}
			}
		}
	}

	/**
	 * Import the resources with extensions as specified by the user
	 */
	protected boolean importResourcesFromZip(List fileSystemObjects) {

		ZipFile zipFile = getSpecifiedSourceFile();
		ZipFileStructureProvider structureProvider = getStructureProvider(zipFile);

		boolean result = executeImportOperation(new ImportOperation(getContainerFullPath(), structureProvider.getRoot(), structureProvider, this, fileSystemObjects));

		closeZipFile(zipFile);

		return result;
	}

	/**
	 * Opens a file selection dialog and returns a string representing the selected file, or
	 * <code>null</code> if the dialog was canceled.
	 */
	protected String queryZipFileToImport() {
		FileDialog dialog = new FileDialog(sourceNameField.getShell(), SWT.OPEN);
		dialog.setFilterExtensions(new String[]{FILE_IMPORT_MASK});

		String currentSourceString = sourceNameField.getText();
		int lastSeparatorIndex = currentSourceString.lastIndexOf(File.separator);
		if (lastSeparatorIndex != -1)
			dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex));

		return dialog.open();
	}

}
