/*******************************************************************************
 * Copyright (c) 2000, 2013 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
 *     Ericsson AB, Hamdan Msheik - Bug 389564
 *******************************************************************************/
package org.eclipse.ant.internal.ui.preferences;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
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.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.StatusDialog;
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.PlatformUI;
import org.eclipse.ui.dialogs.FileSystemElement;
import org.eclipse.ui.externaltools.internal.ui.TreeAndListGroup;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.model.WorkbenchViewerComparator;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;

import com.ibm.icu.text.MessageFormat;

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<IAntClasspathEntry> libraryEntries;
	private List<String> existingNames;

	private String noNameErrorMsg;
	private String alreadyExistsErrorMsg;

	private TreeAndListGroup selectionGroup;

	private Text nameField;

	private String name = IAntCoreConstants.EMPTY_STRING;
	private IAntClasspathEntry library = null;
	private String className = IAntCoreConstants.EMPTY_STRING;

	private boolean editing = false;

	private String helpContext;

	/**
	 * Creates a new dialog with the given shell and title.
	 */
	public AddCustomDialog(Shell parent, List<IAntClasspathEntry> libraryEntries, List<String> existingNames, String helpContext) {
		super(parent);
		this.libraryEntries = libraryEntries;
		this.existingNames = existingNames;
		this.helpContext = helpContext;
		setShellStyle(getShellStyle() | SWT.RESIZE);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite topComposite = (Composite) super.createDialogArea(parent);
		topComposite.setSize(topComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

		Composite topGroup = new Composite(topComposite, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		topGroup.setLayout(layout);
		topGroup.setFont(topComposite.getFont());
		topGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));

		createNameGroup(topGroup);
		createRootDirectoryGroup(topGroup);
		createFileSelectionGroup(topComposite);

		if (library != null) {
			setSourceName(library.getLabel());
		}
		return topComposite;
	}

	private void createNameGroup(Composite topComposite) {
		Label label = new Label(topComposite, SWT.NONE);
		label.setFont(topComposite.getFont());
		label.setText(AntPreferencesMessages.AddCustomDialog__Name__3);

		nameField = new Text(topComposite, 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() {
			@Override
			public void modifyText(ModifyEvent e) {
				updateStatus();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		PlatformUI.getWorkbench().getHelpSystem().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.AddCustomDialog_Could_not_close_zip_file__0__4, new Object[] { file.getName() }), e);
			return false;
		}

		return true;
	}

	/**
	 * Create the group for creating the root directory
	 */
	private void createRootDirectoryGroup(Composite parent) {
		Label groupLabel = new Label(parent, SWT.NONE);
		groupLabel.setText(AntPreferencesMessages.AddCustomDialog__Location);
		groupLabel.setFont(parent.getFont());

		// source name entry field
		sourceNameField = new Combo(parent, 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() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				updateFromSourceField();
			}
		});

		for (IAntClasspathEntry entry : libraryEntries) {
			sourceNameField.add(entry.getLabel());
		}
		sourceNameField.addKeyListener(new KeyAdapter() {
			/*
			 * @see KeyListener.keyPressed
			 */
			@Override
			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)
			 */
			@Override
			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) {
			for (String aName : existingNames) {
				if (aName.equals(customName)) {
					status.setError(MessageFormat.format(alreadyExistsErrorMsg, new Object[] { customName }));
					updateStatus(status);
					return;
				}
			}
		}
		if (selectionGroup.getListTableSelection().isEmpty()) {
			status.setError(AntPreferencesMessages.AddCustomDialog_mustSelect);
		}
		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() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				updateStatus();
			}
		};

		WorkbenchViewerComparator comparator = new WorkbenchViewerComparator();
		this.selectionGroup.setTreeComparator(comparator);
		this.selectionGroup.setListSorter(comparator);
		this.selectionGroup.addSelectionChangedListener(listener);
		selectionGroup.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			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() {
			@Override
			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(IAntCoreConstants.EMPTY_STRING, null, true);
		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.AddCustomDialog_Bad_Format);
			updateStatus(status);
		}
		catch (IOException e) {
			StatusInfo status = new StatusInfo();
			status.setError(AntPreferencesMessages.AddCustomDialog_Unreadable);
			updateStatus(status);
		}
		catch (CoreException e) {
			StatusInfo status = new StatusInfo();
			status.setError(AntPreferencesMessages.AddCustomDialog_13);
			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<MinimizedFileSystemElement> folders = currentParent.getFolders(currentProvider);
		if (folders.size() == 1) {
			MinimizedFileSystemElement element = 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<MinimizedFileSystemElement> allFolders = folders.iterator();
			while (allFolders.hasNext()) {
				MinimizedFileSystemElement folder = allFolders.next();
				if (folder.getLabel(null).equals(currentName)) {
					selectionGroup.selectAndRevealFolder(folder);
					selectClass(folder, tokenizer);
					return;
				}
			}
		} else {
			List<MinimizedFileSystemElement> files = currentParent.getFiles(currentProvider);
			for (MinimizedFileSystemElement file : files) {
				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() {
			@Override
			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() {
			@Override
			public Object[] getChildren(Object o) {
				if (o instanceof MinimizedFileSystemElement) {
					MinimizedFileSystemElement element = (MinimizedFileSystemElement) o;
					return element.getFolders(currentProvider).toArray();
				}
				return new Object[0];
			}

			@Override
			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()
	 */
	@Override
	protected void cancelPressed() {
		clearProviderCache();
		super.cancelPressed();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
	 */
	@Override
	protected void okPressed() {
		clearProviderCache();
		name = nameField.getText().trim();
		library = 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 = null;
			try {
				libraryPath = new Path(URIUtil.toURL(URIUtil.toURI(library.getEntryURL())).getPath());
			}
			catch (MalformedURLException e) {
				AntUIPlugin.log(e);
			}
			catch (URISyntaxException e) {
				AntUIPlugin.log(e);
			}

			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()
	 */
	@Override
	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;
	}
}
