/*******************************************************************************
 * Copyright (c) 2000, 2019 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.*;
import org.eclipse.swt.internal.gtk3.*;
import org.eclipse.swt.internal.gtk4.*;

/**
 * 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 handle;
	static final char SEPARATOR = File.separatorChar;
	static final char EXTENSION_SEPARATOR = ';';
	static final char FILE_EXTENSION_SEPARATOR = '.';

/**
 * 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 list = 0;
		if (GTK.GTK4) {
			list = GTK4.gtk_file_chooser_get_files(handle);
		} else {
			if (uriMode) {
				list = GTK3.gtk_file_chooser_get_uris (handle);
			} else {
				list = GTK3.gtk_file_chooser_get_filenames (handle);
			}
		}

		int listLength = OS.g_slist_length (list);
		fileNames = new String [listLength];
		long current = list;
		int writePos = 0;
		for (int i = 0; i < listLength; i++) {
			long name = OS.g_slist_data (current);
			long utf8Ptr = 0;
			if (uriMode) {
				if (GTK.GTK4) {
					utf8Ptr = OS.g_file_get_uri(name);
				} else {
					utf8Ptr = name;
				}
			} else {
				if (GTK.GTK4) {
					name = OS.g_file_get_path(name);
				}

				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 [] items_written = new long [1];
				long utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
				OS.g_free (utf8Ptr);
				if (utf16Ptr != 0) {
					int clength = (int)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 utf8Ptr = 0;
		if (uriMode) {
			if (GTK.GTK4) {
				long file = GTK4.gtk_file_chooser_get_file(handle);
				utf8Ptr = OS.g_file_get_uri(file);
			} else {
				utf8Ptr = GTK3.gtk_file_chooser_get_uri (handle);
			}
		} else {
			long path;
			if (GTK.GTK4) {
				long file = GTK4.gtk_file_chooser_get_file(handle);
				path = OS.g_file_get_path(file);
			} else {
				path = GTK3.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 [] items_written = new long [1];
			long utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
			OS.g_free (utf8Ptr);
			if (utf16Ptr != 0) {
				int clength = (int)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 filter = GTK.gtk_file_chooser_get_filter (handle);
	if (filter != 0) {
		long 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 openNativeChooserDialog();
}
/**
 * Open the file chooser dialog using the GtkFileChooserNative API (GTK3.20+) for running applications
 * without direct filesystem access (such as Flatpak). API for GtkFileChoosernative does not
 * give access to any GtkWindow or GtkWidget for the dialog, thus this method omits calls that
 * requires such access. These are be handled by the GtkNativeDialog API.
 *
 * @return a string describing the absolute path of the first selected file, or null
 */
String openNativeChooserDialog () {
	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 shellHandle = parent.topHandle();
	Display display = parent != null ? parent.getDisplay (): Display.getCurrent();
	handle = GTK.gtk_file_chooser_native_new(titleBytes, shellHandle, action, null, null);
	if (handle == 0) error (SWT.ERROR_NO_HANDLES);

	if (uriMode && !GTK.GTK4) {
		// GTK4 file chooser works on GFiles and does not need to worry about this
		GTK3.gtk_file_chooser_set_local_only (handle, false);
	}
	presetChooserDialog ();
	display.addIdleProc ();
	String answer = null;
	int signalId = 0;
	long 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);
	}

	int response;
	if (GTK.GTK4) {
		response = SyncDialogUtil.run(display, handle, true);
	} else {
		display.externalEventLoop = true;
		display.sendPreExternalEventDispatchEvent ();
		response = GTK.gtk_native_dialog_run(handle);
		display.externalEventLoop = false;
		display.sendPostExternalEventDispatchEvent ();
	}

	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		OS.g_signal_remove_emission_hook (signalId, hookId);
	}
	if (response == GTK.GTK_RESPONSE_ACCEPT) {
		answer = computeResultChooserDialog ();
	}
	display.removeIdleProc ();
	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);

				if (GTK.GTK4) {
					long file = OS.g_file_new_for_uri(buffer);
					GTK4.gtk_file_chooser_set_current_folder (handle, file, 0);
					OS.g_object_unref(file);
				} else {
					GTK3.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.
				 */
				long ptr = OS.realpath (buffer, null);
				if (ptr != 0) {
					if (GTK.GTK4) {
						long file = OS.g_file_new_for_path(buffer);
						GTK4.gtk_file_chooser_set_current_folder (handle, file, 0);
						OS.g_object_unref(file);
					} else {
						GTK3.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 (GTK.GTK4) {
			long file;
			if (uriMode) {
				file = OS.g_file_new_for_uri(buffer);
				GTK4.gtk_file_chooser_set_file (handle, file, 0);
			} else {
				file = OS.g_file_new_for_path(buffer);

				if (fileName.length() > 0) {
					GTK4.gtk_file_chooser_set_file (handle, file, 0);
				} else {
					GTK4.gtk_file_chooser_set_current_folder (handle, file, 0);
				}
			}

			OS.g_object_unref(file);
		} else {
			if (uriMode) {
				GTK3.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.
				 */
				long ptr = OS.realpath (buffer, null);
				if (ptr != 0) {
					if (fileName.length() > 0) {
						GTK3.gtk_file_chooser_set_filename (handle, ptr);
					} else {
						GTK3.gtk_file_chooser_set_current_folder (handle, ptr);
					}
					OS.g_free (ptr);
				}
			}
		}
	}

	/* Set overwrite mode */
	if ((style & SWT.SAVE) != 0) {
		if (GTK.GTK4) {
			// TODO: GTK4 does not this property for the file chooser, not sure what the default behavior is. Must test before trying an alternative.
		} else {
			GTK3.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 initialFilter = 0;
	for (int i = 0; i < filterExtensions.length; i++) {
		if (filterExtensions [i] != null) {
			long 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.
 * <p>
 * Note: On some platforms where suppressing the overwrite prompt
 * is not supported, the prompt is shown even when invoked with
 * overwrite false.
 * </p>
 *
 * @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;
}
}
