/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;

/**
 * Instances of this class allow the user to navigate
 * the file system and select or enter a file name.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SAVE, OPEN, MULTI</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles SAVE and OPEN may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class FileDialog extends Dialog {
	String [] filterNames = new String [0];
	String [] filterExtensions = new String [0];
	String filterPath = "";
	String fileName = "";
	String[] fileNames = new String [0];
	String fullPath = "";
	int filterIndex = -1;
	boolean overwrite = false;
	boolean uriMode;
	long /*int*/ handle;
	static final char SEPARATOR = File.separatorChar;
	static final char EXTENSION_SEPARATOR = ';';
	static final char FILE_EXTENSION_SEPARATOR = '.';
	private static final int PATH_MAX = 1024;

/**
 * Constructs a new instance of this class given only its parent.
 *
 * @param parent a shell which will be the parent of the new instance
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 */
public FileDialog (Shell parent) {
	this (parent, SWT.APPLICATION_MODAL);
}
/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a shell which will be the parent of the new instance
 * @param style the style of dialog to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#SAVE
 * @see SWT#OPEN
 * @see SWT#MULTI
 */
public FileDialog (Shell parent, int style) {
	super (parent, checkStyle (parent, style));
	checkSubclass ();
}
String computeResultChooserDialog () {
	/* MULTI is only valid if the native dialog's action is Open */
	fullPath = null;
	if ((style & SWT.MULTI) != 0) {
		long /*int*/ list = 0;
		if (uriMode) {
			list = GTK.gtk_file_chooser_get_uris (handle);
		} else {
			list = GTK.gtk_file_chooser_get_filenames (handle);
		}
		int listLength = OS.g_slist_length (list);
		fileNames = new String [listLength];
		long /*int*/ current = list;
		int writePos = 0;
		for (int i = 0; i < listLength; i++) {
			long /*int*/ name = OS.g_slist_data (current);
			long /*int*/ utf8Ptr = 0;
			if (uriMode) {
				utf8Ptr = name;
			} else {
				utf8Ptr = OS.g_filename_to_utf8 (name, -1, null, null, null);
				if (utf8Ptr == 0) utf8Ptr = OS.g_filename_display_name (name);
			}
			if (name != utf8Ptr) OS.g_free (name);
			if (utf8Ptr != 0) {
				long /*int*/ [] items_written = new long /*int*/ [1];
				long /*int*/ utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
				OS.g_free (utf8Ptr);
				if (utf16Ptr != 0) {
					int clength = (int)/*64*/items_written [0];
					char [] chars = new char [clength];
					C.memmove (chars, utf16Ptr, clength * 2);
					OS.g_free (utf16Ptr);
					fullPath = new String (chars);
					fileNames [writePos++] = fullPath.substring (fullPath.lastIndexOf (SEPARATOR) + 1);
				}
			}
			current = OS.g_slist_next (current);
		}
		if (writePos != 0 && writePos != listLength) {
			String [] validFileNames = new String [writePos];
			System.arraycopy (fileNames, 0, validFileNames, 0, writePos);
			fileNames = validFileNames;
		}
		OS.g_slist_free (list);
	} else {
		long /*int*/ utf8Ptr = 0;
		if (uriMode) {
			utf8Ptr = GTK.gtk_file_chooser_get_uri (handle);
		} else {
			long /*int*/ path = GTK.gtk_file_chooser_get_filename (handle);
			if (path != 0) {
				utf8Ptr = OS.g_filename_to_utf8 (path, -1, null, null, null);
				if (utf8Ptr == 0) utf8Ptr = OS.g_filename_display_name (path);
				if (path != utf8Ptr) OS.g_free (path);
			}
		}
		if (utf8Ptr != 0) {
			long /*int*/ [] items_written = new long /*int*/ [1];
			long /*int*/ utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
			OS.g_free (utf8Ptr);
			if (utf16Ptr != 0) {
				int clength = (int)/*64*/items_written [0];
				char [] chars = new char [clength];
				C.memmove (chars, utf16Ptr, clength * 2);
				OS.g_free (utf16Ptr);
				fullPath = new String (chars);
				fileNames = new String [1];
				fileNames[0] = fullPath.substring (fullPath.lastIndexOf (SEPARATOR) + 1);
			}
		}
	}
	filterIndex = -1;
	long /*int*/ filter = GTK.gtk_file_chooser_get_filter (handle);
	if (filter != 0) {
		long /*int*/ filterNamePtr = GTK.gtk_file_filter_get_name (filter);
		if (filterNamePtr != 0) {
			int length = C.strlen (filterNamePtr);
			byte[] buffer = new byte [length];
			C.memmove (buffer, filterNamePtr, length);
			//OS.g_free (filterNamePtr); //GTK owns this pointer - do not free
			String filterName = new String (Converter.mbcsToWcs (buffer));
			for (int i = 0; i < filterExtensions.length; i++) {
				if (filterNames.length > 0) {
					if (filterNames[i].equals(filterName)) {
						filterIndex = i;
						break;
					}
				} else {
					if (filterExtensions[i].equals(filterName)) {
						filterIndex = i;
						break;
					}
				}
			}
		}
	}
	if (fullPath != null) {
		int separatorIndex = fullPath.lastIndexOf (SEPARATOR);
		fileName = fullPath.substring (separatorIndex + 1);
		filterPath = fullPath.substring (0, separatorIndex);
	}
	return fullPath;
}

