001 package net.minecraftforge.common;
002
003 import java.io.BufferedWriter;
004 import java.io.IOException;
005 import java.util.ArrayList;
006 import java.util.Collection;
007 import java.util.Map;
008 import java.util.Set;
009 import java.util.TreeMap;
010
011 import com.google.common.base.Splitter;
012
013 import static net.minecraftforge.common.Configuration.*;
014
015 public class ConfigCategory implements Map<String, Property>
016 {
017 private String name;
018 private String comment;
019 private ArrayList<ConfigCategory> children = new ArrayList<ConfigCategory>();
020 private Map<String, Property> properties = new TreeMap<String, Property>();
021 public final ConfigCategory parent;
022
023 public ConfigCategory(String name)
024 {
025 this(name, null);
026 }
027
028 public ConfigCategory(String name, ConfigCategory parent)
029 {
030 this.name = name;
031 this.parent = parent;
032 if (parent != null)
033 {
034 parent.children.add(this);
035 }
036 }
037
038 public boolean equals(Object obj)
039 {
040 if (obj instanceof ConfigCategory)
041 {
042 ConfigCategory cat = (ConfigCategory)obj;
043 return name.equals(cat.name) && children.equals(cat.children);
044 }
045
046 return false;
047 }
048
049 public String getQualifiedName()
050 {
051 return getQualifiedName(name, parent);
052 }
053
054 public static String getQualifiedName(String name, ConfigCategory parent)
055 {
056 return (parent == null ? name : parent.getQualifiedName() + Configuration.CATEGORY_SPLITTER + name);
057 }
058
059 public ConfigCategory getFirstParent()
060 {
061 return (parent == null ? this : parent.getFirstParent());
062 }
063
064 public boolean isChild()
065 {
066 return parent != null;
067 }
068
069 public Map<String, Property> getValues()
070 {
071 return properties;
072 }
073
074 public void setComment(String comment)
075 {
076 this.comment = comment;
077 }
078
079 public boolean containsKey(String key)
080 {
081 return properties.containsKey(key);
082 }
083
084 public Property get(String key)
085 {
086 return properties.get(key);
087 }
088
089 public void set(String key, Property value)
090 {
091 properties.put(key, value);
092 }
093
094 public void write(BufferedWriter out, int indent) throws IOException
095 {
096 String pad = getIndent(indent);
097
098 out.write(pad + "####################" + NEW_LINE);
099 out.write(pad + "# " + name + NEW_LINE);
100
101 if (comment != null)
102 {
103 out.write(pad + "#===================" + NEW_LINE);
104 Splitter splitter = Splitter.onPattern("\r?\n");
105
106 for (String line : splitter.split(comment))
107 {
108 out.write(pad + "# " + line + NEW_LINE);
109 }
110 }
111
112 out.write(pad + "####################" + NEW_LINE + NEW_LINE);
113
114 if (!allowedProperties.matchesAllOf(name))
115 {
116 name = '"' + name + '"';
117 }
118
119 out.write(pad + name + " {" + NEW_LINE);
120
121 pad = getIndent(indent + 1);
122
123 Property[] props = properties.values().toArray(new Property[properties.size()]);
124
125 for (int x = 0; x < props.length; x++)
126 {
127 Property prop = props[x];
128
129 if (prop.comment != null)
130 {
131 if (x != 0)
132 {
133 out.newLine();
134 }
135
136 Splitter splitter = Splitter.onPattern("\r?\n");
137 for (String commentLine : splitter.split(prop.comment))
138 {
139 out.write(pad + "# " + commentLine + NEW_LINE);
140 }
141 }
142
143 String propName = prop.getName();
144
145 if (!allowedProperties.matchesAllOf(propName))
146 {
147 propName = '"' + propName + '"';
148 }
149
150 if (prop.isList())
151 {
152 out.write(String.format(pad + "%s:%s <" + NEW_LINE, prop.getType().getID(), propName));
153 pad = getIndent(indent + 2);
154
155 for (String line : prop.valueList)
156 {
157 out.write(pad + line + NEW_LINE);
158 }
159
160 out.write(getIndent(indent + 1) + " >" + NEW_LINE);
161 }
162 else if (prop.getType() == null)
163 {
164 out.write(String.format(pad + "%s=%s" + NEW_LINE, propName, prop.value));
165 }
166 else
167 {
168 out.write(String.format(pad + "%s:%s=%s" + NEW_LINE, prop.getType().getID(), propName, prop.value));
169 }
170 }
171
172 for (ConfigCategory child : children)
173 {
174 child.write(out, indent + 1);
175 }
176
177 out.write(getIndent(indent) + "}" + NEW_LINE + NEW_LINE);
178 }
179
180 private String getIndent(int indent)
181 {
182 StringBuilder buf = new StringBuilder("");
183 for (int x = 0; x < indent; x++)
184 {
185 buf.append(" ");
186 }
187 return buf.toString();
188 }
189
190
191 //Map bouncer functions for compatibility with older mods, to be removed once all mods stop using it.
192 @Override public int size(){ return properties.size(); }
193 @Override public boolean isEmpty() { return properties.isEmpty(); }
194 @Override public boolean containsKey(Object key) { return properties.containsKey(key); }
195 @Override public boolean containsValue(Object value){ return properties.containsValue(value); }
196 @Override public Property get(Object key) { return properties.get(key); }
197 @Override public Property put(String key, Property value) { return properties.put(key, value); }
198 @Override public Property remove(Object key) { return properties.remove(key); }
199 @Override public void putAll(Map<? extends String, ? extends Property> m) { properties.putAll(m); }
200 @Override public void clear() { properties.clear(); }
201 @Override public Set<String> keySet() { return properties.keySet(); }
202 @Override public Collection<Property> values() { return properties.values(); }
203 @Override public Set<java.util.Map.Entry<String, Property>> entrySet() { return properties.entrySet(); }
204
205 }