/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui.preferences;


import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.ui.model.AntUIPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.FileSystemElement;
import org.eclipse.ui.externaltools.internal.ui.TreeAndListGroup;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.model.WorkbenchViewerSorter;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;

public class AddCustomDialog extends StatusDialog {
	
	private ZipFileStructureProvider providerCache;
	private IImportStructureProvider currentProvider;
	
	//A boolean to indicate if the user has typed anything
	private boolean entryChanged = false;

	private Combo sourceNameField;
	private List libraryEntries;
	private List existingNames;
	
	private String noNameErrorMsg;
	private String alreadyExistsErrorMsg;
	
	private TreeAndListGroup selectionGroup;
	
	private Text nameField;
	
	private String name=""; //$NON-NLS-1$
	private IAntClasspathEntry library= null;
	private String className=""; //$NON-NLS-1$
	
	private boolean editing= false;
	
	private String helpContext;

	/**
	 * Creates a new dialog with the given shell and title.
	 */
	public AddCustomDialog(Shell parent, List libraryEntries, List existingNames, String helpContext) {
		super(parent);
		this.libraryEntries = libraryEntries;
		this.existingNames= existingNames;
		this.helpContext= helpContext;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createDialogArea(Composite parent) {
		Composite topComposite= (Composite) super.createDialogArea(parent);
		topComposite.setSize(topComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

		createNameGroup(topComposite);
		new Label(topComposite, SWT.NULL);
		createRootDirectoryGroup(topComposite);
		createFileSelectionGroup(topComposite);
		
		if (library != null) {
			setSourceName(library.getLabel());
		}
		return topComposite;
	}
	
	private void createNameGroup(Composite topComposite) {
		Composite nameContainerGroup = new Composite(topComposite, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		nameContainerGroup.setLayout(layout);
		nameContainerGroup.setFont(topComposite.getFont());
		nameContainerGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
		
		Label label = new Label(nameContainerGroup, SWT.NONE);
		label.setFont(topComposite.getFont());
		label.setText(AntPreferencesMessages.getString("AddCustomDialog.&Name__3")); //$NON-NLS-1$
		
		nameField = new Text(nameContainerGroup, SWT.BORDER);
		GridData data = new GridData(GridData.FILL_HORIZONTAL);
		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
	
		nameField.setLayoutData(data);
		nameField.setFont(topComposite.getFont());
		nameField.setText(name);
		nameField.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				updateStatus();
			}
		});
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		WorkbenchHelp.setHelp(newShell, helpContext);
	}
	
	/**
	 * Clears the cached structure provider after first finalizing
	 * it properly.
	 */
	private void clearProviderCache() {
		if (providerCache != null) {
			closeZipFile(providerCache.getZipFile());
			providerCache = null;
		}
	}
	
	/**
	 * Attempts to close the passed zip file, and answers a boolean indicating success.
	 */
	private boolean closeZipFile(ZipFile file) {
		try {
			file.close();
		} catch (IOException e) {
			AntUIPlugin.log(MessageFormat.format(AntPreferencesMessages.getString("AddCustomDialog.Could_not_close_zip_file_{0}_4"), new String[]{file.getName()}), e); //$NON-NLS-1$
			return false;
		}

		return true;
	}