/**
 * Returns the path of the first file that was
 * selected in the dialog relative to the filter path, or an
 * empty string if no such file has been selected.
 *
 * @return the relative path of the file
 */
public String getFileName () {
	return fileName;
}
/**
 * Returns a (possibly empty) array with the paths of all files
 * that were selected in the dialog relative to the filter path.
 *
 * @return the relative paths of the files
 */
public String [] getFileNames () {
	return fileNames;
}
/**
 * Returns the file extensions which the dialog will
 * use to filter the files it shows.
 *
 * @return the file extensions filter
 */
public String [] getFilterExtensions () {
	return filterExtensions;
}
/**
 * Get the 0-based index of the file extension filter
 * which was selected by the user, or -1 if no filter
 * was selected.
 * <p>
 * This is an index into the FilterExtensions array and
 * the FilterNames array.
 * </p>
 *
 * @return index the file extension filter index
 *
 * @see #getFilterExtensions
 * @see #getFilterNames
 *
 * @since 3.4
 */
public int getFilterIndex () {
	return filterIndex;
}
/**
 * Returns the names that describe the filter extensions
 * which the dialog will use to filter the files it shows.
 *
 * @return the list of filter names
 */
public String [] getFilterNames () {
	return filterNames;
}
/**
 * Returns the directory path that the dialog will use, or an empty
 * string if this is not set.  File names in this path will appear
 * in the dialog, filtered according to the filter extensions.
 *
 * @return the directory path string
 *
 * @see #setFilterExtensions
 */
public String getFilterPath () {
	return filterPath;
}
/**
 * Returns the flag that the dialog will use to
 * determine whether to prompt the user for file
 * overwrite if the selected file already exists.
 *
 * @return true if the dialog will prompt for file overwrite, false otherwise
 *
 * @since 3.4
 */
public boolean getOverwrite () {
	return overwrite;
}
/**
 * Makes the dialog visible and brings it to the front
 * of the display.
 *
 * @return a string describing the absolute path of the first selected file,
 *         or null if the dialog was cancelled or an error occurred
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
 * </ul>
 */
