// $Id: GEDCOM.java,v 1.5 2001/01/18 20:34:29 mdean Exp $


/**
 * tree representation of a parsed Genealogical Data Communication (GEDCOM)
 * file.
 */
class GEDCOM
{
    /**
     * representation of a single node within a parsed GEDCOM tree.
     */
    class Node
    {
	String key = null;
	String tag = null;
	String value = null;

	Node(String key,
	     String tag,
	     String value)
	{
	    this.key = key;
	    this.tag = tag;
	    this.value = value;
	    if (key != null)
		keys.put(key, this);
	}
	
	/**
	 * vector of Node.
	 */
	java.util.Vector children = new java.util.Vector();

	void print(int depth)
	{
	    for (int i = 0; i < depth; i++)
		System.out.print("  ");
	    if (key != null)
		System.out.print(key + " ");
	    System.out.print(tag);
	    if (value != null)
		System.out.print(" " + value);
	    System.out.println();

	    java.util.Iterator iterator = children.iterator();
	    while (iterator.hasNext())
		{
		    Node child = (Node) iterator.next();
		    child.print(depth + 1);
		}
	}
    }

    static boolean debug = false;

    /**
     * map from String key to Node.
     */
    java.util.Hashtable keys = new java.util.Hashtable();

    /**
     * return the Node with the specified key (e.g. "@I1@").
     */
    Node lookup(String key)
    {
	return (Node) keys.get(key);
    }
    
    void parseLine(String line)
    {
	int space1 = line.indexOf(' ');
	int level = Integer.parseInt(line.substring(0, space1));
	String key = null;
	int tagStart = space1 + 1;
	if (line.charAt(tagStart) == '@')
	    {
		int keyEnd = line.indexOf(' ', tagStart);
		key = line.substring(tagStart, keyEnd);
		tagStart = keyEnd + 1;
	    }
	String tag = null;
	String value = null;
	int tagEnd = line.indexOf(' ', tagStart);
	if (tagEnd == (-1))
	    {
		tag = line.substring(tagStart);
	    }
	else
	    {
		tag = line.substring(tagStart, tagEnd);
		value = line.substring(tagEnd + 1);
	    }

	if (debug)
	    {
		System.out.println("level = " + level);
		System.out.println("key = " + key);
		System.out.println("tag = " + tag);
		System.out.println("value = " + value);
		System.out.println();
	    }
	
	Node node = new Node(key, tag, value);
	while (level < stack.size())
	    stack.pop();
	stack.push(node);
	if (level > 0)
	    {
		Node parent = (Node) stack.elementAt(level - 1);
		parent.children.add(node);
	    }
    }

    /**
     * stack used while parsing.
     */
    java.util.Stack stack = new java.util.Stack();

    /**
     * parse the specified file and return a tree representation.
     */
    static GEDCOM parseFile(String path)
	throws Exception
    {
	GEDCOM retval = new GEDCOM();

	java.io.BufferedReader stream = new java.io.BufferedReader(new java.io.FileReader(path));
	String line;
	while ((line = stream.readLine()) != null)
	    {
		retval.parseLine(line);
	    }

	return retval;
    }
}