	/**
	 *	Create the group for creating the root directory
	 */
	private void createRootDirectoryGroup(Composite parent) {
		Composite sourceContainerGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight=0;
		layout.marginWidth=0;
		
		sourceContainerGroup.setLayout(layout);
		sourceContainerGroup.setFont(parent.getFont());
		sourceContainerGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		Label groupLabel = new Label(sourceContainerGroup, SWT.NONE);
		groupLabel.setText(AntPreferencesMessages.getString("AddCustomDialog.&Location")); //$NON-NLS-1$
		groupLabel.setFont(parent.getFont());

		// source name entry field
		sourceNameField = new Combo(sourceContainerGroup, SWT.BORDER | SWT.READ_ONLY);
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
		sourceNameField.setLayoutData(data);
		sourceNameField.setFont(parent.getFont());
		
		sourceNameField.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				updateFromSourceField();
			}
		});

		Iterator libraries= libraryEntries.iterator();
		while (libraries.hasNext()) {
			ClasspathEntry entry = (ClasspathEntry) libraries.next();
			sourceNameField.add(entry.getLabel());
		}

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

		sourceNameField.addFocusListener(new FocusAdapter() {
			/*
			 * @see FocusListener.focusLost(FocusEvent)
			 */
			public void focusLost(FocusEvent e) {
				//Clear the flag to prevent constant update
				if (entryChanged) {
					entryChanged = false;
					updateFromSourceField();
				}
			}
		});
	}
	
	/**
	 * Update the receiver from the source name field.
	 */
	private void updateFromSourceField(){
		setSourceName(sourceNameField.getText());
		updateStatus();
	}
	
	
	/**
	 * Check the field values and display a message in the status if needed.
	 */
	private void updateStatus() {
		StatusInfo status= new StatusInfo();
		String customName= nameField.getText().trim();
		if (customName.length() == 0) {
			status.setError(noNameErrorMsg);
		} else if (!editing){
			Iterator names= existingNames.iterator();
			while (names.hasNext()) {
				String aName = (String) names.next();
				if(aName.equals(customName)) {
					status.setError(MessageFormat.format(alreadyExistsErrorMsg, new String[]{customName}));
					updateStatus(status);
					return;
				}
			}
		} 
		if (selectionGroup.getListTableSelection().isEmpty()) {
			status.setError(AntPreferencesMessages.getString("AddCustomDialog.mustSelect")); //$NON-NLS-1$
		}
		updateStatus(status);
	}

	
	/**
	 * 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
	 */
	private 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;
					break;
				}
			}
			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();
		}
	}

	/*
	* Create the file selection widget
	*/
	private void createFileSelectionGroup(Composite parent) {
		//Just create with a dummy root.
		FileSystemElement dummyRoot= new FileSystemElement("Dummy", null, true); //$NON-NLS-1$
		this.selectionGroup = new TreeAndListGroup(parent, dummyRoot, 
				getFolderProvider(), new WorkbenchLabelProvider(), getFileProvider(),
				new WorkbenchLabelProvider(), SWT.NONE, 400, 150, false);

		ISelectionChangedListener listener = new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				updateStatus();
			}
		};

		WorkbenchViewerSorter sorter = new WorkbenchViewerSorter();
		this.selectionGroup.setTreeSorter(sorter);
		this.selectionGroup.setListSorter(sorter);
		this.selectionGroup.addSelectionChangedListener(listener);
		selectionGroup.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				if (getButton(IDialogConstants.OK_ID).isEnabled()) {
					buttonPressed(IDialogConstants.OK_ID);
				}
			}
		});
	}
	
	/**
	 *	Returns whether the specified source currently exists
	 *	and is valid (ie.- proper format)
	 */
	protected boolean ensureSourceIsValid() {
		ZipFile specifiedFile = getSpecifiedSourceFile();

		if (specifiedFile == null){
			return false;
		}

		return closeZipFile(specifiedFile);
	}
	/**
	*	Answer the root FileSystemElement that represents the contents of the
	*	currently-specified .zip file.  If this FileSystemElement is not
	*	currently defined then create and return it.
	*/
	private MinimizedFileSystemElement getFileSystemTree() {
		IImportStructureProvider provider= null;
		MinimizedFileSystemElement element= null;
		ZipFile sourceFile = getSpecifiedSourceFile();
		if (sourceFile == null) {
			File file= new File(sourceNameField.getText());
			if (file.exists()) {
				provider = FileSystemStructureProvider.INSTANCE;
				element= selectFiles(file, provider);
			} 
		} else {
			//zip file set as location
			provider = getStructureProvider(sourceFile);
			element= selectFiles(((ZipFileStructureProvider)provider).getRoot(), provider);
		}
		this.currentProvider = provider;
		return element;
	}
	
	/**
	 * Invokes a file selection operation using the specified file system and
	 * structure provider.  If the user specifies files then this selection is
	 * cached for later retrieval and is returned.
	 */
	private 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];
	}
	
	/**
	 * Creates and returns a <code>MinimizedFileSystemElement</code> if the specified
	 * file system object merits one.
	 */
	private 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.setFileSystemObject(fileSystemObject);

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

		return dummyParent;
	}
	
	/**
	 *	Answer a handle to the zip file currently specified as being the source.
	 *	Return <code>null</code> if this file does not exist or is not of valid format.
	 */
	private ZipFile getSpecifiedSourceFile() {
		try {
			String expanded = sourceNameField.getText();
			expanded= VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(expanded);
			return new ZipFile(expanded);
		} catch (ZipException e) {
			StatusInfo status= new StatusInfo();
			status.setError(AntPreferencesMessages.getString("AddCustomDialog.Bad_Format")); //$NON-NLS-1$
			updateStatus(status);
		} catch (IOException e) {
			StatusInfo status= new StatusInfo();
			status.setError(AntPreferencesMessages.getString("AddCustomDialog.Unreadable")); //$NON-NLS-1$
			updateStatus(status);
		} catch (CoreException e) {
			StatusInfo status= new StatusInfo();
			status.setError(AntPreferencesMessages.getString("AddCustomDialog.13")); //$NON-NLS-1$
			updateStatus(status);
		}

		sourceNameField.setFocus();
		return null;
	}
	/**
	 * Returns a structure provider for the specified zip file.
	 */
	private 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;
	}

	/**
	 *	Repopulate the view based on the currently entered directory.
	 */
	private void resetSelection() {
		MinimizedFileSystemElement currentRoot = getFileSystemTree();
		selectionGroup.setRoot(currentRoot);
		
		if (className.length() != 0) {
			StringTokenizer tokenizer= new StringTokenizer(className, "."); //$NON-NLS-1$
			selectClass(currentRoot, tokenizer);
		}
	}
	
	private void selectClass(MinimizedFileSystemElement currentParent, StringTokenizer tokenizer) {
		if (!tokenizer.hasMoreTokens()) {
			return;
		}
		List folders= currentParent.getFolders(currentProvider);
		if (folders.size() == 1) {
			MinimizedFileSystemElement element = (MinimizedFileSystemElement)folders.get(0);
			if (element.getLabel(null).equals("/")) { //$NON-NLS-1$
				selectionGroup.selectAndRevealFolder(element);
				selectClass(element, tokenizer);
				return;
			}
		}
		String currentName= tokenizer.nextToken();
		if (tokenizer.hasMoreTokens()) {
			Iterator allFolders= folders.iterator();
			while (allFolders.hasNext()) {
				MinimizedFileSystemElement folder = (MinimizedFileSystemElement) allFolders.next();
				if (folder.getLabel(null).equals(currentName)) {
					selectionGroup.selectAndRevealFolder(folder);
					selectClass(folder, tokenizer);
					return;
				}
			}	
		} else {
			List files= currentParent.getFiles(currentProvider);
			Iterator iter= files.iterator();
			while (iter.hasNext()) {
				MinimizedFileSystemElement file = (MinimizedFileSystemElement) iter.next();
				if (file.getLabel(null).equals(currentName + ".class")) { //$NON-NLS-1$
					selectionGroup.selectAndRevealFile(file);
					return;
				}
			}
		}
	}

	/**
	 * Returns a content provider for <code>MinimizedFileSystemElement</code>s that returns
	 * only files as children.
	 */
	private ITreeContentProvider getFileProvider() {
		return new WorkbenchContentProvider() {
			public Object[] getChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					return element.getFiles(currentProvider).toArray();
				}
				return new Object[0];
			}
		};
	}

	/**
	 * Returns a content provider for <code>MinimizedFileSystemElement</code>s that returns
	 * only folders as children.
	 */
	private ITreeContentProvider getFolderProvider() {
		return new WorkbenchContentProvider() {
			public Object[] getChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					return element.getFolders(currentProvider).toArray();
				}
				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;
			}
		};
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#cancelPressed()
	 */
	protected void cancelPressed() {
		clearProviderCache();
		super.cancelPressed();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
	 */
	protected void okPressed() {
		clearProviderCache();
		name= nameField.getText().trim();
		library= (ClasspathEntry)libraryEntries.get(sourceNameField.getSelectionIndex());
		IStructuredSelection selection= this.selectionGroup.getListTableSelection();
		MinimizedFileSystemElement element= (MinimizedFileSystemElement)selection.getFirstElement();
		if (element == null) {
			super.okPressed();
			return;
		}
		Object file= element.getFileSystemObject();
		if (file instanceof ZipEntry) {
			className= ((ZipEntry)file).getName();
		} else {
			className= ((File)file).getAbsolutePath();
			IPath classPath= new Path(className);
			IPath libraryPath= new Path(library.getEntryURL().getPath());
			int matching= classPath.matchingFirstSegments(libraryPath);
			classPath= classPath.removeFirstSegments(matching);
			classPath= classPath.setDevice(null);
			className= classPath.toString();
		}
		int index= className.lastIndexOf('.');
		className= className.substring(0, index);
		className= className.replace('/', '.'); 
		super.okPressed();
	}
	
	protected String getName() {
		return name;
	}
	
	protected void setName(String name) {
		this.name= name;
	} 
	
	protected void setLibraryEntry(IAntClasspathEntry library) {
		this.library= library;
		editing= true;
	}
	
	protected IAntClasspathEntry getLibraryEntry() {
		return this.library;
	}
	
	protected String getClassName() {
		return className;
	}
	
	protected void setClassName(String className) {
		this.className= className;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#create()
	 */
	public void create() {
		super.create();
		getButton(IDialogConstants.OK_ID).setEnabled(!(library == null));
	}
	
	protected void setAlreadyExistsErrorMsg(String alreadyExistsErrorMsg) {
		this.alreadyExistsErrorMsg = alreadyExistsErrorMsg;
	}

	protected void setNoNameErrorMsg(String noNameErrorMsg) {
		this.noNameErrorMsg = noNameErrorMsg;
	}
}