public String open () {
		return openChooserDialog ();
}
String openChooserDialog () {
	byte [] titleBytes = Converter.wcsToMbcs (title, true);
	int action = (style & SWT.SAVE) != 0 ?
		GTK.GTK_FILE_CHOOSER_ACTION_SAVE :
		GTK.GTK_FILE_CHOOSER_ACTION_OPEN;
	long /*int*/ shellHandle = parent.topHandle ();
	Display display = parent != null ? parent.getDisplay (): Display.getCurrent ();
	if (display.getDismissalAlignment() == SWT.RIGHT) {
		handle = GTK.gtk_file_chooser_dialog_new (titleBytes, shellHandle, action, GTK.GTK_NAMED_LABEL_CANCEL, GTK.GTK_RESPONSE_CANCEL, GTK.GTK_NAMED_LABEL_OK, GTK.GTK_RESPONSE_OK, 0);
	} else {
		handle = GTK.gtk_file_chooser_dialog_new (titleBytes, shellHandle, action, GTK.GTK_NAMED_LABEL_OK, GTK.GTK_RESPONSE_OK, GTK.GTK_NAMED_LABEL_CANCEL, GTK.GTK_RESPONSE_CANCEL, 0);
	}
	if (handle == 0) error (SWT.ERROR_NO_HANDLES);
	GTK.gtk_window_set_modal (handle, true);
	long /*int*/ group = GTK.gtk_window_get_group(0);
	GTK.gtk_window_group_add_window (group, handle);
	long /*int*/ pixbufs = GTK.gtk_window_get_icon_list (shellHandle);
	if (pixbufs != 0) {
		GTK.gtk_window_set_icon_list (handle, pixbufs);
		OS.g_list_free (pixbufs);
	}
	if (uriMode) {
		GTK.gtk_file_chooser_set_local_only (handle, false);
	}
	presetChooserDialog ();
	display.addIdleProc ();
	String answer = null;
	Dialog oldModal = null;
	if (GTK.gtk_window_get_modal (handle)) {
		oldModal = display.getModalDialog ();
		display.setModalDialog (this);
	}
	int signalId = 0;
	long /*int*/ hookId = 0;
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		signalId = OS.g_signal_lookup (OS.map, GTK.GTK_TYPE_WIDGET());
		hookId = OS.g_signal_add_emission_hook (signalId, 0, display.emissionProc, handle, 0);
	}
	display.sendPreExternalEventDispatchEvent ();
	int response = GTK.gtk_dialog_run (handle);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	GDK.gdk_threads_leave();
	display.sendPostExternalEventDispatchEvent ();
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		OS.g_signal_remove_emission_hook (signalId, hookId);
	}
	if (GTK.gtk_window_get_modal (handle)) {
		display.setModalDialog (oldModal);
	}
	if (response == GTK.GTK_RESPONSE_OK) {
		answer = computeResultChooserDialog ();
	}
	display.removeIdleProc ();
	GTK.gtk_widget_destroy (handle);
	return answer;
}
void presetChooserDialog () {
	/* MULTI is only valid if the native dialog's action is Open */
	if ((style & (SWT.SAVE | SWT.MULTI)) == SWT.MULTI) {
		GTK.gtk_file_chooser_set_select_multiple (handle, true);
	}
	if (filterPath == null) filterPath = "";
	if (fileName == null) fileName = "";
	if ((style & SWT.SAVE) != 0) {
		if (fileName.equals ("")) {
			fileName = "Untitled";
		}
		if (filterPath.length () > 0) {
			if (uriMode) {
				byte [] buffer = Converter.wcsToMbcs (filterPath, true);
				GTK.gtk_file_chooser_set_current_folder_uri (handle, buffer);
			} else {
				/* filename must be a full path */
				byte [] buffer = Converter.wcsToMbcs (SEPARATOR + filterPath, true);
				/*
				 * in GTK version 2.10, gtk_file_chooser_set_current_folder requires path
				 * to be true canonical path. So using realpath to convert the path to
				 * true canonical path.
				 */
				if (OS.IsAIX) {
					byte [] outputBuffer = new byte [PATH_MAX];
					long /*int*/ ptr = OS.realpath (buffer, outputBuffer);
					if (ptr != 0) {
						GTK.gtk_file_chooser_set_current_folder (handle, ptr);
					}
					/* We are not doing free here because realpath returns the address of outputBuffer
					 * which is created in this code and we let the garbage collector to take care of this
					 */
				} else {
					long /*int*/ ptr = OS.realpath (buffer, null);
					if (ptr != 0) {
						GTK.gtk_file_chooser_set_current_folder (handle, ptr);
						OS.g_free (ptr);
					}
				}
			}
		}
		if (fileName.length () > 0) {
			StringBuilder filenameWithExt = new StringBuilder();
			filenameWithExt.append (fileName);
			if ((fileName.lastIndexOf (FILE_EXTENSION_SEPARATOR) == -1) &&
					(filterExtensions.length != 0)) {  // Filename doesn't contain the extension and user has provided filter extensions
				String selectedFilter = null;
				if (this.filterIndex == -1) {
					selectedFilter = filterExtensions[0];
				} else {
					selectedFilter = filterExtensions[filterIndex];
				}
				String extFilter = null;
				int index = selectedFilter.indexOf (EXTENSION_SEPARATOR);
				if (index == -1) {
					extFilter = selectedFilter.trim ();
				} else {
					extFilter = selectedFilter.substring (0, index).trim ();
				}

				int separatorIndex = extFilter.lastIndexOf (FILE_EXTENSION_SEPARATOR);
				String extension = extFilter.substring (separatorIndex);

				if (!isGlobPattern (extension)) { //if the extension is of type glob pattern we should not add the extension
					filenameWithExt.append (extension);
				}
			}
			byte [] buffer = Converter.wcsToMbcs (filenameWithExt.toString (), true);
			GTK.gtk_file_chooser_set_current_name (handle, buffer);
		}
	} else {
		StringBuilder stringBuilder = new StringBuilder();
		if (filterPath.length () > 0) {
			if (!uriMode) {
				/* filename must be a full path */
				stringBuilder.append(SEPARATOR);
			}
			stringBuilder.append(filterPath);
			stringBuilder.append(SEPARATOR);
		}
		if (fileName.length () > 0) {
			stringBuilder.append(fileName);
		}
		byte [] buffer = Converter.wcsToMbcs (stringBuilder.toString(), true);
		if (uriMode) {
			GTK.gtk_file_chooser_set_uri (handle, buffer);
		} else {
			/*
			 * in GTK version 2.10, gtk_file_chooser_set_current_folder requires path
			 * to be true canonical path. So using realpath to convert the path to
			 * true canonical path.
			 */
			if (OS.IsAIX) {
				byte [] outputBuffer = new byte [PATH_MAX];
				long /*int*/ ptr = OS.realpath (buffer, outputBuffer);
				if (ptr != 0) {
					if (fileName.length() > 0) {
						GTK.gtk_file_chooser_set_filename (handle, ptr);
					} else {
						GTK.gtk_file_chooser_set_current_folder (handle, ptr);
					}
					/* We are not doing free here because realpath returns the address of outputBuffer
					 * which is created in this code and we let the garbage collector to take care of this
					 */
				}
			} else {
				long /*int*/ ptr = OS.realpath (buffer, null);
				if (ptr != 0) {
					if (fileName.length() > 0) {
						GTK.gtk_file_chooser_set_filename (handle, ptr);
					} else {
						GTK.gtk_file_chooser_set_current_folder (handle, ptr);
					}
					OS.g_free (ptr);
				}
			}
		}
	}

	/* Set overwrite mode */
	if ((style & SWT.SAVE) != 0) {
		GTK.gtk_file_chooser_set_do_overwrite_confirmation (handle, overwrite);
	}

	/* Set the extension filters */
	if (filterNames == null) filterNames = new String [0];
	if (filterExtensions == null) filterExtensions = new String [0];
	long /*int*/ initialFilter = 0;
	for (int i = 0; i < filterExtensions.length; i++) {
		if (filterExtensions [i] != null) {
			long /*int*/ filter = GTK.gtk_file_filter_new ();
			if (filterNames.length > i && filterNames [i] != null) {
				byte [] name = Converter.wcsToMbcs (filterNames [i], true);
				GTK.gtk_file_filter_set_name (filter, name);
			} else {
				byte [] name = Converter.wcsToMbcs (filterExtensions [i], true);
				GTK.gtk_file_filter_set_name (filter, name);
			}
			int start = 0;
			int index = filterExtensions [i].indexOf (EXTENSION_SEPARATOR);
			while (index != -1) {
				String current = filterExtensions [i].substring (start, index);
				byte [] filterString = Converter.wcsToMbcs (current, true);
				GTK.gtk_file_filter_add_pattern (filter, filterString);
				start = index + 1;
				index = filterExtensions [i].indexOf (EXTENSION_SEPARATOR, start);
			}
			String current = filterExtensions [i].substring (start);
			byte [] filterString = Converter.wcsToMbcs (current, true);
			GTK.gtk_file_filter_add_pattern (filter, filterString);
			GTK.gtk_file_chooser_add_filter (handle, filter);
			if (i == filterIndex) {
				initialFilter = filter;
			}
		}
	}
	if (initialFilter != 0) {
		GTK.gtk_file_chooser_set_filter(handle, initialFilter);
	}
	fullPath = null;
	fileNames = new String [0];
}
/**
 * Check whether the file extension is a glob pattern.
 * For example, *.* is a glob pattern which corresponds to all files
 * *.jp* corresponds to all the files with extension starting with jp like jpg,jpeg etc
 * *.jp? corresponds to 3 letter extension starting with jp with any 3rd letter
 * *.[pq]ng this corresponds to *.png and *.qng
 *
 * @param extension file extension as a string
 *
 * @returns true if the extension contains any of the glob pattern wildcards
 */
