package com.drakulo.games.ais.core.io;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import com.drakulo.games.ais.core.Resource;
import com.drakulo.games.ais.core.Settings;
import com.drakulo.games.ais.core.tech.Technology;
import com.drakulo.games.ais.ui.I18n;
public class TechnologyIO {
public static Map<String, Technology> loadTechnologies() {
Map<String, Technology> map = null;
File f = new File("./data/technologies.xml");
SAXBuilder sxb = new SAXBuilder();
try {
Document document = sxb.build(f);
Element root = document.getRootElement();
map = handleNodes(root);
// The map is loaded. Each technology will now be linked to it's
// parents and children
Set<String> keys = map.keySet();
for (String key : keys) {
List<Technology> parents = new ArrayList<Technology>();
List<Technology> children = new ArrayList<Technology>();
Technology t = map.get(key);
for (Technology pt : t.getParents()) {
parents.add(map.get(pt.getId()));
}
for (Technology ct : t.getChildren()) {
children.add(map.get(ct.getId()));
}
t.setParents(parents);
t.setChildren(children);
}
calculateLevels(map);
loadCosts(root, map);
return map;
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* Analyse the costs from the XML stream and loads it into each technology
*
* @param root
* - the root node
* @param map
* - the technology map
*/
@SuppressWarnings("unchecked")
private static void loadCosts(Element root, Map<String, Technology> map) {
Element costsElement = root.getChild("costs");
List<Element> costsByLevel = costsElement.getChildren("level");
Map<String, Map<Resource, BigDecimal>> costMap = new HashMap<String, Map<Resource, BigDecimal>>();
for (Element costElement : costsByLevel) {
String level = costElement.getAttribute("value").getValue();
Resource[] resources = Resource.values();
Map<Resource, BigDecimal> temp = new HashMap<Resource, BigDecimal>();
for (Resource r : resources) {
Element e = costElement.getChild(r.toString().toLowerCase());
if (e == null) {
temp.put(r, BigDecimal.ZERO);
} else {
temp.put(r, BigDecimal.valueOf(Long.valueOf(e.getText())));
}
}
costMap.put(level, temp);
}
for (String k : map.keySet()) {
Technology t = map.get(k);
int level = t.getLevel();
t.setCost(costMap.get(String.valueOf(level)));
}
}
/**
* Determine the technology level according to its parents / children
*
* @param map
* - the data map
*/
private static void calculateLevels(Map<String, Technology> map) {
for (String k : map.keySet()) {
initLevel(map.get(k));
}
}
private static void initLevel(Technology t) {
if (t.getLevel() != -1) {
// The level is already initialized
return;
}
List<Technology> parents = t.getParents();
// No parents => root technology => level 0;
if (parents.size() == 0) {
t.setLevel(0);
return;
}
int maxParentLevel = 0;
for (Technology parent : parents) {
if (parent.getLevel() == -1) {
// The parent is not initialized yet
initLevel(parent);
}
if (maxParentLevel < parent.getLevel()) {
maxParentLevel = parent.getLevel();
}
}
t.setLevel(maxParentLevel + 1);
}
@SuppressWarnings("unchecked")
private static Map<String, Technology> handleNodes(Element root) {
Map<String, Technology> map = new HashMap<String, Technology>();
List<Element> technologies = root.getChildren("technology");
// System.out.println("===================================");
// System.out.println("===================================");
for (Element te : technologies) {
Technology t = createFromNode(te);
// System.out.println(t.getId()+".name = ");
// System.out.println(t.getId()+".description = ");
// System.out.println("");
map.put(t.getId(), t);
}
// System.out.println("===================================");
// System.out.println("===================================");
return map;
}
@SuppressWarnings("unchecked")
private static Technology createFromNode(Element node) {
Technology t = new Technology();
String id = node.getChildText("id");
t.setId(id);
t.setName(I18n.getFirstToUpper(id + ".name"));
t.setDescription(I18n.getFirstToUpper(id + ".description"));
t.setImageKey(node.getChildText("icon"));
List<Element> parents = node.getChild("parents").getChildren("parent");
for (Element p : parents) {
Technology pt = new Technology();
pt.setId(p.getText());
t.addParent(pt);
}
List<Element> children = node.getChild("children").getChildren("child");
for (Element p : children) {
Technology ct = new Technology();
ct.setId(p.getText());
t.addChild(ct);
}
// Debug mode
if (Settings.IS_DEBUG) {
t.setOwned(true);
}
return t;
}
}