package pl.shockah;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;
import pl.shockah.FileLine;
public class Config {
public Config() {
this(null);
}
public Config(Config fallback) {
fallbackConfig = fallback;
}
public final Config fallbackConfig;
private HashMap<String,String> mapValues = new HashMap<String,String>();
private HashMap<String,Config> mapSubconfigs = new HashMap<String,Config>();
public synchronized void set(String key, Object value) {
String[] sub = key.split(Pattern.quote("->"));
Config cfg = this;
for (int i = 0; i < sub.length-1; i++) cfg = cfg.getConfig(sub[i]);
cfg.set(sub[sub.length-1],value,true);
}
protected synchronized void set(String key, Object value, boolean direct) {
if (direct) mapValues.put(key,value.toString());
else set(key,value);
}
public void set(String key, boolean value) {set(key,new Boolean(value));}
public void set(String key, int value) {set(key,new Integer(value));}
public void set(String key, long value) {set(key,new Long(value));}
public void set(String key, float value) {set(key,new Float(value));}
public void set(String key, double value) {set(key,new Double(value));}
public void add(String key, int value, int def) {setNotExists(key,def); set(key,getInt(key)+value);}
public void add(String key, long value, long def) {setNotExists(key,def); set(key,getLong(key)+value);}
public void add(String key, float value, float def) {setNotExists(key,def); set(key,getFloat(key)+value);}
public void add(String key, double value, double def) {setNotExists(key,def); set(key,getDouble(key)+value);}
public synchronized boolean remove(String key) {
String[] sub = key.split(Pattern.quote("->"));
Config cfg = this;
for (int i = 0; i < sub.length-1; i++) cfg = cfg.getConfig(sub[i].trim());
return cfg.remove(sub[sub.length-1].trim(),true);
}
protected synchronized boolean remove(String key, boolean direct) {
if (direct) {
if (mapValues.containsKey(key)) {
mapValues.remove(key);
return true;
} else return false;
} else return remove(key);
}
public synchronized void makeConfig(String key) {
if (mapValues.containsKey(key)) mapValues.remove(key);
if (mapSubconfigs.containsKey(key)) return;
mapSubconfigs.put(key,new Config(this));
}
public synchronized Config getConfig(String key) {
if (!mapSubconfigs.containsKey(key)) makeConfig(key);
return mapSubconfigs.get(key);
}
public synchronized void removeConfig(String key) {
mapSubconfigs.remove(key);
}
public synchronized boolean existsConfig(String key) {
return mapSubconfigs.containsKey(key);
}
public synchronized boolean exists(String key) {
return mapValues.containsKey(key);
}
public void setNotExists(String key, Object value) {
if (!exists(key)) set(key,value);
}
public void setNotExists(String key, boolean value) {setNotExists(key,new Boolean(value));}
public void setNotExists(String key, int value) {setNotExists(key,new Integer(value));}
public void setNotExists(String key, long value) {setNotExists(key,new Long(value));}
public void setNotExists(String key, float value) {setNotExists(key,new Float(value));}
public void setNotExists(String key, double value) {setNotExists(key,new Double(value));}
public synchronized String getString(String key) {
if (mapValues.containsKey(key))
return mapValues.get(key);
if (fallbackConfig != null)
return fallbackConfig.getString(key);
return null;
}
public boolean getBoolean(String key) {
String v = getString(key);
if (v.equals("1")) return true;
if (v.equals("0")) return false;
return Boolean.parseBoolean(v);
}
public int getInt(String key) {return Integer.parseInt(getString(key));}
public long getLong(String key) {return Long.parseLong(getString(key));}
public float getFloat(String key) {return Float.parseFloat(getString(key));}
public double getDouble(String key) {return Double.parseDouble(getString(key));}
public Set<String> getKeysSubconfigs() {
return mapSubconfigs.keySet();
}
public Set<String> getKeys() {
return mapValues.keySet();
}
public void load(File file) {
load(FileLine.read(file));
}
public void load(ArrayList<String> lines) {
for (String line : lines) {
line = line.trim();
if (line.isEmpty()) continue;
if (line.startsWith("//")) continue;
if (line.indexOf('=') == -1) continue;
String key = line.substring(0,line.indexOf('='));
String value = line.substring(key.length()+1);
set(key.trim(),value.trim());
}
}
public void save(File file) {
ArrayList<String> lines = new ArrayList<String>();
saveSubconfig(lines,"");
Collections.sort(lines);
FileLine.write(file,lines);
}
protected void saveSubconfig(ArrayList<String> lines, String path) {
Iterator<Entry<String,Config>> it1 = mapSubconfigs.entrySet().iterator();
while (it1.hasNext()) {
Entry<String,Config> pair = it1.next();
pair.getValue().saveSubconfig(lines,(path.isEmpty()? "" : path+"->")+pair.getKey());
}
Iterator<Entry<String,String>> it2 = mapValues.entrySet().iterator();
while (it2.hasNext()) {
Entry<String,String> pair = it2.next();
lines.add(path+(path.isEmpty() ? "" : "->")+pair.getKey()+" = "+pair.getValue());
}
}
}