package codechicken.lib.config;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.Map.Entry;
public abstract class ConfigTagParent {
public static class TagOrderComparator implements Comparator<ConfigTag> {
int sortMode;
public TagOrderComparator(int sortMode) {
this.sortMode = sortMode;
}
public int compare(ConfigTag o1, ConfigTag o2) {
if (o1.position != o2.position) {
return compareInt(o1.position, o2.position);
}
if (o1.brace != o2.brace) {
return o1.brace ? 1 : -1;//braced one goes after
}
switch (sortMode) {
case 1:
if (o1.value == o2.value) {
return 0;
}
if (o1.value == null) {
return 1;
}
if (o2.value == null) {
return -1;
}
return o1.value.compareTo(o2.value);
default:
return o1.name.compareTo(o2.name);
}
}
private int compareInt(int a, int b) {
return a == b ? 0 : a < b ? -1 : 1;
}
}
private TreeMap<String, ConfigTag> childtags = new TreeMap<String, ConfigTag>();
public String comment;
/**
* 0 = name, 1 = value
*/
public int sortMode = 0;
/**
* The mode for determining when child tags should leave a blank line between them and the one above
* 0 = never, 1 = when braced, 2 = always
*/
public int newlinemode = 1;
public abstract void saveConfig();
public abstract String getNameQualifier();
public ConfigTagParent setComment(String comment) {
this.comment = comment;
saveConfig();
return this;
}
public ConfigTagParent setSortMode(int mode) {
sortMode = mode;
saveConfig();
return this;
}
public ConfigTagParent setNewLineMode(int mode) {
newlinemode = mode;
for (Entry<String, ConfigTag> entry : childtags.entrySet()) {
ConfigTag tag = entry.getValue();
if (newlinemode == 0) {
tag.newline = false;
} else if (newlinemode == 1) {
tag.newline = tag.brace;
} else if (newlinemode == 2) {
tag.newline = true;
}
}
saveConfig();
return this;
}
public Map<String, ConfigTag> childTagMap() {
return childtags;
}
public boolean hasChildTags() {
return !childtags.isEmpty();
}
public boolean containsTag(String tagname) {
return getTag(tagname, false) != null;
}
public ConfigTag getNewTag(String tagname) {
return new ConfigTag(this, tagname);
}
public ConfigTag getTag(String tagname, boolean create) {
int dotpos = tagname.indexOf(".");
String basetagname = dotpos == -1 ? tagname : tagname.substring(0, dotpos);
ConfigTag basetag = childtags.get(basetagname);
if (basetag == null) {
if (!create) {
return null;
}
basetag = getNewTag(basetagname);
saveConfig();
}
if (dotpos == -1) {
return basetag;
}
return basetag.getTag(tagname.substring(dotpos + 1), create);
}
public ConfigTag getTag(String tagname) {
return getTag(tagname, true);
}
public boolean removeTag(String tagname) {
ConfigTag tag = getTag(tagname, false);
if (tag == null) {
return false;
}
int dotpos = tagname.lastIndexOf(".");
String lastpart = dotpos == -1 ? tagname : tagname.substring(dotpos + 1, tagname.length());
if (tag.parent != null) {
boolean ret = tag.parent.childtags.remove(lastpart) != null;
if (ret) {
saveConfig();
}
return ret;
}
return false;
}
public void addChild(ConfigTag tag) {
childtags.put(tag.name, tag);
}
public <T extends ConfigTag> ArrayList<T> getSortedTagList() {
ArrayList<T> taglist = new ArrayList<T>(childtags.size());
for (Entry<String, ConfigTag> tag : childtags.entrySet()) {
taglist.add((T) tag.getValue());
}
Collections.sort(taglist, new TagOrderComparator(sortMode));
return taglist;
}
public void loadChildren(BufferedReader reader) {
String comment = "";
String bracequalifier = "";
try {
while (true) {
String line = ConfigFile.readLine(reader);
if (line == null) {
break;
}
if (line.startsWith("#")) {
if (comment.equals("")) {
comment = line.substring(1);
} else {
comment = comment + "\n" + line.substring(1);
}
} else if (line.contains("=")) {
String qualifiedname = line.substring(0, line.indexOf("="));
getTag(qualifiedname).onLoaded().setComment(comment).setValue(line.substring(line.indexOf("=") + 1));
comment = "";
bracequalifier = qualifiedname;
} else if (line.equals("{")) {
getTag(bracequalifier).setComment(comment).useBraces().loadChildren(reader);
comment = "";
bracequalifier = "";
} else if (line.equals("}")) {
break;
} else {
bracequalifier = line;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void saveTagTree(PrintWriter writer, int tabs, String bracequalifier) {
boolean first = true;
for (ConfigTag tag : getSortedTagList()) {
tag.save(writer, tabs, bracequalifier, first);
first = false;
}
}
public void writeComment(PrintWriter writer, int tabs) {
if (comment != null && !comment.equals("")) {
String[] comments = comment.split("\n");
for (int i = 0; i < comments.length; i++) {
ConfigFile.writeLine(writer, "#" + comments[i], tabs);
}
}
}
}