package vooga.rts.gamedesign.factories;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import vooga.rts.gamedesign.upgrades.UpgradeNode;
import vooga.rts.gamedesign.upgrades.UpgradeTree;
import vooga.rts.util.ReflectionHelper;
/**
* This class is an extension of Decoder class that is in charge of the creation
* of UpgradeTree for upgrade package.
*
* @author Wenshun Liu
*
*/
public class UpgradeDecoder extends Decoder {
public static final String TREE_TAG = "tree";
public static final String TREE_NAME_TAG = "treeName";
public static final String UPGRADE_CATEGORY_TAG = "type";
public static final String CATEGORY_NAME_TAG = "name";
public static final String INDIVIDUAL_UPGRADE_TAG = "upgradeNode";
public static final String PARENT_UPGRADE_TAG = "parent";
public static final String TITLE_TAG = "nodeName";
public static final String AFFECTING_OBJECT_TAG = "object";
public static final String AFFECTING_VALUE_TAG = "value";
public static final String COSTING_RESOURCE_TYPE_TAG = "resourceCostType";
public static final String COSTING_RESOURCE_AMOUNT_TAG = "resourceAmount";
private Factory myFactory;
private Map<String, String> myUpgradeNodeType;
public UpgradeDecoder(Factory factory) throws IllegalArgumentException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, ParserConfigurationException, SAXException, IOException{
myFactory = factory;
myUpgradeNodeType = new HashMap<String, String>();
myFactory.loadMappingInfo("UpgradeNodeMatchUp", myUpgradeNodeType);
}
/**
* Creates the UpgradeTrees and puts them into map in Factory by receiving
* Document passed in from the Factory, containing necessary information
* related to the UpgradeTree
*
* @param doc the Document passed in from Factory
* @throws NumberFormatException
*
*/
public void create(Document doc, String type) throws NumberFormatException {
NodeList treeLst = doc.getElementsByTagName(TREE_TAG);
for (int i = 0; i < treeLst.getLength(); i++) {
Element treeElmnt = (Element) treeLst.item(i);
Element treeNameElmnt = (Element) treeElmnt.getElementsByTagName(TREE_NAME_TAG).item(0);
NodeList treeName = treeNameElmnt.getChildNodes();
createSingleTree(((Node) treeName.item(0)).getNodeValue(), treeElmnt);
}
}
/**
* Creates a single upgrade tree based on information loaded from the input
* xml file.
*
* @param treeName
* @param treeElmnt
*/
private void createSingleTree(String treeName, Element treeElmnt) {
UpgradeTree upgradeTree = new UpgradeTree();
NodeList nodeLst = treeElmnt.getElementsByTagName(UPGRADE_CATEGORY_TAG);
for (int i = 0; i < nodeLst.getLength(); i++) {
Element typeElmnt = (Element) nodeLst.item(i);
Element nameElmnt = (Element) typeElmnt.
getElementsByTagName(CATEGORY_NAME_TAG).item(0);
NodeList name = nameElmnt.getChildNodes();
upgradeTree.addBranch(((Node) name.item(0)).getNodeValue());
NodeList upgradeNodeList = typeElmnt.
getElementsByTagName(INDIVIDUAL_UPGRADE_TAG);
for (int j=0; j<upgradeNodeList.getLength(); ++j) {
Element upgradeNodeElement = (Element) upgradeNodeList.item(j);
String parent = getElement(upgradeNodeElement,
PARENT_UPGRADE_TAG);
String nodeName = getElement(upgradeNodeElement,
TITLE_TAG);
String object = getElement(upgradeNodeElement,
AFFECTING_OBJECT_TAG);
String value = getElement(upgradeNodeElement,
AFFECTING_VALUE_TAG);
String costedResource = getElement(upgradeNodeElement,
COSTING_RESOURCE_TYPE_TAG);
String costedResourceAmount = getElement(upgradeNodeElement,
COSTING_RESOURCE_AMOUNT_TAG);
UpgradeNode newUpgrade = (UpgradeNode) ReflectionHelper.
makeInstance(myUpgradeNodeType.get(object),
upgradeTree, nodeName, Integer.parseInt(value),
Integer.parseInt(costedResourceAmount));
UpgradeNode current = upgradeTree.findNode(parent);
current.addChild(newUpgrade);
}
}
upgradeTree.updateTreeStatus();
myFactory.put(treeName, upgradeTree);
}
/**
* TESTING PURPOSE. PRINTS TREE.
* @param upgradeTree
*/
private void printTree(UpgradeTree upgradeTree) {
for (UpgradeNode u: upgradeTree.getHead().getChildren()) {
UpgradeNode current = u;
while (!current.getChildren().isEmpty()) {
for (UpgradeNode node: current.getChildren()) {
System.out.println("Name: " + node.getUpgradeName() +
" Parent Name " + current.getUpgradeName());
}
current = current.getChildren().get(0);
//should recurse if really want to print the whole tree
}
}
for (UpgradeNode u: upgradeTree.getCurrentUpgrades()) {
System.out.println("Current Upgrades: " + u.getUpgradeName());
}
}
}