import java.io.*;
import org.w3c.dom.*;
import java.text.*;
import java.util.*;


public class OrgUnmarshaller {

	private Map<String, Person> idTable = new Hashtable<String, Person>();

	public String getTextContent(Node node) {
		Text content = (Text)((Element)node).getFirstChild();
		return content.getWholeText().trim();
	}




	public Member unmarshalMember(Element node) {
		if (!node.getNodeName().equals("member")) return null;

		String id = node.getAttribute("id");

		Member result = (Member)idTable.get(id);

		if (result == null) {
			result = new Member();
			idTable.put(id, result);
			result.setId(id);
		}

		setPersonFields(result, node);

		Element xmlSpouse = (Element)(node.getElementsByTagName("spouse").item(0));

		String spouseID = xmlSpouse.getAttribute("id");

		Person spouse = idTable.get(spouseID);

		if (spouse == null) {
			spouse = new Member(); // order dependence here :-(
			idTable.put(spouseID, spouse);
			spouse.setId(spouseID);
		}

		result.setSpouse(spouse);

		NodeList kids = node.getElementsByTagName("child");

		for(int i = 0; i < kids.getLength(); i++) {
			Element xmlKid = (Element)kids.item(i);
			String kidID = xmlKid.getAttribute("id");
			Person kid = idTable.get(kidID);
			if (kid == null) {
				kid = new Member(); // another oder dependence
				idTable.put(kidID, kid);
				kid.setId(kidID);
			}
			result.addChild(kid);
		}



		return result;
	}


	private void setPersonFields(Person p, Element node) {



		Node child = (Element)node.getElementsByTagName("lastName").item(0);
		p.setLastName(child.getTextContent());

		child = (Element)node.getElementsByTagName("firstName").item(0);
		p.setFirstName(child.getTextContent());

		child = (Element)node.getElementsByTagName("dob").item(0);
		String dob = child.getTextContent();

		DateFormat formatter = DateFormat.getDateInstance();
		Date bday = null;

		try {
			bday = formatter.parse(dob);
		} catch(Exception e) {

		}

		p.setDob(bday);

	}



	public Dependant unmarshalDependant(Element node) {
		if (!node.getNodeName().equals("dependant")) return null;

		String id = node.getAttribute("id");

		Dependant result = (Dependant)idTable.get(id);

		if (result == null) {
			result = new Dependant();
			idTable.put(id, result);
			result.setId(id);
		}

		setPersonFields(result, node);

		Element sponsor = (Element)(node.getElementsByTagName("sponsor").item(0));

		String sponsorID = sponsor.getAttribute("id");

		Member member = (Member)idTable.get(sponsorID);

		if (member == null) {
			member = new Member();
			idTable.put(sponsorID, member);
			member.setId(sponsorID);
		}

		result.setSponsor(member);

		return result;
	}



	public Organization unmarshalOrganization(Element node) {
		if (!node.getNodeName().equals("org")) return null;
		Organization org = new Organization();

		NodeList dependants = node.getElementsByTagName("dependant");
		for(int i = 0; i < dependants.getLength(); i++) {
			Dependant d = unmarshalDependant((Element)(dependants.item(i)));
			//org.add(d);
		}

		NodeList members = node.getElementsByTagName("member");
		for(int i = 0; i < members.getLength(); i++) {
			Member m = unmarshalMember((Element)(members.item(i)));
			org.add(m);
		}


		return org;
	}
}