private boolean isGlobPattern (String extension) {
	if (extension.contains ("*") ||
			extension.contains ("?") ||
			(extension.contains ("[") && extension.contains ("]"))) {
		return true;
	}
	return false;
}
/**
 * Set the initial filename which the dialog will
 * select by default when opened to the argument,
 * which may be null.  The name will be prefixed with
 * the filter path when one is supplied.
 *
 * @param string the file name
 */
public void setFileName (String string) {
	fileName = string;
}
/**
 * Set the file extensions which the dialog will
 * use to filter the files it shows to the argument,
 * which may be null.
 * <p>
 * The strings are platform specific. For example, on
 * some platforms, an extension filter string is typically
 * of the form "*.extension", where "*.*" matches all files.
 * For filters with multiple extensions, use semicolon as
 * a separator, e.g. "*.jpg;*.png".
 * </p>
 * <p>
 * Note: On Mac, setting the file extension filter affects how
 * app bundles are treated by the dialog. When a filter extension
 * having the app extension (.app) is selected, bundles are treated
 * as files. For all other extension filters, bundles are treated
 * as directories. When no filter extension is set, bundles are
 * treated as files.
 * </p>
 *
 * @param extensions the file extension filter
 *
 * @see #setFilterNames to specify the user-friendly
 * names corresponding to the extensions
 */
