    001package net.minecraftforge.common;
    002
    003import java.io.BufferedWriter;
    004import java.io.IOException;
    005import java.util.ArrayList;
    006import java.util.Collection;
    007import java.util.Map;
    008import java.util.Set;
    009import java.util.TreeMap;
    010
    011import com.google.common.base.Splitter;
    012
    013import static net.minecraftforge.common.Configuration.*;
    014
    015public 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}