    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    }