import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;
import java.util.*;
/**
 * UpdateParser is SAX XML Parser  used for parsing 
 */
public class UpdateParser extends XParser {
	/**
	 * The connections
	 * */
	Vector connections = null;
	/**
	 * The Patches 
	 * */
	Vector patches = null;
	/**
	 * The current connection being connected
	 * */
	Connection currConn = null;
	/**
	 * the currpoint used temporarily for making patches 
	 * */
	FromTo currPoint =null; //Temporary For Patches
	/**
	 * The time of the state of the system.
	 * */
	int time = 0;
	/**
	 * used when a tag opens
	 * */
	public void startElement( String namespaceURI, String localName, String qName, Attributes attr ) throws SAXException {
		super.startElement(namespaceURI,localName,qName,attr);
		if (localName.equals("update")) {
			connections = new Vector();
			patches = new Vector();
		} else if (localName.equals("connection")) {
			currConn = new Connection();
		} else if (localName.equals("patch")) {
			currPoint = new FromTo();
		} else {
		}
	}
	/**
	 * used when a tag Closes
	 * */
	public void endElement( String namespaceURI, String localName, String qName ) throws SAXException{
		super.endElement(namespaceURI,localName,qName);
		String value = contents.toString().trim();
		if ( localName.equals( "type" ) ) {
			int type = 0;
			if (value.equals("INPUT")) {
				type = Connection.INPUT;
			} else if (value.equals("OUTPUT")) {
				type = Connection.OUTPUT;
			} else if (value.equals("FILTER")) {
				type = Connection.FILTER;
			}
			currConn.setType(type);
		} else if (localName.equals( "name" ) ) {
			if (value.equals("")) {
				value = "UnNamed";
			}
			currConn.setName(value);
		} else if ( localName.equals("id")) {
			currConn.setID(parseInt(value));
		} else if ( localName.equals("from")) {
			currPoint.setFrom(parseInt(value));
		} else if ( localName.equals("to")) {
			currPoint.setTo(parseInt(value));
		} else if ( localName.equals("time")) {
			time = parseInt(value);
		} else if ( localName.equals("connection")) {
			connections.add(currConn);
		} else if ( localName.equals("patch")) {
			patches.add(currPoint);
		}
	}
	/**
	 * Gets a list of View Objects consisting of ConnectionBoxes and
	 * PatchLines
	 * */
	public Object [] getViewObjects() {
		LinkedList list = new LinkedList();
		HashMap map = new HashMap();
		Iterator iter = connections.iterator();
		int connSize = connections.size();
		while (iter.hasNext()) {
			ConnectionBox box = new ConnectionBox((Connection)iter.next());
			map.put(new Integer(box.getConnection().getID()),box);
			list.add(box);
		}
		iter = patches.iterator();
		while (iter.hasNext()) {
			FromTo p = (FromTo)iter.next();
			Integer from = new Integer(p.getFrom());
			Integer to = new Integer(p.getTo());
			ConnectionBox fromBox = (ConnectionBox)map.get(from);
			ConnectionBox toBox = (ConnectionBox)map.get(to);
			if (fromBox == null || toBox == null) {
				System.err.println("Do not have a connection for "+from+" to "+ to);
			} else {
				list.add(new PatchLine(fromBox,toBox));
			}
		}
		return list.toArray();
	}
	/**
	 * gets the time of the update 
	 * @return int the time
	 * */
	int getTime() {
		return time;
	}
	
	/**
	 * two integer struct class
	 * */
	class FromTo {
		int from=0;
		int to=0;
		FromTo() {
		}
		FromTo(int f,int t) {
			from = f; to = t;
		}
		int getFrom() { return from; } 
		int getTo() { return to; } 
		void setFrom(int i) { from=i; } 
		void setTo(int i) { to=i; } 
	}
}

