001/**
002 * This software is provided under the terms of the Minecraft Forge Public
003 * License v1.0.
004 */
005
006package net.minecraftforge.common;
007
008import java.util.ArrayList;
009
010import net.minecraftforge.common.Property.Type;
011
012public class Property
013{
014    public enum Type
015    {
016        STRING,
017        INTEGER,
018        BOOLEAN,
019        DOUBLE;
020
021        private static Type[] values = {STRING, INTEGER, BOOLEAN, DOUBLE};
022
023        public static Type tryParse(char id)
024        {
025            for (int x = 0; x < values.length; x++)
026            {
027                if (values[x].getID() == id)
028                {
029                    return values[x];
030                }
031            }
032
033            return STRING;
034        }
035
036        public char getID()
037        {
038            return name().charAt(0);
039        }
040    }
041
042    private String name;
043    private String value;
044    public String comment;
045    private String[] values;
046
047    private final boolean wasRead;
048    private final boolean isList;
049    private final Type type;
050    private boolean changed = false;
051
052    public Property()
053    {
054        wasRead = false;
055        type    = null;
056        isList  = false;
057    }
058
059    public Property(String name, String value, Type type)
060    {
061        this(name, value, type, false);
062    }
063
064    Property(String name, String value, Type type, boolean read)
065    {
066        setName(name);
067        this.value = value;
068        this.type  = type;
069        wasRead    = read;
070        isList     = false;
071    }
072
073    public Property(String name, String[] values, Type type)
074    {
075        this(name, values, type, false);
076    }
077
078    Property(String name, String[] values, Type type, boolean read)
079    {
080        setName(name);
081        this.type   = type;
082        this.values = values;
083        wasRead     = read;
084        isList      = true;
085    }
086
087    /**
088     * Returns the value in this property as it's raw string.
089     * 
090     * @return current value
091     */
092    public String getString()
093    {
094        return value;
095    }
096
097    /**
098     * Returns the value in this property as an integer,
099     * if the value is not a valid integer, it will return -1.
100     * 
101     * @return The value
102     */
103    public int getInt()
104    {
105        return getInt(-1);
106    }
107
108    /**
109     * Returns the value in this property as an integer,
110     * if the value is not a valid integer, it will return the
111     * provided default.
112     * 
113     * @param _default The default to provide if the current value is not a valid integer
114     * @return The value
115     */
116    public int getInt(int _default)
117    {
118        try
119        {
120            return Integer.parseInt(value);
121        }
122        catch (NumberFormatException e)
123        {
124            return _default;
125        }
126    }
127    
128    /**
129     * Checks if the current value stored in this property can be converted to an integer.
130     * @return True if the type of the Property is an Integer
131     */
132    public boolean isIntValue()
133    {
134        try
135        {
136            Integer.parseInt(value);
137            return true;
138        }
139        catch (NumberFormatException e)
140        {
141            return false;
142        }
143    }
144
145    /**
146     * Returns the value in this property as a boolean,
147     * if the value is not a valid boolean, it will return the
148     * provided default.
149     * 
150     * @param _default The default to provide
151     * @return The value as a boolean, or the default
152     */
153    public boolean getBoolean(boolean _default)
154    {
155        if (isBooleanValue())
156        {
157            return Boolean.parseBoolean(value);
158        }
159        else
160        {
161            return _default;
162        }
163    }
164
165    /**
166     * Checks if the current value held by this property is a valid boolean value.
167     * @return True if it is a boolean value
168     */
169    public boolean isBooleanValue()
170    {
171        return ("true".equals(value.toLowerCase()) || "false".equals(value.toLowerCase()));
172    }
173
174    /**
175     * Checks if the current value held by this property is a valid double value.
176     * @return True if the value can be converted to an double
177     */
178    public boolean isDoubleValue()
179    {
180        try
181        {
182            Double.parseDouble(value);
183            return true;
184        }
185        catch (NumberFormatException e)
186        {
187            return false;
188        }
189    }
190
191    /**
192     * Returns the value in this property as a double,
193     * if the value is not a valid double, it will return the
194     * provided default.
195     * 
196     * @param _default The default to provide if the current value is not a valid double
197     * @return The value
198     */
199    public double getDouble(double _default)
200    {
201        try
202        {
203            return Double.parseDouble(value);
204        }
205        catch (NumberFormatException e)
206        {
207            return _default;
208        }
209    }
210
211    public String[] getStringList()
212    {
213        return values;
214    }
215
216    /**
217     * Returns the integer value of all values that can
218     * be parsed in the list.
219     * 
220     * @return Array of length 0 if none of the values could be parsed.
221     */
222    public int[] getIntList()
223    {
224        ArrayList<Integer> nums = new ArrayList<Integer>();
225        
226        for (String value : values)
227        {
228            try
229            {
230                nums.add(Integer.parseInt(value));
231            }
232            catch (NumberFormatException e){}
233        }
234
235        int[] primitives = new int[nums.size()];
236
237        for (int i = 0; i < nums.size(); i++)
238        {
239            primitives[i] = nums.get(i);
240        }
241
242        return primitives;
243    }
244
245    /**
246     * Checks if all of the current values stored in this property can be converted to an integer.
247     * @return True if the type of the Property is an Integer List
248     */
249    public boolean isIntList()
250    {
251        for (String value : values)
252        {
253            try
254            {
255                Integer.parseInt(value);
256            }
257            catch (NumberFormatException e)
258            {
259                return false;
260            }
261        }
262        return true;
263    }
264
265    /**
266     * Returns the boolean value of all values that can
267     * be parsed in the list.
268     * 
269     * @return Array of length 0 if none of the values could be parsed.
270     */
271    public boolean[] getBooleanList()
272    {
273        ArrayList<Boolean> tmp = new ArrayList<Boolean>();
274        for (String value : values)
275        {
276            try
277            {
278                tmp.add(Boolean.parseBoolean(value));
279            }
280            catch (NumberFormatException e){}
281        }
282
283        boolean[] primitives = new boolean[tmp.size()];
284
285        for (int i = 0; i < tmp.size(); i++)
286        {
287            primitives[i] = tmp.get(i);
288        }
289
290        return primitives;
291    }
292
293    /**
294     * Checks if all of current values stored in this property can be converted to a boolean.
295     * @return True if it is a boolean value
296     */
297    public boolean isBooleanList()
298    {
299        for (String value : values)
300        {
301            if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value))
302            {
303                return false;
304            }
305        }
306
307        return true;
308    }
309
310    /**
311     * Returns the double value of all values that can
312     * be parsed in the list.
313     * 
314     * @return Array of length 0 if none of the values could be parsed.
315     */
316    public double[] getDoubleList()
317    {
318        ArrayList<Double> tmp = new ArrayList<Double>();
319        for (String value : values)
320        {
321            try
322            {
323                tmp.add(Double.parseDouble(value));
324            }
325            catch (NumberFormatException e) {}
326        }
327
328        double[] primitives = new double[tmp.size()];
329
330        for (int i = 0; i < tmp.size(); i++)
331        {
332            primitives[i] = tmp.get(i);
333        }
334
335        return primitives;
336    }
337
338    /**
339     * Checks if all of the current values stored in this property can be converted to a double.
340     * @return True if the type of the Property is a double List
341     */
342    public boolean isDoubleList()
343    {
344        for (String value : values)
345        {
346            try
347            {
348                Double.parseDouble(value);
349            }
350            catch (NumberFormatException e)
351            {
352                return false;
353            }
354        }
355
356        return true;
357    }
358
359    public String getName()
360    {
361        return name;
362    }
363
364    public void setName(String name)
365    {
366        this.name = name;
367    }
368
369    /**
370     * Determines if this config value was just created, or if it was read from the config file.
371     * This is useful for mods who auto-assign there blocks to determine if the ID returned is 
372     * a configured one, or a automatically generated one.
373     * 
374     * @return True if this property was loaded from the config file with a value
375     */
376    public boolean wasRead()
377    {
378        return wasRead;
379    }
380
381    public Type getType()
382    {
383        return type;
384    }
385
386    public boolean isList()
387    {
388        return isList;
389    }
390
391    public boolean hasChanged(){ return changed; }
392    void resetChangedState(){ changed = false; }
393
394    public void set(String value)
395    {
396        this.value = value;
397        changed = true;
398    }
399
400    public void set(String[] values)
401    {
402        this.values = values;
403        changed = true;
404    }
405
406    public void set(int     value){ set(Integer.toString(value)); }
407    public void set(boolean value){ set(Boolean.toString(value)); }
408    public void set(double  value){ set(Double.toString(value));  }
409}