package hibergui.generator.tool.xml;

import hibergui.HiberGUI;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Reads HiberGUI mapping (<code>hibergui-mapping</code>) XML files.
 * Validate it by DTD file which is specified at <code>DOCTYPE</code> element of mapping XML
 * or if it is not available - file doesn't exist - then validate by DTD file
 * in <code>hibergui.jar</code> archive.
 */
public class MappingReader extends XMLReader{
	private static final String ROOT_NODE_NAME = "hibergui-mapping";
	private static final String ROOT_ATTRIBUTE_NAME = "package";
	private static final String FORM_NODE_NAME = "form";
	private static final String FORM_ATTRIBUTE_NAME = "name";
	
	private static final String DTD_FOLDER = "dtd";
	private static final String DTD_FILE = "hibergui-mapping-1.0.dtd";
	
	/**
	 * Constructor of this class. Validates and reads content of XML.
	 */
	public MappingReader(String file) throws SAXException, IOException,
			ParserConfigurationException, TransformerException {
		super(new FileInputStream(new File(file)), HiberGUI.class.getResourceAsStream(DTD_FOLDER + "/" + DTD_FILE));
	}

	/**
	 * Gets the name of target class, e.g.: <code>TargetClassName</code>.
	 * 
	 * @return Name of target class.
	 */
	public String getTargetClassName() {
		NodeList nl = getNode(Node.ELEMENT_NODE, this.getDOM().getNode(), ROOT_NODE_NAME, null).getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node n = nl.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals(FORM_NODE_NAME)) {
				return n.getAttributes().getNamedItem(FORM_ATTRIBUTE_NAME).getNodeValue();
			}
		}
		return null;
	}
	
	/**
	 * Gets the name of package of target class.
	 * 
	 * @param asFolder Boolean value which determine form of the result. If value of
	 * this parameter is: <ul> 
	 * <li><code>true</code>: result will be formatted as a relative path, e.g. <code>package/of/my/class</code>.</li>
	 * <li><code>false</code>: result will be formatted as package name, e.g. <code>package.of.my.class</code>.</li>
	 * </ul>
	 * @return Name of package of target class.
	 */
	public String getPackageName(boolean asFolder) {
		String pcg = getNode(Node.ELEMENT_NODE, this.getDOM().getNode(), ROOT_NODE_NAME, ROOT_ATTRIBUTE_NAME).getNodeValue();
		if (asFolder){
			return pcg.replaceAll("\\.", "/");
		}
		return pcg;
	}
	
	/**
	 * Gets the node called hibergui-mapping. This node will be passed to
	 * the Freemarker to generate the java source code from this node tree.
	 * 
	 * @return <code>hibergui-mapping</code> root node.
	 */
	public Node getRootNode(){
		return getNode(Node.ELEMENT_NODE, this.getDOM().getNode(), ROOT_NODE_NAME, null);
	}
}
