package net.trevize.gui.xmltreetable;

import java.io.IOException;

import javax.swing.tree.TreeModel;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XmlTreeModel implements TreeModel {

	private XmlTreeNode root;

	public XmlTreeModel(String filepath) {
		loadModelFromFile(filepath);
	}

	public void loadModelFromFile(String filepath) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder loader = factory.newDocumentBuilder();
			Document document = loader.parse(filepath);
			Element rootElement = document.getDocumentElement();
			root = fillModelFromDOM(rootElement);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private XmlTreeNode fillModelFromDOM(Node rootElement) {
		//creating a node for this element
		XmlTreeNode nodeRow = new XmlTreeNode();
		nodeRow.setUserObject(rootElement.getNodeName());

		//adding all attributes like subnodes.
		NamedNodeMap nnm = rootElement.getAttributes();
		if (nnm != null) {
			for (int i = 0; i < nnm.getLength(); ++i) {
				XmlTreeNode subNodeRow = new XmlTreeNode();
				subNodeRow.setUserObject("@" + nnm.item(i).getNodeName());
				subNodeRow.getTableRowValues()
						.add(nnm.item(i).getTextContent());
				nodeRow.add(subNodeRow);
			}
		}

		//adding subelement.
		NodeList nl = rootElement.getChildNodes();
		for (int i = 0; i < nl.getLength(); ++i) {
			if (nl.item(i).getNodeType() != Node.TEXT_NODE) {
				nodeRow.add(fillModelFromDOM(nl.item(i)));
			} else {
				String text_content = nl.item(i).getTextContent();
				nodeRow.getTableRowValues().add(text_content);
			}
		}

		return nodeRow;
	}

	@Override
	public void addTreeModelListener(javax.swing.event.TreeModelListener l) {
		//do nothing
	}

	@Override
	public Object getChild(Object parent, int index) {
		return ((XmlTreeNode) parent).getChildAt(index);
	}

	@Override
	public int getChildCount(Object parent) {
		return ((XmlTreeNode) parent).getChildCount();
	}

	@Override
	public int getIndexOfChild(Object parent, Object child) {
		return ((XmlTreeNode) parent).getIndex((XmlTreeNode) child);
	}

	@Override
	public Object getRoot() {
		return root;
	}

	@Override
	public boolean isLeaf(Object node) {
		int child_count = getChildCount(node);
		if (child_count == 0) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void removeTreeModelListener(javax.swing.event.TreeModelListener l) {
		//do nothing
	}

	@Override
	public void valueForPathChanged(javax.swing.tree.TreePath path,
			Object newValue) {
		//do nothing
	}

}

