/*
 * Copyright LWJGL. All rights reserved.
 * License terms: http://lwjgl.org/license.php
 */
package org.lwjgl.demo.nfd;

import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.nfd.NFDPathSet;
import org.lwjgl.opengl.GL;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.nfd.NativeFileDialog.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;

public final class HelloNFD {

	private HelloNFD() {
	}

	public static void main(String[] args) {
		GLFWErrorCallback errorfun = GLFWErrorCallback.createPrint();
		GLFWKeyCallback keyfun = new GLFWKeyCallback() {
			@Override
			public void invoke(long window, int key, int scancode, int action, int mods) {
				if ( action == GLFW_RELEASE )
					return;

				switch ( key ) {
					case GLFW_KEY_ESCAPE:
						glfwSetWindowShouldClose(window, GLFW_TRUE);
						break;
					case GLFW_KEY_O:
						if ( (mods & GLFW_MOD_CONTROL) != 0 ) {
							if ( (mods & GLFW_MOD_SHIFT) != 0 )
								openMulti();
							else
								openSingle();
						}
						break;
					case GLFW_KEY_S:
						if ( (mods & GLFW_MOD_CONTROL) != 0 )
							save();
						break;
				}
			}
		};

		errorfun.set();
		if ( glfwInit() != GLFW_TRUE )
			throw new IllegalStateException("Unable to initialize GLFW");

		long window = glfwCreateWindow(300, 300, "Hello NativeFileDialog!", NULL, NULL);
		if ( window == NULL )
			throw new RuntimeException("Failed to create the GLFW window");

		keyfun.set(window);

		// Center window
		GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
		glfwSetWindowPos(
			window,
			(vidmode.width() - 300) / 2,
			(vidmode.height() - 300) / 2
		);

		glfwMakeContextCurrent(window);
		GL.createCapabilities();

		glfwSwapInterval(1);

		System.out.println("Press Ctrl+O to launch the single file open dialog.");
		System.out.println("Press Ctrl+Shift+O to launch the multi file open dialog.");
		System.out.println("Press Ctrl+S to launch the file save dialog.");
		while ( glfwWindowShouldClose(window) == GLFW_FALSE ) {
			glfwPollEvents();

			glClear(GL_COLOR_BUFFER_BIT);
			glfwSwapBuffers(window);
		}

		glfwDestroyWindow(window);

		glfwTerminate();

		keyfun.release();
		errorfun.release();
	}

	private static void openSingle() {
		PointerBuffer outPath = memAllocPointer(1);

		try {
			int result = NFD_OpenDialog("png,jpg;pdf", null, outPath);
			switch ( result ) {
				case NFD_OKAY:
					System.out.println("Success!");
					System.out.println(outPath.getStringUTF8(0));
					nNFD_Free(outPath.get(0));
					break;
				case NFD_CANCEL:
					System.out.println("User pressed cancel.");
					break;
				default: // NFD_ERROR
					System.err.format("Error: %s\n", NFD_GetError());
			}
		} finally {
			memFree(outPath);
		}
	}

	private static void openMulti() {
		NFDPathSet pathSet = NFDPathSet.calloc();

		try {
			int result = NFD_OpenDialogMultiple("png,jpg;pdf", null, pathSet);
			switch ( result ) {
				case NFD_OKAY:
					long count = NFD_PathSet_GetCount(pathSet);
					for ( long i = 0; i < count; i++ ) {
						String path = NFD_PathSet_GetPath(pathSet, i);
						System.out.format("Path %d: %s\n", i, path);
					}
					NFD_PathSet_Free(pathSet);
					break;
				case NFD_CANCEL:
					System.out.println("User pressed cancel.");
					break;
				default: // NFD_ERROR
					System.err.format("Error: %s\n", NFD_GetError());
			}
		} finally {
			pathSet.free();
		}
	}

	private static void save() {
		PointerBuffer savePath = memAllocPointer(1);

		try {
			int result = NFD_SaveDialog("png,jpg;pdf", null, savePath);
			switch ( result ) {
				case NFD_OKAY:
					System.out.println("Success!");
					System.out.println(savePath.getStringUTF8(0));
					nNFD_Free(savePath.get(0));
					break;
				case NFD_CANCEL:
					System.out.println("User pressed cancel.");
					break;
				default: // NFD_ERROR
					System.err.format("Error: %s\n", NFD_GetError());
			}
		} finally {
			memFree(savePath);
		}
	}

}
@@ -324,16 +324,50 @@
 engl.GL;
+%0Aimport org.lwjgl.system.Platform;
 %0A%0Aimport
@@ -629,16 +629,214 @@
 args) %7B%0A
+%09%09final int mod;%0A%09%09final String modDescr;%0A%09%09if ( Platform.get() == Platform.MACOSX ) %7B%0A%09%09%09mod = GLFW_MOD_SUPER;%0A%09%09%09modDescr = %22Cmd%22;%0A%09%09%7D else %7B%0A%09%09%09mod = GLFW_MOD_CONTROL;%0A%09%09%09modDescr = %22Ctrl%22;%0A%09%09%7D%0A%0A
 %09%09GLFWEr
@@ -1238,32 +1238,19 @@
 (mods & 
-GLFW_MOD_CONTROL
+mod
 ) != 0 )
@@ -1412,32 +1412,19 @@
 (mods & 
-GLFW_MOD_CONTROL
+mod
 ) != 0 )
@@ -2085,20 +2085,32 @@
 (%22Press 
-Ctrl
+%22 + modDescr + %22
 +O to la
@@ -2174,20 +2174,32 @@
 (%22Press 
-Ctrl
+%22 + modDescr + %22
 +Shift+O
@@ -2268,20 +2268,32 @@
 (%22Press 
-Ctrl
+%22 + modDescr + %22
 +S to la

Use cmd on OSX