package speiger.src.coreengine.utils.io.finders;

import java.io.File;

import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.util.nfd.NFDFilterItem;
import org.lwjgl.util.nfd.NativeFileDialog;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.sets.ObjectOrderedSet;

public class NativeFileFinder implements IFileFinder {
	public static final IFileFinder INSTANCE = new NativeFileFinder();
	
	@Override
	public ObjectList<File> build(int flags, String startPath, ObjectOrderedSet<String> validFormats, String description) {
		ObjectList<File> files = new ObjectArrayList<>();
		if((flags & SAVE) != 0) {
			try(MemoryStack stack = MemoryStack.stackPush()) {
				PointerBuffer output = stack.mallocPointer(1);
				if(NativeFileDialog.NFD_SaveDialog(output, toFileFormat(stack, validFormats, description), startPath, "") == NativeFileDialog.NFD_OKAY) {
					File file = new File(output.getStringUTF8());
					if(file.getName().lastIndexOf(".") == -1) file = new File(file.getParent(), file.getName()+"."+validFormats.getFirst());
					files.add(file);
				}
			}
		}
		else if((flags & FOLDER) != 0) {
			try(MemoryStack stack = MemoryStack.stackPush()) {
				PointerBuffer output = stack.mallocPointer(1);
				if(NativeFileDialog.NFD_PickFolder(output, startPath) == NativeFileDialog.NFD_OKAY) files.add(new File(output.getStringUTF8()));
			}
		}
		else if((flags & MULTI_FILE) != 0) {
			try(MemoryStack stack = MemoryStack.stackPush()) {
				PointerBuffer result = stack.mallocPointer(1);
				if(NativeFileDialog.NFD_OpenDialogMultiple(result, toFileFormat(stack, validFormats, description), startPath) == NativeFileDialog.NFD_OKAY) {
					int[] size = new int[1];
					long address = result.address();
					if(NativeFileDialog.NFD_PathSet_GetCount(address, size) != NativeFileDialog.NFD_OKAY) {
						for(int i = 0,m = size[0];i < m;i++) {
							PointerBuffer output = stack.mallocPointer(1);
							if(NativeFileDialog.NFD_PathSet_GetPath(address, i, output) != NativeFileDialog.NFD_OKAY) continue;
							files.add(new File(output.getStringUTF8()));
						}
					}
				}
			}
		}
		else {
			try(MemoryStack stack = MemoryStack.stackPush()) {
				PointerBuffer output = stack.mallocPointer(1);
				if(NativeFileDialog.NFD_OpenDialog(output, toFileFormat(stack, validFormats, description), startPath) == NativeFileDialog.NFD_OKAY) files.add(new File(output.getStringUTF8()));
			}
		}
		return files;
	}
	
	private NFDFilterItem.Buffer toFileFormat(MemoryStack stack, ObjectOrderedSet<String> validFormats, String name) {
		NFDFilterItem.Buffer buffer = NFDFilterItem.malloc(1, stack);
		buffer.put(NFDFilterItem.malloc(stack).name(stack.UTF8(name)).spec(stack.UTF8(toFileFormat(validFormats))));
		return buffer;
	}
}
