// Path: src/com/ganggarrison/gmdec/DeferredReferenceCreatorNotifier.java
// public class DeferredReferenceCreatorNotifier {
// 	private Set<DeferredReferenceCreator> drcSet = new HashSet<DeferredReferenceCreator>();
// 
// 	public void addDeferredReferenceCreator(DeferredReferenceCreator drc) {
// 		drcSet.add(drc);
// 	}
// 
// 	public void createReferences(GmFile gmf) {
// 		for (DeferredReferenceCreator drc : drcSet) {
// 			drc.createReferences(gmf);
// 		}
// 	}
// }
// 
// Path: src/com/ganggarrison/gmdec/FileTools.java
// public class FileTools {
// 	public static void writeFile(File file, String content) throws IOException {
// 		writeFile(file, content.getBytes("UTF-8"));
// 	}
// 
// 	public static void writeFile(File file, byte[] content) throws IOException {
// 		// Never overwrite
// 		if (file.exists()) {
// 			throw new IOException("File " + file + " already exists.");
// 		}
// 
// 		FileOutputStream fos = null;
// 		DataOutputStream dos = null;
// 
// 		try {
// 			fos = new FileOutputStream(file);
// 			dos = new DataOutputStream(fos);
// 			dos.write(content);
// 		} finally {
// 			tryToClose(fos);
// 			tryToClose(dos);
// 		}
// 	}
// 
// 	/**
// 	 * Modify the given String so that it can be used as part of a filename
// 	 * without causing problems from illegal/special characters.
// 	 * 
// 	 * The result should be similar to the input, but isn't necessarily
// 	 * reversible. The implementation might change in the future, so don't rely
// 	 * on the output staying the same.
// 	 */
// 	public static String replaceBadChars(String name) {
// 		if (name == null || name.trim().isEmpty())
// 			return "_";
// 		name = name.trim();
// 		for (String badChar : badChars) {
// 			name = name.replace(badChar, "_");
// 		}
// 		return name;
// 	}
// 
// 	public static boolean isGoodFilename(String name) {
// 		if (name == null || name.trim().isEmpty())
// 			return false;
// 		if (!name.trim().equals(name)) {
// 			return false;
// 		}
// 		for (String s : badChars) {
// 			if (name.contains(s))
// 				return false;
// 		}
// 		return true;
// 	}
// 
// 	private static final String[] badChars = new String[] { "/", "\\", ":", "*", "?", "\"", "<", ">", "|", ".", "\0" };
// 
// 	public static String readFileAsString(File file) throws IOException {
// 		return new String(readWholeFileBytes(file), "UTF-8");
// 	}
// 
// 	public static byte[] readWholeFileBytes(File file) throws IOException {
// 		FileInputStream fis = null;
// 		DataInputStream dis = null;
// 		try {
// 			fis = new FileInputStream(file);
// 			dis = new DataInputStream(fis);
// 			byte[] buffer = new byte[(int) file.length()];
// 			dis.readFully(buffer);
// 
// 			return buffer;
// 		} finally {
// 			tryToClose(fis);
// 			tryToClose(dis);
// 		}
// 	}
// 
// 	private static void tryToClose(Closeable stream) {
// 		if (stream != null) {
// 			try {
// 				stream.close();
// 			} catch (IOException e) {
// 			}
// 		}
// 	}
// }
// 
// Path: src/com/ganggarrison/gmdec/ResourceTreeEntry.java
// public class ResourceTreeEntry {
// 	public String name;
// 	public String filename;
// 	public Type type;
// 
// 	public ResourceTreeEntry(String name, String filename, Type type) {
// 		this.name = name;
// 		this.filename = filename;
// 		this.type = type;
// 	}
// 
// 	public ResourceTreeEntry() {
// 	}
// 
// 	public String getFilename() {
// 		String result;
// 		if (filename != null && !filename.isEmpty()) {
// 			result = filename;
// 		} else {
// 			result = name;
// 		}
// 		if (FileTools.isGoodFilename(result)) {
// 			return result;
// 		} else {
// 			throw new IllegalStateException("Bad filename in resource list: " + result);
// 		}
// 	}
// 
// 	public static enum Type {
// 		RESOURCE, GROUP
// 	}
// }


import java.io.File;
import java.io.IOException;
import java.util.List;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.file.GmFile;
import org.lateralgm.resources.Resource;
import com.ganggarrison.gmdec.DeferredReferenceCreatorNotifier;
import com.ganggarrison.gmdec.FileTools;
import com.ganggarrison.gmdec.ResourceTreeEntry;
/*
 * Copyright (C) 2010 Medo <smaxein@googlemail.com>
 * 
 * This file is part of GmkSplitter.
 * GmkSplitter is free software and comes with ABSOLUTELY NO WARRANTY.
 * See LICENSE for details.
 */
package com.ganggarrison.gmdec.files;




public abstract class FileTreeFormat<T> {
	public abstract void write(File path, T resource, GmFile gmf) throws IOException;

	/**
	 * Add a resource into the resource tree.
	 * 
	 * @param resource
	 *            A resource read by this format
	 * @param parent
	 *            The parent node for this resource
	 */
	public abstract void addResToTree(T resource, ResNode parent);