public void setFilterExtensions (String [] extensions) {
	filterExtensions = extensions;
}
/**
 * Set the 0-based index of the file extension filter
 * which the dialog will use initially to filter the files
 * it shows to the argument.
 * <p>
 * This is an index into the FilterExtensions array and
 * the FilterNames array.
 * </p>
 *
 * @param index the file extension filter index
 *
 * @see #setFilterExtensions
 * @see #setFilterNames
 *
 * @since 3.4
 */
public void setFilterIndex (int index) {
	filterIndex = index;
}
/**
 * Sets the names that describe the filter extensions
 * which the dialog will use to filter the files it shows
 * to the argument, which may be null.
 * <p>
 * Each name is a user-friendly short description shown for
 * its corresponding filter. The <code>names</code> array must
 * be the same length as the <code>extensions</code> array.
 * </p>
 *
 * @param names the list of filter names, or null for no filter names
 *
 * @see #setFilterExtensions
 */
public void setFilterNames (String [] names) {
	filterNames = names;
}
/**
 * Sets the directory path that the dialog will use
 * to the argument, which may be null. File names in this
 * path will appear in the dialog, filtered according
 * to the filter extensions. If the string is null,
 * then the operating system's default filter path
 * will be used.
 * <p>
 * Note that the path string is platform dependent.
 * For convenience, either '/' or '\' can be used
 * as a path separator.
 * </p>
 *
 * @param string the directory path
 *
 * @see #setFilterExtensions
 */
public void setFilterPath (String string) {
	filterPath = string;
}

/**
 * Sets the flag that the dialog will use to
 * determine whether to prompt the user for file
 * overwrite if the selected file already exists.
 *
 * @param overwrite true if the dialog will prompt for file overwrite, false otherwise
 *
 * @since 3.4
 */
public void setOverwrite (boolean overwrite) {
	this.overwrite = overwrite;
}
/* Sets URI Mode.
 *
 * When the FileDialog is in URI mode it returns
 * a URI (instead of a file name) for the following
 * methods: open() and getFilterPath().
 * The input argment for setFilterPath() should also
 * be a URI.
 */
/*public*/ void setURIMode (boolean uriMode) {
	this.uriMode = uriMode;
}
}
