/*
* 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;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.file.GmFile;
import org.lateralgm.file.ResourceList;
import org.lateralgm.resources.Extensions;
import org.lateralgm.resources.GameInformation;
import org.lateralgm.resources.GameSettings;
import org.lateralgm.resources.InstantiableResource;
import org.lateralgm.resources.Resource;
import com.ganggarrison.gmdec.ResourceTreeEntry.Type;
import com.ganggarrison.gmdec.files.ExtensionsFormat;
import com.ganggarrison.gmdec.files.GameInfoFormat;
import com.ganggarrison.gmdec.files.GameSettingsFormat;
import com.ganggarrison.gmdec.files.FileTreeFormat;
import com.ganggarrison.gmdec.files.ResourceFormat;
import com.ganggarrison.gmdec.xml.ResourceListXmlFormat;
public class ResourceWriter {
public static void writeTree(ResNode root, GmFile gmf, File startPath) throws IOException {
for (Class<?> resKind : gmf.resMap.keySet()) {
if (InstantiableResource.class.isAssignableFrom(resKind)) {
ResourceList<?> list = gmf.resMap.getList((Class) resKind);
if (list != null) {
ResourceFormat.checkDuplicateNames(list, resKind);
}
}
}
if (startPath.exists()) {
throw new IOException("Output folder already exists! Overwriting is not supported.");
}
int numChilds = root.getChildCount();
for (int i = 0; i < numChilds; i++) {
ResNode child = (ResNode) root.getChildAt(i);
if (child.status == ResNode.STATUS_PRIMARY) {
writeChildTree(startPath, child, gmf);
} else if (child.status == ResNode.STATUS_SECONDARY) {
if (GameInformation.class.equals(child.kind)) {
new GameInfoFormat().write(startPath, gmf.gameInfo, gmf);
} else if (Extensions.class.equals(child.kind)) {
new ExtensionsFormat().write(startPath, gmf.packages, gmf);
} else if (GameSettings.class.equals(child.kind)) {
new GameSettingsFormat().write(startPath, gmf.gameSettings, gmf);
} else {
throw new IOException("Unexpected secondary resource kind " + child.kind
+ " in first level of the tree.");
}
} else {
throw new IOException("Unexpected resource group \"" + child.getUserObject()
+ "\" in resource tree root.");
}
}
}
// TODO: create a subclass like in the Reader case to reduce parameter count
private static void writeChildTree(File startPath, ResNode child, GmFile gmf) throws IOException {
for (PrimaryResourceType type : PrimaryResourceType.values()) {
if (type.resourceKind.equals(child.kind)) {
writeTreeRecursive(child, new File(startPath, type.pathName), type, gmf);
return;
}
}
throw new IOException("Unknown primary resource group \"" + child.getUserObject() + "\"");
}
private static void writeTreeRecursive(ResNode node, File path, PrimaryResourceType type, GmFile gmf)
throws IOException {
if (!path.mkdirs()) {
throw new IOException("Duplicate resource group: \"" + node.getUserObject() + "\"");
}
Enumeration<ResNode> children = node.children();
ArrayList<ResourceTreeEntry> groupResList = new ArrayList<ResourceTreeEntry>();
while (children.hasMoreElements()) {
ResNode child = children.nextElement();
if (child.status != ResNode.STATUS_SECONDARY) {
String childName = (String) child.getUserObject();
String filename = FileTools.replaceBadChars(childName);
File subPath = new File(path, filename);
writeTreeRecursive(child, subPath, type, gmf);
groupResList.add(new ResourceTreeEntry(childName, filename, Type.GROUP));
} else {
if (child.getRes() != null) {
FileTreeFormat format = type.format;
Resource<?, ?> resource = child.getRes().get();
format.write(path, resource, gmf);
groupResList.add(format.createResourceTreeEntry(resource));
} else {
System.err.println("Ressource without reference in tree: " + child.getUserObject());
}
}
}
new ResourceListXmlFormat().write(groupResList, new File(path, "_resources.list.xml"));
}
}