	/**
	 * Add all resources of the type read by this format into the GmFile. This
	 * method must be called with all resources of that type that should go into
	 * the GmFile, so that ID conflicts can be properly resolved.
	 */
	public abstract void addAllResourcesToGmFile(List<T> resources, GmFile gmf);

// Path: src/com/ganggarrison/gmdec/DeferredReferenceCreatorNotifier.java
// public class DeferredReferenceCreatorNotifier {
// 	private Set<DeferredReferenceCreator> drcSet = new HashSet<DeferredReferenceCreator>();
// 
// 	public void addDeferredReferenceCreator(DeferredReferenceCreator drc) {
// 		drcSet.add(drc);
// 	}
// 
// 	public void createReferences(GmFile gmf) {
// 		for (DeferredReferenceCreator drc : drcSet) {
// 			drc.createReferences(gmf);
// 		}
// 	}
// }
// 
// Path: src/com/ganggarrison/gmdec/FileTools.java
// public class FileTools {
// 	public static void writeFile(File file, String content) throws IOException {
// 		writeFile(file, content.getBytes("UTF-8"));
// 	}
// 
// 	public static void writeFile(File file, byte[] content) throws IOException {
// 		// Never overwrite
// 		if (file.exists()) {
// 			throw new IOException("File " + file + " already exists.");
// 		}
// 
// 		FileOutputStream fos = null;
// 		DataOutputStream dos = null;
// 
// 		try {
// 			fos = new FileOutputStream(file);
// 			dos = new DataOutputStream(fos);
// 			dos.write(content);
// 		} finally {
// 			tryToClose(fos);
// 			tryToClose(dos);
// 		}
// 	}
// 
// 	/**
// 	 * Modify the given String so that it can be used as part of a filename
// 	 * without causing problems from illegal/special characters.
// 	 * 
// 	 * The result should be similar to the input, but isn't necessarily
// 	 * reversible. The implementation might change in the future, so don't rely
// 	 * on the output staying the same.
// 	 */
// 	public static String replaceBadChars(String name) {
// 		if (name == null || name.trim().isEmpty())
// 			return "_";
// 		name = name.trim();
// 		for (String badChar : badChars) {
// 			name = name.replace(badChar, "_");
// 		}
// 		return name;
// 	}
// 
// 	public static boolean isGoodFilename(String name) {
// 		if (name == null || name.trim().isEmpty())
// 			return false;
// 		if (!name.trim().equals(name)) {
// 			return false;
// 		}
// 		for (String s : badChars) {
// 			if (name.contains(s))
// 				return false;
// 		}
// 		return true;
// 	}
// 
// 	private static final String[] badChars = new String[] { "/", "\\", ":", "*", "?", "\"", "<", ">", "|", ".", "\0" };
// 
// 	public static String readFileAsString(File file) throws IOException {
// 		return new String(readWholeFileBytes(file), "UTF-8");
// 	}
// 
// 	public static byte[] readWholeFileBytes(File file) throws IOException {
// 		FileInputStream fis = null;
// 		DataInputStream dis = null;
// 		try {
// 			fis = new FileInputStream(file);
// 			dis = new DataInputStream(fis);
// 			byte[] buffer = new byte[(int) file.length()];
// 			dis.readFully(buffer);
// 
// 			return buffer;
// 		} finally {
// 			tryToClose(fis);
// 			tryToClose(dis);
// 		}
// 	}
// 
// 	private static void tryToClose(Closeable stream) {
// 		if (stream != null) {
// 			try {
// 				stream.close();
// 			} catch (IOException e) {
// 			}
// 		}
// 	}
// }
// 
// Path: src/com/ganggarrison/gmdec/ResourceTreeEntry.java
// public class ResourceTreeEntry {
// 	public String name;
// 	public String filename;
// 	public Type type;
// 
// 	public ResourceTreeEntry(String name, String filename, Type type) {
// 		this.name = name;
// 		this.filename = filename;
// 		this.type = type;
// 	}
// 
// 	public ResourceTreeEntry() {
// 	}
// 
// 	public String getFilename() {
// 		String result;
// 		if (filename != null && !filename.isEmpty()) {
// 			result = filename;
// 		} else {
// 			result = name;
// 		}
// 		if (FileTools.isGoodFilename(result)) {
// 			return result;
// 		} else {
// 			throw new IllegalStateException("Bad filename in resource list: " + result);
// 		}
// 	}
// 
// 	public static enum Type {
// 		RESOURCE, GROUP
// 	}
// }


// Path: src/com/ganggarrison/gmdec/files/FileTreeFormat.java
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.file.GmFile;
import org.lateralgm.resources.Resource;
import com.ganggarrison.gmdec.DeferredReferenceCreatorNotifier;
import com.ganggarrison.gmdec.FileTools;
import com.ganggarrison.gmdec.ResourceTreeEntry;

/*
 * Copyright (C) 2010 Medo <smaxein@googlemail.com>
 * 
 * This file is part of GmkSplitter.
 * GmkSplitter is free software and comes with ABSOLUTELY NO WARRANTY.
 * See LICENSE for details.
 */
package com.ganggarrison.gmdec.files;




public abstract class FileTreeFormat<T> {
	public abstract void write(File path, T resource, GmFile gmf) throws IOException;

	/**
	 * Add a resource into the resource tree.
	 * 
	 * @param resource
	 *            A resource read by this format
	 * @param parent
	 *            The parent node for this resource
	 */
	public abstract void addResToTree(T resource, ResNode parent);

	/**
	 * Add all resources of the type read by this format into the GmFile. This
	 * method must be called with all resources of that type that should go into
	 * the GmFile, so that ID conflicts can be properly resolved.
	 */
	public abstract void addAllResourcesToGmFile(List<T> resources, GmFile gmf);

	public abstract T read(File path, ResourceTreeEntry entry, DeferredReferenceCreatorNotifier drcn)