// file: DiGraph.java
//
// Last Author: Ryan Irwin
//

// Testing post-commit script again for the nth time.

// Small change for testing 
// import java libraries
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.util.*;
import java.io.*;
import java.lang.*;
import java.net.*;

/**
 * Main class of application that handles the frames actions and stores
 * input data
 */
public class DiGraph extends JFrame implements ActionListener, MouseListener,
					       MouseMotionListener, Constants {

    // ---------------------------------------------------
    //
    // declare class member data
    //
    // ---------------------------------------------------

    // keep track the current vertex in focus
    //
    public Vertex systemVertex = null;
    public Vertex inVertex = null;
    public Vertex outVertex = null;
    public Vertex initVertexFocus = null;
    public Vertex cfgVertexFocus = null;
    public Vertex currVertexFocus = null;

    // differentiate between parent and child 
    //
    public Vertex vertexParent = null;
    public Vertex vertexChild = null;

    // various types of been in the work area
    //
    public Vector<Vertex> vertices = null;
    public Vector<String> coeffLabels = null;
    public Vector<String> dataLabels = null;

    // flag that enables insertion and removal of arcs
    //
    public boolean enableArcInsertion = false;
    public boolean enableArcDeletion = false;

    // flag that enables insertion and removal of Component
    //
    public boolean enableCompDeletion = false;

    // flag that determines if input block exists
    //
    public boolean inputBlockExist = false; 

    // flag that determines if output block exists
    //
    public boolean outputBlockExist = false; 

    // target of the front end for output data type
    //
    public String targetStr = null;

    // input data type
    //
    public String inputDataStr = SAMPLED_DATA_STR;

    // current save status flag
    //
    public boolean saveWork = false;

    // vector of selected vertices
    //
    public Vector<Vertex> selectedVertices = null;

    // clipboard to handle things like cut, copy and paste
    //
    public Vector<Vertex> clipboard = null;

    // hash tables for quick reference
    //
    public Hashtable<String, Vertex> tagToVertex = null;

    // holds the maximum width and height of the scroller
    //
    public int maxWidth = WORKAREA_WIDTH;
    public int maxHeight = WORKAREA_HEIGHT;

    // holds the current location of the mouse
    //
    public int mouseXloc = 0;
    public int mouseYloc = 0;
    public int line_index = 0;

    // border for the viewport of the scrollpane
    //
    public Border border = null;

    // the label of the vertex that has been selected form the tool bar
    //
    public String currVertexLabel= null;

    // record the maximum number of inputs generated
    //
    public int maxInputVertices = 0;

    // algorithm association for the processes
    //
    public Association currAssociation = null;

    // maximum width and height of the work area
    //
    public int loadWidthMax = Integer.MIN_VALUE;
    public int loadHeightMax = Integer.MIN_VALUE;

    // input/output block type and impl
    //
    public int iotype = -1;
    public int ioimpl = -1;

    // varaible name in input block 
    //
    public String inputVariable = null;

    // varaible name in output block 
    //
    public String outputVariable = null;

    // creates a fram to manipulate the configuration options
    //
    public JFrame config = null;

    // textfields and labels for the connector properties
    //
    public JLabel toLabel = null;
    public JLabel fromLabel = null;
    public JLabel nameLabel = null;

    public JTextField toField = null;
    public JTextField fromField = null;
    public JTextField nameField = null;

    // main menu for functionality
    //
    public MainMenu mainMenu = null;

    // work area to drag and drop components
    //
    public WorkArea workArea = null;

    // paramenet file to be written to
    //
    public File paramFile = null;

    // scroll bars for the work area
    //
    public JScrollPane scroller = null;

    // declare the popup menu objects
    //
    public JPopupMenu popup = null;
    public JMenuItem menuItem = null;

    // default strings for the popup menus
    //
    public String ordering = null;
    public String delete = null;
    public String expand = null;
    public String configuration = null;
    public String label = null;
    public String apply = null;
    public String update = null;
    public String cancel = null;
    public String saveApprove = null;
    public String loadApprove = null;

    // default number for duration
    //
    public double frame_duration = 0.01;
    public double signal_duration = 0.1;
    public double sample_frequency = 8000.0;

    // data object for reading the algorithm resource file
    //
    public Data data = null;
    public Parser parser = null;

    // ---------------------------------------------------
    //
    // declare class constructors
    //
    // ---------------------------------------------------

    /**
     * default class constructor
     *
     * @param title String title that is passed to the super() constructor
     */
    public DiGraph(String title) {
	
	// invoke the parent default constructor
	//
	super(title);

	//instantiate the data class
	//
	data = new Data();
	
	// run the parser
	//
	parser = new Parser(data);
	
	// initialize the vectors data members
	//
	vertices = new Vector<Vertex>(100, 50);
	coeffLabels = new Vector<String>(100, 50);
	dataLabels = new Vector<String>(100, 50);
	clipboard = new Vector<Vertex>(10, 10);
	selectedVertices = new Vector<Vertex>(100, 50);
	
	// initialize the hashtables 
	//
	tagToVertex = new Hashtable<String, Vertex>(50);

	// instantiate the process algorithm association
	//
	currAssociation = new Association();

	// initialize the popup menu strings
	//
	ordering = new String("Ordering");
	delete = new String("Delete");
	configuration = new String("Configuration");

	// create the popup menu for the process vertex
	//
	popup = new JPopupMenu();
	menuItem = new JMenuItem(configuration);
	menuItem.addActionListener(this);
	popup.add(menuItem);
	popup.addSeparator();

	menuItem = new JMenuItem(ordering);
	menuItem.addActionListener(this);
	popup.add(menuItem);

	menuItem = new JMenuItem(delete);
	menuItem.addActionListener(this);
	popup.add(menuItem);

	// set the font of the popup menu
	//
	popup.setFont(newCoeffFont);

	// create the menu to control functionality
	//
	mainMenu = new MainMenu(this);

	// create a work area to drag and drop components
	//
	workArea = new WorkArea(vertices, this);
	workArea.addMouseListener(this);
	workArea.addMouseMotionListener(this);

	// add scroll panes to the workarea
	//
	scroller = new JScrollPane(workArea, 
				   JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				   JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
	
	// set the dimensions of the scroller
	//
	scroller.setPreferredSize(new Dimension(MAX_WIDTH, MAX_HEIGHT));

	// add the components
	//
	this.getContentPane().add(mainMenu, BorderLayout.NORTH);
	this.getContentPane().add(scroller, BorderLayout.CENTER);
	mainMenu.add_components();

	// create and initialize input configuration vertex
	//
	inVertex = new Vertex("system", ALGORITHM, NONE);
	inVertex.association = "AudioFrontEnd";
	
	// to simplify the creation, the data vectors will be trimmed to
	// only include the transform we're looking at and saved into
	// these three vectors for use in a bit
	//
	Vector<Object> labels2 = new Vector<Object>(5,5);
	Vector<Object> types2 = new Vector<Object>(5,5);
	Vector<Object> values2 = new Vector<Object>(5,5);
	
	for(int j=data.association.indexOf(inVertex.association); 
	    j <= data.association.lastIndexOf(inVertex.association);
	    j++) {
	    if(j != -1) {
		labels2.add(data.name.get(j));
		types2.add(data.type.get(j));
		values2.add(data.values.get(j));
	    }
	}	
	
	// initialize the vertex to the default values for its type
	//
	inVertex.initializeConfig(labels2, values2, types2,
				    inVertex.association, data);
	
	// create and initialize output configuration vertex
	//
	outVertex = new Vertex("system", ALGORITHM, NONE);
	outVertex.association = "Audio_Output";
	
	// to simplify the creation, the data vectors will be trimmed to
	// only include the transform we're looking at and saved into
	// these three vectors for use in a bit
	//
	Vector<Object> labels3 = new Vector<Object>(5,5);
	Vector<Object> types3 = new Vector<Object>(5,5);
	Vector<Object> values3 = new Vector<Object>(5,5);
	
	for(int j=data.association.indexOf(outVertex.association); 
	    j <= data.association.lastIndexOf(outVertex.association);
	    j++) {
	    if(j != -1) {
		labels3.add(data.name.get(j));
		types3.add(data.type.get(j));
		values3.add(data.values.get(j));
	    }
	}	
	
	// initialize the vertex to the default values for its type
	//
	outVertex.initializeConfig(labels3, values3, types3,
				    outVertex.association, data);

    }


    /**
     * resets the parent and child relationships
     */
    public void resetVertexFocus() {
	
	// reset the parent and child focus
	//
	vertexChild = null;
	vertexParent = null;

	// reset the current vertex selected
	//
	initVertexFocus = null;
	currVertexFocus = null;

	// reset the arc enables
	//
	enableArcInsertion = false;
	enableArcDeletion = false;

	// reset component enables
	//
	enableCompDeletion = false;

	// repaint the workarea
	//
	workArea.repaint();
    }

    /**
     * updates the parent and child relationships
     * @param e input mouse event
     */
    public void updateVertexFocus(MouseEvent e) {
	
	// check to make sure that the vertex parent is valid
	//
	if (vertexParent == null) {
	    
	    // highligh the current vertex parent
	    //
	    vertexParent = (Vertex)e.getSource();
	}

	// initialize the child if the vertex parent is valid
	//
	else {

	    // initialize the child of the connection
	    //
	    vertexChild = (Vertex)e.getSource();
	}
    }

    /**
     * this method creates an algorithm object
     * @param algorithmstr name of the algorithm that fired the event
     */
    public void createAlgorithm(String algorithmstr) {

	// determine which algorithm fired the event
	//
	int action = data.association.indexOf(algorithmstr);
	
	// if the action is found in the list of transforms
	//
	if (action != -1) {
	    
	    String image_name = null;
	    String image_association= null;
	    String icon_name = null;
	    
	    // tells the program which transform it is looking to match
	    //
	    image_association = algorithmstr;
	    
	    // scans through the association until 
	    // it finds the largeIcon key
	    //
	    for(int j=data.association.indexOf(image_association); 
		j <= data.association.lastIndexOf(image_association); 
		j++) {
		
		if (j != -1) {
		    if (((String)(data.name.get(j))).equals(ALGORITHM_ICON_BIG)) {
			
			// sets the image_name to the value held 
			// in large icon
			//
			image_name = (String)data.values.elementAt(j);
		    }
		    if (((String)(data.name.get(j))).equals("iconName")) {
			
			// sets the image_name to the value held 
			// in large icon
			//
			icon_name = (String)data.values.elementAt(j);
		    }  
		}
	    }
	    
	    // check to see if the file exists. If it does not exist,
	    // use a default image.
	    //
	    if(image_name != null) {
		
		File image_file = new File(image_name);
		if (image_file.exists() == false)
		    image_name = ALGORITHM_DEFAULT;
	    }
	    else {
		image_name = ALGORITHM_DEFAULT;
	    }
	    
	    // create the vertex for the work area
	    //
	    ImageIcon vertex_icon = new ImageIcon(image_name);
	    if(image_association.equals("FourierTransform")) {
		image_name = GUI_PATH +"/lib/images/isip_transform_builder/icons/algorithm_00.gif";
		vertex_icon = new ImageIcon(image_name);
	    }

	    Vertex  vertex = new Vertex(vertex_icon , ALGORITHM);
	    vertex.setVertexName(algorithmstr);
	    if (algorithmstr.length() > 4) {
		vertex.setText(algorithmstr.substring(0, 4));
	    }
	    else {
		vertex.setText(algorithmstr);
	    }

	    if(algorithmstr.equals("Generator")) {
		vertex.setText("");
		vertex.setVertexImpl(INPUT);
	    }
	    if(algorithmstr.equals("FilterBank")) {
		vertex.setText("FilB");
	    }
	    if(image_association.equals("AudioFrontEnd")) {
		if(!inputBlockExist)
		    inputBlockExist = true;
		else {
		    JFrame frame = new JFrame("Warning");
		    JOptionPane.showMessageDialog(frame, "An input** block is already present.");	
		
		    // Create an instance of java.awt.Cursor
		    Cursor c = new Cursor ( Cursor.HAND_CURSOR );
		    
		    // Set cursor for the frame component
		    this.setCursor (c);
		    return;
		}
	    }
	    
            if(icon_name != null) {
		vertex.setText(icon_name);
		vertex.setIconName(icon_name);
	    }

	    // to simplify the creation, the data vectors will be
	    // trimmed to only include the transform we're looking
	    // at and saved into these three vectors for use in a
	    // bit
	    //
	    Vector<Object> labels = new Vector<Object>(5,5);
	    Vector<Object> types = new Vector<Object>(5,5);
	    Vector<Object> values = new Vector<Object>(5,5);
	    
	    for(int j=data.association.indexOf(image_association); 
		j <= data.association.lastIndexOf(image_association); 
		j++) {
		
		if(j != -1) {
		    labels.add(data.name.get(j));
		    types.add(data.type.get(j));
		    values.add(data.values.get(j));
		}
	    }	 
	    
	    // initialize the vertex to the default values for its type
	    //
	    vertex.initializeConfig(labels, values, types, 
				    image_association, data);
	    
	    // set the tool tip for the algorithm vertex
	    //
	    vertex.setToolTipText(vertex.association);
	    
	    // attach a mouse motion listener to the vertex
	    //
	    vertex.addMouseListener(this);
	    vertex.addMouseMotionListener(this);
	    
	    // set the current vertex selected
	    //
	    initVertexFocus = vertex;
	
	    // Create an instance of java.awt.Cursor
	    Cursor c = new Cursor ( Cursor.HAND_CURSOR );

	    // Set cursor for the frame component
	    this.setCursor (c);

	    // must act as if save of configure is done for proper
	    // output, 08/09/05 (ConfigBox, SubConfigBox, SubConfigBoxParam)
	    //
	    //   ActionEvent action_a = new ActionEvent(vertex,
	    //					 1001,
	    //					 "Configuration");
	    //this.actionPerformed(action_a);

	}
    }

    /**
     * this method creates a name data node (SAMPLE_DATA or FEATURES)
     * @param type assigned to iotype variable which is originally
     *  set to block (-1)
     * @param impl assigned to ioimpl variable which is originally 
     *  set to block (-1)
     */
    public void createIOData(int type, int impl) {
	iotype = type;
	ioimpl = impl;
	
	// Create an instance of java.awt.Cursor
	Cursor c = new Cursor ( Cursor.HAND_CURSOR );

	// Set cursor for the frame component
	this.setCursor (c);
    }

    /***********************************************
    // createData() has been commented as the input and output class
    // have become algorithm-like class
    // method: createData
    //
    // arguments:
    //   String label: data label
    //
    // this method creates a name data node (SAMPLE_DATA or FEATURES)
    //
    public void createData() {

	// declare local variables
	//
	Vertex vertex = null;

	// currently we only allow one sample input/output and one
	// feature input/output but not one of both
	//

	if ((dataLabels.contains(INPUT_STR)) &&  
	     (iotype == INPUT) && (ioimpl == INPUT)) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "An input** block is already present.");		

	    // Create an instance of java.awt.Cursor
	    //
	    Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
	    this.setCursor (c);

	    return;
	}
	
	if ((dataLabels.contains(OUTPUT_STR)) && 
	    (iotype == OUTPUT) && (ioimpl == OUTPUT)) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "An output block is already present.");
	   
	    // Create an instance of java.awt.Cursor
	    //
	    Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
	    this.setCursor (c);
	    
	    return;	    
	}
	
	if ((dataLabels.contains(INPUT_STR)) && 
	    (iotype == INPUT) && (ioimpl == INPUT)) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "An input block is already present.");
	    // Create an instance of java.awt.Cursor
	    //
	    Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
	    this.setCursor (c);
	    
	    return;	    
	}
	if ((dataLabels.contains(OUTPUT_STR)) && 
	    (iotype == OUTPUT) && (ioimpl == OUTPUT)) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "An output block is already present.");
	    // Create an instance of java.awt.Cursor
	    //
	    Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
	    this.setCursor (c);
	    
	    return;   
	}
	
	// when the type is SAMPLED_DATA
	//
	if (iotype == INPUT) {

	    // when the implementation is INPUT
	    //
	    if (ioimpl == INPUT) {

		// create a unique label for the input vertex
		//
		currVertexLabel = new String("Input");
		
		// create a vertex to be added in the work area
		//
		ImageIcon vertex_icon = new ImageIcon(INPUT_IMAGE);
		vertex = new Vertex(vertex_icon, currVertexLabel, 
				    INPUT, INPUT);
		dataLabels.addElement(SAMPLED_DATA_STR);
		dataLabels.addElement(INPUT_STR);

		// set the tool tip for the vertex
		//
		vertex.setToolTipText("Input");

		// set flag for input block
		//
		inputBlockExist = true;
	    }

	    // when the implementation is OUTPUT
	    //
	    if (ioimpl == OUTPUT) {

		// create a unique label for the input vertex
		//
		currVertexLabel = new String("Output");
		
		// create a vertex to be added in the work area
		//
		ImageIcon vertex_icon = new ImageIcon(OUTPUT_IMAGE);
		vertex = new Vertex(vertex_icon, currVertexLabel, 
				    OUTPUT, OUTPUT);
		dataLabels.addElement(SAMPLED_DATA_STR);
		dataLabels.addElement(OUTPUT_STR);

		// set the tool tip for the vertex
		//
		vertex.setToolTipText("Output");

		// set flag for input block
		//
		outputBlockExist = true;
		
		// add the output block name as the system target
		//
		targetStr = currVertexLabel;
       	    }
	}

	// when the type is FEATURE_DATA
	//
	else if (iotype == OUTPUT) {

	    // when the implementation is INPUT
	    //
	    if (ioimpl == INPUT) {

		// create a unique label for the input vertex
		//
		currVertexLabel = new String("Input");
		
		// create a vertex to be added in the work area
		//
		ImageIcon vertex_icon = new ImageIcon(INPUT_IMAGE);
		vertex = new Vertex(vertex_icon, currVertexLabel, 
				    INPUT, INPUT);
		dataLabels.addElement(FEATURE_DATA_STR);
		dataLabels.addElement(INPUT_STR);

		// set the tool tip for the vertex
		//
		vertex.setToolTipText("Input");
		
		// set flag for input block
		//
		inputBlockExist = true;
	    }
	    
	    // when the implementation is OUTPUT
	    //
	    if (ioimpl == OUTPUT) {

		// create a unique label for the input vertex
		//
		currVertexLabel = new String("Output");
		
		// create a vertex to be added in the work area
		//
		ImageIcon vertex_icon = new ImageIcon(OUTPUT_IMAGE);
		vertex = new Vertex(vertex_icon, currVertexLabel,
				    OUTPUT, OUTPUT);
		dataLabels.addElement(FEATURE_DATA_STR);
		dataLabels.addElement(OUTPUT_STR);

		// set the tool tip for the vertex
		//
		vertex.setToolTipText("Output");

		// set flag for input block
		//
		outputBlockExist = true;

		// add the output block name as the system target
		//
		targetStr =  currVertexLabel;	      
	    }
	}

	// when the type is GENERATOR
	//
	else if (iotype == GENERATOR_DATA) {

	    // when the implementation is INPUT
	    //
	    if (ioimpl == INPUT) {

		// create a unique label for the input vertex
		//
		currVertexLabel = new String(GENERATOR_DATA_STR);
		
		// create a vertex to be added in the work area
		//
		ImageIcon vertex_icon = new ImageIcon(GENERATOR_IMAGE);
		vertex = new Vertex(vertex_icon, currVertexLabel, 
				    GENERATOR_DATA, INPUT);
		vertex.association = "GENERATOR";
		dataLabels.addElement(GENERATOR_DATA_STR);
		dataLabels.addElement(INPUTGEN_STR);
		
		// to simplify the creation, the data vectors will be
		// trimmed to only include the transform we're looking
		// at and saved into these three vectors for use in a
		// bit
		//
		Vector<Object> labels = new Vector<Object>(5,5);
		Vector<Object> types = new Vector<Object>(5,5);
		Vector<Object> values = new Vector<Object>(5,5);
	    
		for(int j=data.association.indexOf("GENERATOR"); 
		    j <= data.association.lastIndexOf("GENERATOR"); 
		    j++) {
		
		    if(j != -1) {
			labels.add(data.name.get(j));
			types.add(data.type.get(j));
			values.add(data.values.get(j));
		    }
		}	 
	
		// initialize the vertex to the default values for its type
		//
		vertex.initializeConfigGen(labels, values, types, 
				"GENERATOR", data);
	
		// set the tool tip for the algorithm vertex
		//
		vertex.setToolTipText(vertex.association);
		
		
		// attach a mouse motion listener to the vertex
		//
				
		// set the current vertex selected
		//
		initVertexFocus = vertex;
		
	    }	    	   
	}

	// when the type is CUSTOM
	//
	else if (iotype == CUSTOM) {

	    // create a unique label for the input vertex
	    //
	    currVertexLabel = new String(CUSTOM_STR + maxInputVertices);
	    
	    // generate a new feature label if the original is not unique
	    //
	    while (coeffLabels.contains(currVertexLabel)) {
		maxInputVertices++;
		currVertexLabel = new String(CUSTOM_STR + maxInputVertices);
	    }
	    
	    // create a vertex to be added in the work area
	    //
	    ImageIcon vertex_icon = new ImageIcon(CUSTOM_IMAGE);
	    vertex = new Vertex(vertex_icon, currVertexLabel, 
				CUSTOM, NONE);
	    coeffLabels.addElement(currVertexLabel);

	    // set the tool tip for the vertex
	    //
	    vertex.setToolTipText("Custom Data");
	}

	// when the type is CONTAINER
	//
	else if (iotype == CONTAINER) {

	    // create a unique label for the input vertex
	    //
	    currVertexLabel = new String(CONTAINER_STR + maxInputVertices);
	    
	    // generate a new feature label if the original is not unique
	    //
	    while (coeffLabels.contains(currVertexLabel)) {
		maxInputVertices++;
		currVertexLabel = new String(CONTAINER_STR + maxInputVertices);
	    }
	    
	    // create a vertex to be added in the work area
	    //
	    ImageIcon vertex_icon = new ImageIcon(CONTAINER_IMAGE);
	    vertex = new Vertex(vertex_icon, currVertexLabel, 
				CONTAINER, NONE);
	    coeffLabels.addElement(currVertexLabel);

	    // set the tool tip for the vertex
	    //
	    vertex.setToolTipText("Container");
	}

	// we have an undefined type
	//
	else {
	    return;
	}
	
	// attach a mouse motion listener to the vertex
	//
	vertex.addMouseListener(this);
	vertex.addMouseMotionListener(this);       
	
	// add the vertex to the vector
	//
	vertex.setFont(newCoeffFont);

	// set the current vertex selected
	//
	initVertexFocus = vertex;
	
    }
    */


    /**
     * method initializes the container object
     * @return  new data buffer vertex
     */
    public Vertex initializeDataBuffer() {
	return (new Vertex());
    }

    // method: initializeContainer
    //
    // arguments:
    /**
     * method initializes the container object
     * @param name name of the container
     * @return  new container vertex
     */
    public Vertex initializeContainer(String name) {
	ImageIcon vertex_icon = new ImageIcon(CONTAINER_IMAGE);
	return (new Vertex(vertex_icon, name, CONTAINER, NONE));
    }

    // method: initializeAlgorithm
    //
    // arguments:
    //     // returns  : new algorithm vertex
    //
    // 
    //
    /**
     * method initializes the algorithm
     * @param name name of the algorithm object
     * @param file input file buffered reader
     * @param typeAlgo String value of algorithm type
     * @return vertex created in initialization
     */
    public Vertex initializeAlgorithm(String name, BufferedReader file, String typeAlgo) {

	// initialize variables
	//
	StringTokenizer tokens = null;
	String line = null;
	String type = typeAlgo;
	String image_name = null;
	String image_association= null;

	// when the name indicates a start or term vertex
	//
	if (name.equals(BUFFER_TAG)) {
	
	    // switch based on the type of the object
	    //
	    if (type.equals(INPUT_STR) || type.equals(INPUTGEN_STR)) {

		// declare local variables
		//
		Vertex START_VERTEX = new Vertex(new ImageIcon(ENTER_IMAGE), ALGORITHM);
		
		// set the location of the vertices
		//
		START_VERTEX.setLocation(new Point(INIT_START_XLOC, 
						   INIT_START_YLOC));
		
		// set the dimensions of the vertices
		//
		START_VERTEX.setSize(ICON_WIDTH, ICON_HEIGHT);
		START_VERTEX.setPreferredSize(new Dimension(ICON_WIDTH, 
							    ICON_HEIGHT));
		START_VERTEX.setMinimumSize(new Dimension(ICON_WIDTH, 
							  ICON_HEIGHT));
		START_VERTEX.setVertexWidth(ICON_WIDTH);
		START_VERTEX.setVertexHeight(ICON_HEIGHT);
		
		// set the font of the vertices
		//
		START_VERTEX.setFont(newCoeffFont);
		
		// set the type of the vertex
		//
		START_VERTEX.setType(INPUT);
		
		// set the vertex papameters
		//
		START_VERTEX.association = new String(BUFFER_TAG);
		START_VERTEX.names = new Vector<Object>();
		START_VERTEX.types = new Vector<Object>();
		
		// return the vertex
		//
		return START_VERTEX;
	    }
	     
	    if (type.equals(OUTPUT_STR)) {
		
		// declare local variables
		//
		Vertex TERM_VERTEX = new Vertex(new ImageIcon(EXIT_IMAGE), ALGORITHM);
		
		// set the location of the vertices
		//
		TERM_VERTEX.setLocation(new Point(INIT_TERM_XLOC, 
						  INIT_TERM_YLOC));
		
		// set the dimensions of the vertices
		//
		TERM_VERTEX.setSize(ICON_WIDTH, ICON_HEIGHT);
		TERM_VERTEX.setPreferredSize(new Dimension(ICON_WIDTH, 
							   ICON_HEIGHT));
		TERM_VERTEX.setMinimumSize(new Dimension(ICON_WIDTH, 
							 ICON_HEIGHT));
		TERM_VERTEX.setVertexWidth(ICON_WIDTH);
		TERM_VERTEX.setVertexHeight(ICON_HEIGHT);
		
		// set the font of the vertices
		//
		TERM_VERTEX.setFont(newCoeffFont);
		
		// set the type of the vertex
		//
		TERM_VERTEX.setType(OUTPUT);
		
		// set the vertex papameters
		//
		TERM_VERTEX.association = new String(BUFFER_TAG);
		TERM_VERTEX.names = new Vector<Object>();
		TERM_VERTEX.types = new Vector<Object>();	

		// return the vertex
		//
		return TERM_VERTEX;
	    }
	}

	// which transform it is looking to match?
	//
	name = name.replace('\"',' ');
	name = name.replace(';', ' ');
	name = name.trim();
	image_association = name;
	
	// scans through the association until it finds the largeIcon key
	//
	int start = data.association.indexOf(image_association);
	int stop = data.association.lastIndexOf(image_association);
	String icon_name =null;

	for(int j=start; j <= stop; j++) {
	    
	    if (j != -1) {
		if (((String)(data.name.get(j))).equals(ALGORITHM_ICON_BIG)) {
		    
		    // sets image_name to large icon
		    //
		    image_name = (String)data.values.elementAt(j);
		}
		if (((String)(data.name.get(j))).equals("iconName")) {
		    
		    // sets the image_name to the value held 
		    // in large icon
		    //
		    icon_name = (String)data.values.elementAt(j);
		}  
	    }
	}
	
	// check to see if the file exists
	//
	if (image_name != null) {
	    
	    File image_file = new File(image_name);
	    if (image_file.exists() == false) {
		image_name = ALGORITHM_SMALL_DEFAULT;
	    }
	}
	else {
	    image_name = ALGORITHM_LARGE_DEFAULT;
	}

	// create the vertex and add it to the vector
	//
	ImageIcon vertex_icon = new ImageIcon(image_name);

	if(image_association.equals("Generator")) {
	    vertex_icon = new ImageIcon(GENERATOR_IMAGE);
	}

	if(image_association.equals("FourierTransform")) {
	    image_name = GUI_PATH +"/lib/images/isip_transform_builder/icons/algorithm_00.gif";
	    vertex_icon = new ImageIcon(image_name);
	}

	Vertex algoVertex = new Vertex(vertex_icon , ALGORITHM);
	algoVertex.setVertexName(name);
	if (name.length() > 4) {
	    algoVertex.setText(name.substring(0, 4));
	}
	else {
	    algoVertex.setText(name);
	}
	
	if(image_association.equals("Generator")) {
	     algoVertex.setText("") ;
	}
	if(image_association.equals("FilterBank")) {
	    algoVertex.setText("FilB");
	}
       	if(icon_name != null) {
	    algoVertex.setText(icon_name);
	    algoVertex.setIconName(icon_name);
	}

	// to simplify the creation, the data vectors will be trimmed
	// to only include the transform we're looking at and saved
	// into these three vectors for use in a bit
	//
	Vector<Object> labels2 = new Vector<Object>(5,5);
	Vector<Object> types2 = new Vector<Object>(5,5);
	Vector<Object> values2 = new Vector<Object>(5,5);
	
	start = data.association.indexOf(image_association);
	stop = data.association.lastIndexOf(image_association);
	for(int j=start; j <= stop; j++) {
	    if(j != -1) {
		labels2.add(data.name.get(j));
		types2.add(data.type.get(j));
		values2.add(data.values.get(j));
	    }
	}
	
	// initialize the vertex to the default values for its type
	//
	if(image_association.equals("GENERATOR")) {

	    algoVertex.initializeConfigGen(labels2, values2, types2, 
					   image_association, data);
	}
	else {
	    algoVertex.initializeConfig(labels2, values2, types2, 
					image_association, data);
	}

	// return the initialize vertex
	//
	return algoVertex;
    }

    /**
     * method that removes the specified vertex from the work area as
     * well as removing all parent and corresponding children links
     *
     * @param target vertex to be removed
     */
    public void removeVertex(Vertex target) {

	// verify that the vertex to be deleted is valid
	//
	if (target == null) {
	    return;
	}

	// reset the vertex focus
	//
	resetVertexFocus();

	// get the parents of the traget and all accurances of target
	//
	Vector<Vertex> parents = target.getParents();
	for (int i=0; i<parents.size(); i++) {
	    if (((Vertex)(parents.elementAt(i))).containsChild(target)) {
		((Vertex)(parents.elementAt(i))).removeChild(target);
	    }
	}

	// get the children of the traget and all accurances of target
	//
	Vector<Vertex> children = target.getChildren();
	for (int i=0; i<children.size(); i++) {
	    if (((Vertex)(children).elementAt(i)).containsParent(target)) {
		((Vertex)(children.elementAt(i))).removeParent(target);
	    }
	}
	
	// remove the node form the work area
	//
	workArea.remove(target);
	vertices.remove(target);

	// remove the label from the vector depending on the implementation
	//
	
	if (target.association.equals("AudioFrontEnd")) {
	    iotype = -1;
	    inputBlockExist = false;	 
	}
	else if (target.getVertexImpl() == OUTPUT) {
	    dataLabels.remove(target.getText());
	    iotype = -1;
	    outputBlockExist = false;	
	    dataLabels.remove(OUTPUT_STR);
	}
	else {
	    coeffLabels.remove(target.getText());
	}

	// repaint the work area
	//
	workArea.repaint();
    }
  
    /**
     * method cuts the current vertex and adds it to the clipboard
     */
    public void cut() {

	// check for a valid vertex
	//
	if (currVertexFocus == null) {
	    return;
	}

	// clear the current contents of the clipboard
	//
	clipboard.removeAllElements();

	// add the vertex to the clipboard
	//
	clipboard.addElement(currVertexFocus);

	// remove the vertex 
	//
	removeVertex(currVertexFocus);

	// repaint the work area
	//
	workArea.repaint();
    }

    /**
     * method copies the current vertex and adds it to the clipboard
     */
    public void copy() {

	// check for a valid vertex
	//
	if (currVertexFocus == null) {
	    return;
	}

	// we cannot copy and paste SAMPLED_DATA and FEATURE
	// vertices, hence, we check for them here
	//
	if ((currVertexFocus.getVertexType() == INPUT) || 
	    (currVertexFocus.getVertexType() == OUTPUT)) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "You cannot paste Input or output block");
	    return;
	}
	if (currVertexFocus.association.equals("AudioFrontEnd")) {
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "You cannot paste Input or output block");
	    return;
	}

	// clear the current contents of the clipboard
	//
	clipboard.removeAllElements();

	// add the vertex to the clipboard
	//
	clipboard.addElement(currVertexFocus);

	// repaint the work area
	//
	workArea.repaint();
    }

    /**
     * method pastes the current vertex from the clipboard
     */
    public void paste() {

	// loop through each element in the clipboard and add them back
	//
	for(int i=0; i < clipboard.size(); i++) {

	    // get the vertex that we intend to paste
	    //
	    Vertex v = (Vertex)clipboard.elementAt(i);
	    
	    // create a copy of the vertex and remove all arcs
	    //
	    Vertex vertex = new Vertex(v);

	    // remove all parents and children associated with the vertex
	    //
	    vertex.vertexParents.removeAllElements();
	    vertex.vertexChildren.removeAllElements();

	    // attach a mouse motion listener to the vertex
	    //
	    vertex.addMouseListener(this);
	    vertex.addMouseMotionListener(this);

	    // set the font for the vertex
	    //
	    vertex.setFont(newCoeffFont);

	    // set the location of the vertex
	    //
	    Point coordinates = new Point(mouseXloc, mouseYloc);
	    vertex.setLocation(coordinates);
	    
	    // we need create a unique name for the current vertex
	    // if it is of type CUSTOM or CONTAINER
	    //
	    if ((vertex.getVertexType() == CUSTOM) ||
		(vertex.getVertexType() == CONTAINER)) {

		// when the old name does not exist reuse it
		//
		if (!coeffLabels.contains(vertex.getText())) {
		    currVertexLabel = vertex.getText();
		}

		// when the old name exist create a new copy
		//
		else {
		    int offset = -1;
		    currVertexLabel = vertex.getText();
		    while (coeffLabels.contains(currVertexLabel)) {
			offset++;
			currVertexLabel = vertex.getText() + offset;
		    }
		}

		// set the name of the vertex
		//
		if (currVertexLabel.length() > 3) {
		    vertex.setText(currVertexLabel.substring(0, 3));
		}
		else {
		    vertex.setText(currVertexLabel);
		}
		vertex.setVertexName(currVertexLabel);
		coeffLabels.addElement(currVertexLabel);
	    }

	    // add the element to the data structures
	    //
	    vertices.addElement(vertex);
	    workArea.add(vertex);
	}
	
	// repaint the work area
	//
	workArea.repaint();
    }

   
    /**
     * method expand the container vertex
     */
    public void expandContainer() {

	// check for validity
	//
	if (currVertexFocus == null) {
	    return;
	}
	if (currVertexFocus.getVertexType() != CONTAINER) {
	    return;
	}

	// declare the sub digraph
	//
	String title = new String("CONTAINER");
	SubDiGraph subdigraph = new SubDiGraph(title, 
				    currVertexFocus.vertexContainer);
	
	// resize and set the frame dimensions
	//
	subdigraph.pack();
	
	// center the frame to the screen
	//
	Dimension screenDim = 
	    Toolkit.getDefaultToolkit().getScreenSize(); 
	Rectangle frameDim = subdigraph.getBounds(); 
	subdigraph.setLocation((screenDim.width -
				frameDim.width + 100) / 2,
			       (screenDim.height -
				frameDim.height + 100) / 2); 
	
	// display the frame
	//
	subdigraph.setVisible(true);		    
    }

    /**
     * method clears out all memory, i.e., vectors and hash tables
     */
    public void clearAllMemory() {

	// reset the maximum number of vertices
	//
	maxInputVertices = 0;
	
	// reset the vertices
	//
	initVertexFocus = null;
	cfgVertexFocus = null;
	currVertexFocus = null;
	vertexParent = null;
	vertexChild = null;

	inputBlockExist = false;
	outputBlockExist = false;

	// clear out all vectors
	//
	vertices.removeAllElements();
	coeffLabels.removeAllElements();
	dataLabels.removeAllElements();
	clipboard.removeAllElements();
	selectedVertices.removeAllElements();
	
	// reset the current line index
	//
	line_index = 0;

	// clear out all hash tables
	//
	tagToVertex.clear();

	// clear out the work area
	//
	workArea.removeAll();
    }
    
    /**
     * writes the sof file
     */
    public void write() {

	// declare local variables
	//
	FileOutputStream fout = null;
	PrintWriter file = null;
	String line = null;

	// reset the save flag to indicate the obvious
	//
	saveWork = false;

	// open the selected file for writing
	//
	try {

	    // initialize the variables
	    //
	    line = new String();

	    // initialize the file output stream
	    //
	    fout = new FileOutputStream(paramFile);
	    file = new PrintWriter(fout);

	    // write the file header
	    //
	    file.println(HEADER_TAG_00);
	    file.println(HEADER_TAG_01);
	    file.println();

	    // write the system configuration parameters
	    //
	    writeSystem(file);
	    file.println();

	    // write the vertex data
	    //
	    for (int i=0; i < vertices.size(); i++) {

		// get the current vertex
		//
		Vertex vertex = (Vertex)vertices.elementAt(i);
 
		// write the data data if the vertex is a data
		//
		if ((vertex.getVertexType() == INPUT) ||
		    (vertex.getVertexType() == OUTPUT) ||
		    (vertex.getVertexType() == CUSTOM)) {
		    
		    // write the data tag
		    //
		    line = ALGO_TAG + " " + vertices.indexOf(vertex) + " @";
		    file.println(line);
		    

		    // write the data's location
		    //
		    Point point = vertex.getLocation();
		    file.println(LOCATION_KEY + " " + point.x + " " + point.y);
		    
		    // write the name tag
		    //
		    line = " name = " + BUFFER_TAG + ";";
		

		    file.println(line);

		    // write the variable tag
		    //
		    if (vertex.getVertexType() == CUSTOM) {
			line = " variable = " + vertex.getVertexName() + ";";
			file.println(line);
		    }
		    else if (vertex.getVertexType() == OUTPUT ) {
			line = " variable = " + "Output" + ";";
			file.println(line);
		    }
		    else {
			line = " variable = " + inputVariable + ";";
			file.println(line);
		    }

		    // write the implementation
		    //
		    if (vertex.getVertexImpl() == INPUT) {
			line = " type = " + INPUT_STR + ";";
			file.println(line);
			file.println();
		    }
		    else if (vertex.getVertexImpl() == OUTPUT) {
			line = " type = " + OUTPUT_STR + ";";
			file.println(line);
			file.println();
		    }
		    else {
			line = " type = " + INTERNAL_STR + ";";
			file.println(line);
			file.println();
		    }
		}
	    }

	    // write the algorithm data if the vertex is a container
	    //
	    for (int i=0; i < vertices.size(); i++) {
	
		// get the current vertex
		//
		Vertex vertex = (Vertex)vertices.elementAt(i);

		if (vertex.getVertexType() == CONTAINER) {

		    // write the container tag
		    //
		    int containerTag = vertices.indexOf(vertex);
		    line = ALGO_TAG + " " + containerTag + " @";
		    file.println(line);

		    // write the containers location
		    //
		    Point point = vertex.getLocation();
		    file.println(LOCATION_KEY + " " + point.x + " " + point.y);

		    // write the name tag
		    //
		    line = " name = " + CONTAINER_TAG + ";";
		    file.println(line);
		    
		    // write the variable tag
		    //
		    line = " variable = " + vertex.getVertexName() + ";";
		    file.println(line);		    

		    // write out the graph tag
		    //
		    file.println(" graph_tag = " 
				 + containerTag * CONT_OFFSET + ";");
		    file.println();		    

		    // retrieve the container
		    //
		    Vector container = vertex.vertexContainer;

		    // write the algorithm data contained
		    //
		    if (container != null) {
			for (int k=0; k < container.size(); k++) {

			    // get the current vertex
			    //
			    vertex = (Vertex)container.elementAt(k);

			    // write the start and term nodes
			    //
			    if (vertex.association != null) {

				// write the algorithm tag
				//
				int algorithmTag = (containerTag * CONT_OFFSET) + container.indexOf(vertex);
				line = ALGO_TAG + " " + algorithmTag + " @";
				file.println(line);

				// write the algorithm data
				//
				writeAlgorithmData(file, vertex);
				file.println();
			    }
			}

			// write the DiGraph header
			//
			file.println(DIGRAPH_TAG + containerTag * CONT_OFFSET + " @");

			// indicated that we have a weighted arc
			//
			file.println(WEIGHTED_KEY);


			// write the vertex information
			//
			writeDiGraphVertices(file, container, true, containerTag);
			
			// write the arcs information
			//
			writeDiGraphArcs(file, container, true, containerTag);
			file.println();
		    }
		}
	    }

	    // write the algorithm data if the vertex is a algorithm
	    //
	    for (int i=0; i < vertices.size(); i++) {


		// get the current vertex
		//
		Vertex vertex = (Vertex)vertices.elementAt(i);

		if (vertex.getVertexType() == ALGORITHM) {

		    // write the algorithm tag
		    //
		    line = ALGO_TAG + " " + vertices.indexOf(vertex) + " @";
		    file.println(line);
		    
		    // write the algorithm data
		    //
		    writeAlgorithmData(file, vertex);
		    file.println();
		}		
	    }


	    // write the generator data if the vertex is a generator
	    //
	    for (int i=0; i < vertices.size(); i++) {


		// get the current vertex
		//
		Vertex vertex = (Vertex)vertices.elementAt(i);

		if (vertex.getVertexType() == GENERATOR_DATA) {

		    // write the algorithm tag
		    //
		    //  line = GENERATOR_TAG + " " + vertices.indexOf(vertex) + " @";
		    line = ALGO_TAG + " " + vertices.indexOf(vertex) + " @";
		    file.println(line);
		    
		    // write the algorithm data
		    //
		    writeGeneratorData(file, vertex);
		    file.println();
		}		
	    }

	    // write the DiGraph header
	    //
	    file.println(DIGRAPH_TAG + "0 @");

	    // indicated that we have a weighted arc
	    //
	    file.println(WEIGHTED_KEY);

	    // write the vertex information
	    //
	    writeDiGraphVertices(file, vertices, false, -1);

	    // write the arcs information
	    //
	    writeDiGraphArcs(file, vertices, false, -1);

	    // close the file descriptor
	    //
	    file.close();
	}

	// catch and deal with any file I/O exceptions
	//
	catch(IOException e1) {}

    }

    /**
     * write the vertices that correspond to the digraph   
     *
     * @param file PrintWriter file descriptor
     * @param vec  vector of input vertices
     * @param flag indicating a container vertex
     * @param offset container sof tag 
     */
    public void writeDiGraphVertices(PrintWriter file, Vector vec, 
				     boolean flag, int offset) {

	// declare local variables
	//
	String line = null;

	// write the vertex tag
	//
	file.println(VERTICES_TAG);
	
	// loop over all vertices and write the vertex tags
	//
	for (int i=0; i < vec.size(); i++) {
	    int id = i+(offset * CONT_OFFSET);
	    if (i == vec.size() - 1) {
		if (flag) {
		    line = "        {" + id + ", {" + id + "}};";
		}
		else {
		    line = "        {" + i + ", {" + i + "}};";
		}
	    }
	    else {
		if (flag) {
		    line = "        {" + id + ", {" + id + "}},";
		}
		else {
		    line = "        {" + i + ", {" + i + "}},";
		}
	    }
	    file.println(line);		
	}	
    }
 


    /**
     * write the arcs that correspond to the digraph
     *
     * @param file PrintWriter file descriptor
     * @param vec  vector of input vertices
     * @param flag indicating a container vertex
     * @param offset container sof tag 
     */
    public void writeDiGraphArcs(PrintWriter file, Vector vec, 
				 boolean flag, int offset) {

	// declare local variables
	//
	String src = null;
	String dst = null;
	String line = null;

	// write the arc information
	//
	file.println(ARCS_TAG);
	
	// loop over all vertices and examine the children
	//
	boolean start = false;
	for (int i=0; i < vec.size(); i++) {
	    
	    // get the current vertex
	    //
	    Vertex vertex = (Vertex)vec.elementAt(i);
	    
	    // check if the vertex has any children
	    //
	    if (vertex.getOutDegree() > 0) {
		
		// get the vector of children
		//
		Vector children = (Vector)vertex.getChildren();
		
		// loop over all children and write the arcs
		//
		for (int j=0; j < children.size(); j++) {
		    
		    // get the current child
		    //
		    Vertex child = (Vertex)children.elementAt(j);
		    if (start) {
			file.println(",");
		    }
		    if (flag) {
			src = new String("" + (vec.indexOf(vertex) +
					       (CONT_OFFSET*offset)));
			dst = new String("" + (vec.indexOf(child) +
					       (CONT_OFFSET*offset)));
		    }
		    else {
			src = new String("" + vec.indexOf(vertex));
			dst = new String("" + vec.indexOf(child));
		    }
		    
		    // determine the position of the parent
		    //
		    int pos = 0;
		    Vector parents = child.getParents();
		    for (int k=0; k<parents.size(); k++) {
			if (vertex == parents.elementAt(k)) {
			    pos = k;
			    break;
			}
		    }
		    line = "        {" + src + ", " + dst + ", " + pos + "}";
		    file.print(line);
		    start = true;
		}
	    }
	}
	file.println(";");
    }
    
      /**
       * write the system configuration parameters
       * 
       * @param file PrintWriter file descriptor
       */
    public void writeSystem(PrintWriter file) {
	
	// get index for looping through and writing the system 
	// data to a file
	//
	String in_sample_frequency = null;
	String in_frame_duration = null;
	String in_signal_duration = null;
	String in_number_of_features = null;
	
	String in_file_format = null;
	String in_data_type = null;
	
	// write system config header
	//
	file.println(HEADER_TAG_03);

	// write the algorithm data if the vertex is a container
	//
	for (int i=0; i < vertices.size(); i++) {
	    
	    // get the current vertex
	    //
	    Vertex vertex = (Vertex)vertices.elementAt(i);
	    
	    if (vertex.association == "AudioFrontEnd") {
		inVertex = vertex;
		break;
	    }
	}

	// write the algorithm data
	//
	writeSystemData(file, inVertex);	
	if(inputBlockExist == true) {
	    file.println(" input_flag" 
			 + " = " + "true" 
			 + ";");
	}
	else {
	    file.println(" input_flag" 
			 + " = " + "false" 
			 + ";");
	}	
    }

    /**
     * write the data associated with each algorithm in the algorithm vertex
     *
     * @param file PrintWriter file descriptor
     * @param vertex algorithm vertex
     */
    public void writeSystemData(PrintWriter file, Vertex vertex) {

	// write the algorithm name to the file
	//
	file.println(" name = " + vertex.association + ";"); 
	
	if(inputBlockExist == false) {
	    String tmp1, tmp2, tmp3;

	    // float value3 = (float)sample_frequency;	    
	    // tmp3 = ""+ value3;
	    // file.println(" sample_frequency" 
	    //		 + " = " + tmp3 
	    //	 + ";");

	    float value2 = (float)frame_duration;	    
	    tmp2 = ""+ value2;
	    file.println(" frame_duration" 
			 + " = " + tmp2 
			 + ";");
	    float value1 = (float)signal_duration;
	    tmp1 = ""+ value1;
	    file.println(" signal_duration" 
			 + " = " + tmp1 
			 + ";");	
	}
	else {

	    // write the algorithm type to the file
	    //
	    if ((vertex.getType() == INPUT_STR) || 
		(vertex.getType() == OUTPUT_STR)) {
		file.println(" type = \"" + vertex.getType() + "\";"); 
	    }

	    // write all other data associated with algorithm
	    //
	    for(int i=0; i < vertex.names.size(); i++) {
		
		String type = vertex.types.get(i).toString();
		String name = vertex.names.get(i).toString();
		String value = vertex.values.get(i).toString();

		
		// Must parse strings to get defaults right
		//
		Character ch = new Character(value.charAt(0));

		if (ch == '[') {
		    
		    value = new String(removeFrontBracket(value));
		}

		// write nothing if the type is image
		//
		if (type.equals(ALGORITHM_IMAGE)) {}

		// write nothing if the variable name is buffer_mode
		//
		else if (name.equals(ALGORITHM_BUFF_MODE)) {}
		
		// write input class if the variable name is "input_data_type"
		//
		else if (name.equals("input_data_type")) {
		    if(value.equals("FEATURES")) {
			file.println(" input_data_type = FEATURES;");
			//file.println(" feature_input = {");
			inputVariable = "FEATURES";
		    }
		    else {
			file.println(" input_data_type = SAMPLED_DATA;");
			//file.println(" audio_input = {");
			inputVariable = "SAMPLED_DATA";
		    }
		}

		// add quotes to the value for output if the value is text
		//
		else if (type.equals(ALGORITHM_TEXT)) {

		    // skip it if there is no text
		    //
		    String text = (String)vertex.values.get(i);

		    text = text.trim();

		    if ( text.equals("")){
			text = "\"\"";
		    }
		    if(!text.equals("")) {
			file.println(" " + vertex.names.get(i) 
				     + " = \"" + vertex.values.get(i) + "\";");
		    }
		}
	    
		// output the subclass if the value is a class
		//
		else if(type.equals(ALGORITHM_CLASS)) {

		    writeSubClassData(file, vertex, i);
	
		    file.println(ALGORITHM_BREAK_00);
		}

		// output the subparam if the value is a param
		//
		else if(type.equals(ALGORITHM_PARAM)) {
		  
		    writeSubParamData(file, vertex, i);
		}
	    
		else {
		    String text = (vertex.values.get(i)).toString();

		    if (text.charAt(0) == '[') {

			text = removeFrontBracket(text);
			
		    }

		    text = text.trim();

		    if ( text.equals("")){
			text = "\"\"";
		    }
		    if(!text.equals(""))
			file.println(" " + vertex.names.get(i) 
				     + " = " + text + ";");

		}
	    } // end for loop
	}
    }

    /**
     * write the data associated with each algorithm in the algorithm vertex
     *
     * @param file PrintWriter file descriptor
     * @param vertex algorithm vertex
     *
     */
    public void writeAlgorithmData(PrintWriter file, Vertex vertex) {

	// declare local variables
	//
	Point position = null;

	// store the location of the connector 
	//
	position = (Point)vertex.getLocation();

	// write the location of the output to file
	//
	if (position != null) {
	    file.print(LOCATION_KEY + " " + position.x + " " + position.y);
	    file.println();
	}
	
	// write the algorithm type to the file
	//	
	if(vertex.association.equals("AudioFrontEnd") && inputBlockExist == true ) {
	    file.println(" name = " + "CoefficientLabel" + ";");
	    file.println(" variable = " + inputVariable + ";");
	    file.println(" type = " + "INPUT" + ";");

	}
	else {

	    // write the algorithm name to the file
	    //
	    file.println(" name = \"" + vertex.association + "\";"); 
	    
	    // write all other data associated with algorithm
	    //
	    for(int i=0; i < vertex.names.size(); i++) {
		
		String type = (String)(vertex.types.get(i));
		String name = (String)(vertex.names.get(i));

		// write nothing if the type is image
		//
		if (type.equals(ALGORITHM_IMAGE)) {}

		// write nothing if the variable name is buffer_mode
		//
		else if (name.equals(ALGORITHM_BUFF_MODE)) {}

		// add quotes to the value for output if the value is text
		//
		else if (type.equals(ALGORITHM_TEXT)) {

		    // skip it if there is no text
		    //
		    String text = (String)vertex.values.get(i);

		    text = text.trim();

		    if ( text.equals("")){
			text = "\"\"";
		    }
		    if(!text.equals("")) {
			file.println(" " + vertex.names.get(i) 
				     + " = \"" + vertex.values.get(i) + "\";");
			
		    }
		}
	    
		// output the subclass if the value is a class
		//
		else if(type.equals(ALGORITHM_CLASS)) {

		    writeSubClassData(file, vertex, i);
	
		    file.println(ALGORITHM_BREAK_00);
		}

		// output the subparam if the value is a param
		//
		else if(type.equals(ALGORITHM_PARAM)) {
		    writeSubParamData(file, vertex, i);	
		}
	    
		else {
		    String text = (vertex.values.get(i)).toString();

		    text = text.trim();

		    if ( text.equals("")){
			text = "\"\"";
		    }
		    if(!text.equals("")) {
			String tmp = null;
			tmp = ""+ vertex.names.get(i);

			if(tmp.equals("signal_duration") && !vertex.association.equals("AudioFrontEnd")) {
			    // do nothing
			}
			else if(tmp.equals("frame_duration") && !vertex.association.equals("AudioFrontEnd")) {
			    // do nothing
			}
			else {

			    String str = vertex.values.get(i).toString();

			    if (str.charAt(0) == '[') {
				
				str = removeFrontBracket(str);
			    }

			    file.println(" " + vertex.names.get(i) 
					 + " = " + str + ";");


			}
		    }
		}
	    } // end for(loop)
	} 
    }

    /**
     * write the data associated with each algorithm in the algorithm vertex
     *
     * @param file PrintWriter file descriptor
     * @param vertex algorithm vertex
     */
    public void writeGeneratorData(PrintWriter file, Vertex vertex) {

	// declare local variables
	//
	Point position = null;

	// store the location of the connector 
	//
	position = (Point)vertex.getLocation();

	// write the location of the output to file
	//
	if (position != null) {
	    file.print(LOCATION_KEY + " " + position.x + " " + position.y);
	    file.println();
	}

	// write the algorithm name to the file
	//
	file.println(" name = \"" + vertex.association + "\";"); 
		

	
	// write the algorithm type to the file
	//
	if ((vertex.getType() == INPUT_STR) || 
	    (vertex.getType() == OUTPUT_STR)) {
	    file.println(" type = \"" + vertex.getType() + "\";"); 
	}

	// write all other data associated with algorithm
	//
	for(int i=0; i < vertex.names.size(); i++) {

	    String type = (vertex.types.get(i)).toString();
	    String name = (vertex.names.get(i)).toString();

	    // write nothing if the type is image
	    //
	    if (type.equals(ALGORITHM_IMAGE)) {}

	    // write nothing if the variable name is buffer_mode
	    //
	    else if (name.equals(ALGORITHM_BUFF_MODE)) {}

	    // add quotes to the value for output if the value is text
	    //
	    else if (type.equals(ALGORITHM_TEXT)) {

		// skip it if there is no text
		//
		String text = (vertex.values.get(i)).toString();

		text = text.trim();

		if ( text.equals("")){
		    text = "\"\"";
		}
		if(!text.equals("")) {
		    file.println(" " + vertex.names.get(i) 
				 + " = \"" + vertex.values.get(i) + "\";");
		}
	    }
	    
	    // output the subclass if the value is a class
	    //
	    else if(type.equals(ALGORITHM_CLASS)) {
		
		
		// get a copy of the algorithm used to configure the subclass
		//
		int subclass_index = 0;

		for(int j=0; j < vertex.subclass.size(); j++) {
		    Vertex temp = (Vertex)vertex.subclass.get(j);
		    if (temp.association.equals((vertex.values.get(i)).toString()))
			subclass_index = j;
		}

		Vertex subclass_copy = 
		    (Vertex)vertex.subclass.get(subclass_index);

		// output the class name and open the brackets for outputting
		// the values of the subclass
		//
		file.println(" " + vertex.names.get(i) + " = {");

		// output all of the values of the subclass
		//
		for(int j=0; j < subclass_copy.values.size(); j++){

		    String subtype = (subclass_copy.types.get(j)).toString();
		    
		    if (subtype.equals(ALGORITHM_IMAGE)) { 
			
		    }

		    // add quotes to the value for output if the value is text
		    //
		    else if (subtype.equals(ALGORITHM_TEXT)) {
			
			// skip it if there is no text
			//
			String text = (vertex.values.get(i)).toString();

			text = text.trim();

			if ( text.equals("")){
			    text = "\"\"";
			}
			if(!text.equals("")) {
			    file.println(" " + vertex.names.get(i) 
					 + " = \"" + vertex.values.get(i) + "\";");
			}
		    }
	    
		    else if (subtype.equals(ALGORITHM_STRING)) {
			if(!subclass_copy.values.get(i).equals("")) {
			    file.println("   " + subclass_copy.names.get(j) 
					 + " = \"" + subclass_copy.
					 values.get(j) + "\";");
			}
		    }
		    else {
			file.println(" " + subclass_copy.names.get(j) 
				     + " = " + subclass_copy.values.get(j) 
				     + ";");
		    }
		}
		file.println(ALGORITHM_BREAK_00);
	    }

	
	    // output the sub parameters if the value is a parameter
	    //
	    else if(type.equals(ALGORITHM_PARAM)) {
		writeSubParamData(file, vertex, i);
	    }
	    else {
		String text = (vertex.values.get(i)).toString();

		text = text.trim();
		if ( text.equals("")){
		    text = "\"\"";
		}
		if ( ! text.equals("")){
		    file.println(" " + vertex.names.get(i) 
				 + " = " + vertex.values.get(i) + ";");
		}
	    }
	}
	
    }

    /**
     * write the data associated with each algorithm in the algorithm vertex
     *
     * @param file  PrintWriter file descriptor
     * @param vertex  algorithm vertex
     */
    public void writeSubParamData(PrintWriter file, Vertex vertex, int index) {


	// get a copy of the algorithm used to configure the subclass
	//
	int subparam_index = 0;
	
	for(int j=0; j < vertex.subparam.size(); j++) {

	    Vertex temp = (Vertex)vertex.subparam.get(j);
	    if (temp.association.equals((vertex.values.get(index)).toString())) {
		subparam_index = j;
		//break;
	    }

	}
	
	Vertex subparam_copy = 
	    (Vertex)vertex.subparam.get(subparam_index);

	// output all of the values of the subparam
	//
	for(int j=0; j < subparam_copy.values.size(); j++){

	    String subtype = (subparam_copy.types.get(j)).toString();
	    
	    if (subtype.equals(ALGORITHM_IMAGE)) { 
		
	    }
	    else if (subtype.equals(ALGORITHM_STRING)) {
		if(!subparam_copy.values.get(index).equals("")) {
		    file.println("   " + subparam_copy.names.get(j) 
				 + " = \"" + subparam_copy.
				 values.get(j) + "\";");
		}
	    }  
	    else if(subtype.equals(ALGORITHM_CLASS)) {
		writeSubClassData(file, subparam_copy, j);      
		file.println(ALGORITHM_BREAK_00);
	    }
	    else if(subtype.equals(ALGORITHM_PARAM)) {
		writeSubParamData(file, subparam_copy, j);
	    }
	    // add quotes to the value for output if the value is text
	    //
	    else if (subtype.equals(ALGORITHM_TEXT)) {

		// skip it if there is no text
		//
		String text = (subparam_copy.values.get(j)).toString();
		text = text.trim();
		
		if ( text.equals("")){
		    text = "\"\"";
		}
		if(!text.equals("")) {
		    file.println(" " + subparam_copy.names.get(j) 
				 + " = \"" + subparam_copy.values.get(j) + "\";");
		}
	    }
	    else {				
		String text = (subparam_copy.values.get(j)).toString();
		text = text.trim();
	
		//if (text.equals("")) {

		//  text = " ";
		//}
		
		// Must parse strings to get defaults right
		//
		if (text.length() != 0) {
		    
		    Character ch = new Character(text.charAt(0));

		    if (ch == '[') {
		    
			text = new String(removeFrontBracket(text));
		    }
		}

		if ( text.equals("")){
		    text = "\"\"";
		}
		if (!text.equals("")){
		    file.println(" " + subparam_copy.names.get(j) 
				 + " = " + text 
				 + ";");	
		}
	    	     
	    }
	}
    }


    /**
     * write the data associated with each algorithm in the algorithm vertex
     *
     * @param file PrintWriter file descriptor
     * @param vertex  algorithm vertex
     * @param i index of vertex
     */
    public void writeSubClassData(PrintWriter file, Vertex vertex, int i) {

		// get a copy of the algorithm used to configure the subclass
		//
		int subclass_index = 0;

		for(int j=0; j < vertex.subclass.size(); j++) {
		    Vertex temp = (Vertex)vertex.subclass.get(j);
		    if (temp.association.equals((vertex.values.get(i)).toString()))
			subclass_index = j;
		}

		Vertex subclass_copy = 
		    (Vertex)vertex.subclass.get(subclass_index);

		// output the class name and open the brackets for outputting
		// the values of the subclass
		//
		file.println(" " + vertex.names.get(i) + " = {");

		// output all of the values of the subclass
		//
		for(int j=0; j < subclass_copy.values.size(); j++){

		    String subtype = (subclass_copy.types.get(j)).toString();
		    
		    if (subtype.equals(ALGORITHM_IMAGE)) { 
			
		    }
		    else if (subtype.equals(ALGORITHM_STRING)) {
			if(!subclass_copy.values.get(i).equals("")) {
			    file.println("   " + subclass_copy.names.get(j) 
					 + " = \"" + subclass_copy.
					 values.get(j) + "\";");
			}
		    }
		    else if(subtype.equals(ALGORITHM_CLASS)) {
			writeSubClassData(file, subclass_copy, j);      
			file.println(ALGORITHM_BREAK_00);
		    }
		    else if(subtype.equals(ALGORITHM_PARAM)) {
			writeSubParamData(file, subclass_copy, j);

			
		    }

		    // add quotes to the value for output if the value is text
		    //
		    else if (subtype.equals(ALGORITHM_TEXT)) {

			
			// skip it if there is no text
			//
			String text = (vertex.values.get(i)).toString();

			text = text.trim();

			if ( text.equals("")){
			    text = "\"\"";
			}
			if(!text.equals("")) {
			    file.println(" " + vertex.names.get(i) 
					 + " = \"" + vertex.values.get(i) + "\";");
			}

		    }
		    else {
			String text = (subclass_copy.values.get(j)).toString();
			text = text.trim();

			// input area executes here


			// Must parse strings to get defaults right
			//
			Character ch = new Character(text.charAt(0));
			
			if (ch == '[') {
			    
			    text = new String(removeFrontBracket(text));
			}

			if ( text.equals("")){
			    text = "\"\"";
			}
			if (!text.equals("")){
			    file.println("   " + subclass_copy.names.get(j) 
					 + " = " + text
					 + ";");
			}
		    }
		}
}


    /**
     * reads the sof file
     */
    public void read() {

	// declare local variables
	//
	int xloc = 0;
	int yloc = 0;
	
	//Vector to store information for determing subclass
	//
	Vector<Object> paramInfo =  new Vector<Object>(5,5);
	
	String name = null;
	String tag = null;
	String line = null;
	String tmpName = null;

	Vertex vertex = null;
	FileReader fin = null;
	BufferedReader file = null;
	Point location = null;
	StringTokenizer tokens = null;
	String type = null;
	boolean dataBufferFlag = false;
	boolean algorithmFlag = false;
	boolean containerFlag = false;

	// clear out all existing memory
	//
	clearAllMemory();

	// open the selected file for writing
	//
	try {

	    // initialize the file output stream
	    //
	    tag = new String();
	    fin = new FileReader(paramFile);
	    file = new BufferedReader(fin);
	    
	    // read the lines form the file
	    //
	    while ((line = file.readLine()) != null) {

		// remove white spaces at the ends of the string
		//
		line = line.trim();
		line_index++;

		// check for the system configuration properties
		//
		if (line.equals(HEADER_TAG_03)) {
		    readSystem(file);
		}

		// check for algorithm objects
		//
		if (line.regionMatches(false, 0, ALGO_TAG, 0, 11)) {

		    // reset the flags
		    //
		    algorithmFlag = false;
		    containerFlag = false;
		    dataBufferFlag = false;

		    // parse the objects unique sof tag
		    //
		    tokens = new StringTokenizer(line);
		    tokens.nextToken();
		    tokens.nextToken();
		    tag = tokens.nextToken();

		    // mark the current position in the buffer stream
		    //
		    file.mark(100);

		    // read the rest of the data for the object
		    //
		    while ((line = file.readLine()) != null) {

			// reset the variables
			//
			name = null;
			type = null;
			boolean isCoeff = false;
			
			// remove leading and trailing white space letters
			//
			line = line.trim();
			line_index++;

			// break the loop when we have read the object 
			//
			if (line.regionMatches(false, 0, ALGO_TAG, 0, 11) ||
			    line.regionMatches(false, 0, ARCS_TAG, 0, 6) ||
			    line.regionMatches(false, 0, DIGRAPH_TAG, 0,15) ||
			    line.regionMatches(false, 0, VERTICES_TAG,0,10)) {

			    // reset the buffer to the last marked position
			    //
			    file.reset();
			    break;
			}

			// parse the location of the data object
			//
			if (line.regionMatches(false, 0, LOCATION_KEY, 0, 2)) {

			    // parse the X and Y coordinates
			    //
			    tokens = new StringTokenizer(line);
			    tokens.nextToken();
			    if (tokens.hasMoreTokens()) {
				String xstr = (tokens.nextToken()).trim();
				xloc = Integer.valueOf(xstr).intValue();
			    }
			    if (tokens.hasMoreTokens()) {
				String ystr = (tokens.nextToken()).trim();
				yloc = Integer.valueOf(ystr).intValue();
			    }

			    // set the location of the object
			    //
			    location = new Point(xloc, yloc);
			}

			// parse the name of the data object
			//
			if (line.regionMatches(false,0, NAME_KEY, 0,6)) {

			    // tokenize the line
			    //
			    tokens = new StringTokenizer(line, "=");
			    tokens.nextToken();
			    
			    // get the tag value of the object
			    //
			    int tagValue = Integer.valueOf(tag).intValue();

			    // get the name of the object
			    //
			    name = null;
			 
			    if (tokens.hasMoreTokens()) {
				name = tokens.nextToken(); 
				name = name.replace(';', ' ');
				name = name.trim();
				if (name.equals("\"CoefficientLabel\"")) {
				    isCoeff =true;				    				}
				name = name.replace('\"',' ');
				name = name.trim();
			    }

			    // determine if the name is valid
			    //
			    if (name == null) { break; }
			    
			    // determine if we are reading a data buffer object
			    //
			    if (name.equals(BUFFER_TAG) && !isCoeff &&
				(tagValue < CONT_OFFSET)) {
				dataBufferFlag = true;
				vertex = initializeDataBuffer();
				continue;
			    }
			    
			    // determine if we are reading a container object
			    // 
			    else if (name.equals(CONTAINER_TAG) &&
				     (tagValue < CONT_OFFSET)) {
				containerFlag = true;
				vertex = initializeContainer(name);
				continue;
			    }

			    // we must be reading a algorithm object
			    //
			    else {
				algorithmFlag = true;
				paramInfo = new Vector<Object>(5,5);

				// read the next line of the file
				//
				try {
				    line = file.readLine();
				    line_index++;
				}

				catch(IOException e) {
				    System.err.println();
				    System.err.println("---------------------------------------");
				    System.err.println("Caught IOException: " + e.getMessage());
				    System.err.println("Line Number: " + line_index);
				    System.err.println("File Line: " + line);
				    System.err.println("---------------------------------------");
				    System.exit(0);
				}
				catch(ArrayIndexOutOfBoundsException e) {
				    System.err.println();
				    System.err.println("---------------------------------------");
				    System.err.println("Caught ArrayIndexOutOfBoundsException: 1" + e.getMessage());
				    System.err.println("Line Number: " + line_index);
				    System.err.println("File Line: " + line);
				    System.err.println("---------------------------------------");
				    System.exit(0);
				}
				catch(NullPointerException e) {
				    System.err.println();
				    System.err.println("---------------------------------------");
				    System.err.println("Caught NullPointerException: " + e.getMessage());
				    System.err.println("Line Number: " + line_index);
				    System.err.println("File Line: " + line);
				    System.err.println("---------------------------------------");
				    System.exit(0);
				}	
				catch(Exception e) {
				    System.err.println();
				    System.err.println("---------------------------------------");
				    System.err.println("Caught Exception: " + e.getMessage());
				    System.err.println("Line Number: " + line_index);
				    System.err.println("File Line: " + line);
				    System.err.println("---------------------------------------");
				    System.exit(0);
				}
	    
				// tokenize the line
				//
				line = line.trim();
				tokens = new StringTokenizer(line, "=");
				String typestr = "" + tokens.nextToken();
				typestr = typestr.trim();
				String typeAlgo = null;

				// get the type of the object
				//
				if (tokens.hasMoreTokens()) {
				    typeAlgo = "" + tokens.nextToken();
				    typeAlgo = typeAlgo.replace('\"',' ');
				    typeAlgo = typeAlgo.replace(';', ' ');   
				    typeAlgo = typeAlgo.trim();

				}
				if(typestr.equals("type")) 
				   vertex = initializeAlgorithm(name, file, typeAlgo);
				else
				    vertex = initializeAlgorithm(name, file, typeAlgo);		
				int updateValue = vertex.names.indexOf(typestr);
				if(updateValue>=0) {
				    String type1 =""+vertex.types.get(updateValue);
				    if(type1.equals("enum")) {
					paramInfo.add(typeAlgo);   
				    }
				}
				if(isItemOfVertex(typestr, vertex)) {
				    readAlgorithmParams(typeAlgo, line, file, 
							vertex, typestr, updateValue);
				}

				continue;
			    }
			}

			// when the line contains data buffer parameters
			//
			if (!line.startsWith(COMMENT_TAG) &&
			    !line.equals("") && dataBufferFlag && !isCoeff) {

			    // get the key value pair
			    //
			    tokens = new StringTokenizer(line, "=");

			    // parse the name of the data object
			    //
			    if (line.regionMatches(false, 0, VARIABLE_KEY, 0, 10)) {
				// set the name of the object
				//
				tokens = new StringTokenizer(line, "=");
				tokens.nextToken();
				if (tokens.hasMoreTokens()) {
				    name = tokens.nextToken();
				    name = name.replace('\"',' ');
				    name = name.replace(';', ' ');
				    name = name.trim();
				    tmpName = name;	
				}
			    }
			    
			    // parse the type of the data object
			    //
			    if (line.regionMatches(false, 0, TYPE_KEY, 0, 6)) {
				
				// set the type of the object
				//
				tokens = new StringTokenizer(line, "=");
				tokens.nextToken();
				if (tokens.hasMoreTokens()) {
				    type = tokens.nextToken();
				    type = type.replace('\"',' ');
				    type = type.replace(';', ' ');
				    type = type.trim();
				    if (type.equals("INPUT")) {		
					vertex = inVertex;
					tmpName = "Inp";
					iotype = INPUT;
					ioimpl = INPUT;
					dataLabels.addElement(INPUT_STR);
				    }
				    else if (type.equals("OUTPUT")){
					dataLabels.addElement(OUTPUT_STR);
					tmpName = "Output";
					iotype = OUTPUT;
					ioimpl = OUTPUT;
				    }
				    if (vertex != null) {
					vertex.setVertexName(tmpName);
					if (tmpName.length() > 3) {
					    vertex.setText(tmpName.substring(0, 3));
					}
					else {
					    vertex.setText(tmpName);
					}		
					if(tmpName.equals("Generator")) {
					    vertex.setText("");
					}
				    }
				    
				    if ((vertex != null) && 
					(vertex.getVertexName() != null)) {
					
					vertex.setType(type);
				    }
				}			    
			    }
			}

			// when the line contains container parameters
			//
			if (!line.startsWith(COMMENT_TAG) &&
			    !line.equals("") && containerFlag) {

			    // parse the name of the data object
			    //
			    if (line.regionMatches(false, 0, VARIABLE_KEY, 0, 10)) {
				
				// set the name of the object
				//
				tokens = new StringTokenizer(line, "=");
				tokens.nextToken();
				if (tokens.hasMoreTokens()) {
				    name = tokens.nextToken();
				    name = name.replace('\"',' ');
				    name = name.replace(';', ' ');
				    name = name.trim();
				    if (vertex != null) {
					vertex.setVertexName(name);
					if (name.length() > 3) {
					    vertex.setText(name.substring(0, 3));
					}
					else {
					    vertex.setText(name);
					}

				    }
				}
			    }   
			}

			// when the line contains algorithm parameters
			//
			if (!line.startsWith(COMMENT_TAG) &&
			    !line.equals("") && algorithmFlag) {

			    // get the key value pair
			    //
			    tokens = new StringTokenizer(line, "=");

			    // make sure there is a key value pair
			    //
			    if (tokens.countTokens() == 2) {
				String key = (tokens.nextToken()).trim();
				int updateValue = vertex.names.indexOf(key);
				String copyKey = new String(key);
				key = tokens.nextToken();
				key = key.replace('\"',' ');
				key = key.replace(';', ' ');   
				key = key.trim();
				if(updateValue>=0) {
				    String type1 =""+vertex.types.get(updateValue);
				    if(type1.equals("enum")) {
					paramInfo.add(key);   
				    }
				}
				if(isItemOfVertex(copyKey, vertex)) {
				    readAlgorithmParams(key, line, file, 
							vertex, copyKey, updateValue);
				}
				else {
				    if(vertex.subparam.size() > 0) {
					readSubParams(key, line, 
						      file, vertex, copyKey, updateValue, paramInfo);
				    }
				}
			    }
			}

			// mark the current position in the buffer stream
			//
			file.mark(100);
		    }

		    // make sure that the vertex is valid
		    //
		    if (vertex == null) {
			break;
		    }
		    if(vertex.association.equals("Generator") || vertex.association.equals("Constant")) {

			for(int inf = 0; inf < vertex.values.size(); inf++) {
			    String tmp;
			    tmp ="" + vertex.names.get(inf);
			    if(tmp.equals("frame_duration")) {
				String duration = "" + (float)frame_duration;
				vertex.values.set(inf,duration);
			    }
			    if(tmp.equals("signal_duration")) {
				String duration = "" + (float)signal_duration;
				vertex.values.set(inf,duration);
			    }
			    if(tmp.equals("sample_frequency") && vertex.association.equals("Generator")) {
				String duration = "" + (float)sample_frequency;
				vertex.values.set(inf,duration);
			    }
			}
		    }
		    
		    // set the location of the object
		    //
		    vertex.setLocation(location);
		    loadWidthMax = location.x > loadWidthMax ? 
			location.x : loadWidthMax;
		    loadHeightMax = location.y > loadHeightMax ? 
			location.y : loadHeightMax;

		    // set the vertex font
		    //
		    vertex.setFont(newCoeffFont);

		    // get the integer equivalent of the tag
		    //
		    int tagValue = Integer.valueOf(tag).intValue();

		    // the vertex is part of some container
		    //
		    if (tagValue >= CONT_OFFSET) {
			
			// determine the container the vertex belongs to
			//
			int cval = (int)(tagValue/CONT_OFFSET);
			
			// get the container in order to add the vertex
			//
			String sval = new String("" + cval);
			Vertex cobj = (Vertex)tagToVertex.get(sval);
			
			// add the vertex to the container
			//
			cobj.insertContainerElement(vertex);
		    }
		    
		    // the vertex is part of the main panel
		    //
		    else {

			// attach a mouse motion listener to the vertex
			//
			if (!vertices.contains(vertex)) {
			    vertex.addMouseListener(this);
			    vertex.addMouseMotionListener(this);
			}
			
			// add the vertex to the required data structures
			//
			workArea.add(vertex);
			vertices.addElement(vertex);
		    }
		    tagToVertex.put(tag, vertex);
		}

		// check for directed arcs
		//
		if (line.regionMatches(false, 0, ARCS_TAG, 0, 6)) {

		    // mark the current position in the buffer stream
		    //
		    file.mark(100);

		    // read the rest of the data for the object
		    //
		    while ((line = file.readLine()) != null) {

			String parentTag = null;
			String childTag = null;
			String indexTag = null;
			Vertex childVertex = null;
			Vertex parentVertex = null;
			int index = 0;

			// remove leading and trailing white space letters
			//
			line = line.trim();
			line_index++;

			// break the loop when we have read the object 
			//
			if (line.regionMatches(false, 0, ALGO_TAG, 0, 11) ||
			    line.regionMatches(false, 0, ARCS_TAG, 0, 6) ||
			    line.regionMatches(false, 0, DIGRAPH_TAG, 0,15) ||
			    line.regionMatches(false, 0, VERTICES_TAG,0,10)) {

			    // reset the buffer to the last marked position
			    //
			    file.reset();
			    break;
			}

			// parse the parent and child tags
			//
			line = line.replace('{',' ');
			line = line.replace('}',' ');
			line = line.replace(',',' ');
			line = line.replace(';',' ');
			line = line.trim();

			if (!line.equals("")) {

			    // tokenize the line on white spaces
			    //
			    tokens = new StringTokenizer(line);
			    if (tokens.hasMoreTokens()) {
				parentTag = tokens.nextToken();
			    }
			    if (tokens.hasMoreTokens()) {
				childTag = tokens.nextToken();
			    }
			    if (tokens.hasMoreTokens()) {
				indexTag = tokens.nextToken();
			    }

			    // get the position 
			    //
			    index = Integer.valueOf(indexTag).intValue();

			    // get the parent and child vertices
			    //
			    if (parentTag != null) {
				parentVertex = (Vertex)tagToVertex.get(parentTag);
			    }
			    if (childTag != null) {
				childVertex = (Vertex)tagToVertex.get(childTag);
			    }
			    
			    // add the child to the parents children list
			    //
			    if ((parentVertex != null) && 
				(childVertex != null)) {
				parentVertex.addChild(childVertex);
				childVertex.addParent(parentVertex, index);
			    }
			}

			// mark the current position in the buffer stream
			//
			file.mark(100);
		    }
		}
	    }
	    
	    // close the file 
	    //
	    file.close();
	}

	catch(IOException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught IOException: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}
	catch(ArrayIndexOutOfBoundsException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught ArrayIndexOutOfBoundsException:2 " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}
	catch(NullPointerException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught NullPointerException: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}	
	catch(Exception e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught Exception: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}

	// update client's preferred size because the area 
	// taken up by the work area has gotten larger
	//
	workArea.setPreferredSize(new Dimension(loadWidthMax+100, 
						loadHeightMax+100));
	
	// let the scroll pane know to update itself
	// and its corresponding scroll bars
	//
	workArea.revalidate();

	// repaint the work area
	//
	workArea.repaint();
	
	iotype = -1;
    }

    /**
     * read the system configuration properties from the sof file
     *
     * @param file PrintWriter file descriptor
     */
    public void readSystem(BufferedReader file) {

	//Vector to store information for determing subclass
	//
	Vector<Object> paramInfo =  new Vector<Object>(5,5);	
	String name = null;
	String tag = null;
	String line = null;
	String tmpName = null;
	Vertex vertex = null;
	Point location = null;
	StringTokenizer tokens = null;
	String type = null;
	boolean dataBufferFlag = false;
	boolean algorithmFlag = false;
	boolean containerFlag = false;

	// open the selected file for writing
	//
	try {

	    // initialize the file output stream
	    //
	    tag = new String();
	    
	    // read the lines form the file
	    //
	    while ((line = file.readLine()) != null) {

		// remove white spaces at the ends of the string
		//
		line = line.trim();
		line_index++;

		// parse the name of the data object
		//
		if (line.regionMatches(false,0, NAME_KEY, 0,6)) {
		    
		    // tokenize the line
		    //
		    tokens = new StringTokenizer(line, "=");
		    tokens.nextToken();
			    
		    // get the name of the object
		    //
		    name = null;
		    
		    if (tokens.hasMoreTokens()) {
			name = tokens.nextToken(); 
			name = name.replace(';', ' ');
			name = name.trim();
			name = name.replace('\"',' ');
			name = name.trim();
		    }

		    // determine if the name is valid
		    //
		    if (name == null) { break; }

		    algorithmFlag = true;
		    paramInfo = new Vector<Object>(5,5);

		    // read the next line of the file
		    //
		    try {
			line = file.readLine();
			line_index++;
		    }

		    catch(IOException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught IOException: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }
		    catch(ArrayIndexOutOfBoundsException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught ArrayIndexOutOfBoundsException: 1" + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }
		    catch(NullPointerException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught NullPointerException: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }	
		    catch(Exception e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught Exception: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }
	    
		    
		   // tokenize the line
		   //
		    line = line.trim();		
		    tokens = new StringTokenizer(line, "=");
		    String typestr = "" + tokens.nextToken();
		    typestr = typestr.trim();
		    String typeAlgo = null;

		    // get the type of the object
		    //
		    if (tokens.hasMoreTokens()) {
			typeAlgo = "" + tokens.nextToken();
			typeAlgo = typeAlgo.replace('\"',' ');
			typeAlgo = typeAlgo.replace(';', ' ');   
			typeAlgo = typeAlgo.trim();
		    }

		    if (typestr.equals("sample_frequency")) {		
			try {
			    float value = Float.valueOf(typeAlgo).floatValue();
			    sample_frequency = value;
			}
			catch (java.lang.NumberFormatException event) {
			    JFrame frame = new JFrame("Warning");
			    String warningMessage = new 
				String("The value entered for " + 
				       typeAlgo + 
				       " is not a floating point number.");
			    JOptionPane.showMessageDialog(frame, warningMessage);			
			}
			  
		    }
		    if (typestr.equals("frame_duration")) {		
			try {
			    float value = Float.valueOf(typeAlgo).floatValue();
			    frame_duration = value;
			}
			catch (java.lang.NumberFormatException event) {
			    JFrame frame = new JFrame("Warning");
			    String warningMessage = new 
				String("The value entered for " + 
				       typeAlgo + 
				       " is not a floating point number.");
			    JOptionPane.showMessageDialog(frame, warningMessage);			
			}
			  
		    }
		    if(typestr.equals("type")) 
			inVertex = initializeAlgorithm(name, file, typeAlgo);
		    else
			inVertex = initializeAlgorithm(name, file, typeAlgo);
	
		    
		    
		    int updateValue = inVertex.names.indexOf(typestr);
		    if(updateValue>=0) {
			String type1 =""+inVertex.types.get(updateValue);
			if(type1.equals("enum")) {
			    paramInfo.add(typeAlgo);   
			}
		    }
		    
		    if(isItemOfVertex(typestr, inVertex)) {
			readAlgorithmParams(typeAlgo, line, file, 
					    inVertex, typestr, updateValue);
		    }
		    
		    continue;
		}
	    	    	    
		// when the line contains algorithm parameters
		//
		if (!line.startsWith(COMMENT_TAG) &&
		    !line.equals("") && algorithmFlag) {

		    // tokenize the line
		    //
		    line = line.trim();		

		    // get the key value pair
		    //
		    tokens = new StringTokenizer(line, "=");
		
		    // make sure there is a key value pair
		    //
		    if (tokens.countTokens() == 2) {
			String key = (tokens.nextToken()).trim();
			int updateValue = inVertex.names.indexOf(key);
			String copyKey = new String(key);
			key = tokens.nextToken();
			key = key.replace('\"',' ');
			key = key.replace(';', ' ');   
			key = key.trim();		
			if (copyKey.equals("input_flag")) {
			    if(key.equals("true"))
				inputBlockExist = true;
			    else
				inputBlockExist = false;
			    break;
			}
	    
			if (copyKey.equals("frame_duration")) {
			    try {
			     float value = Float.valueOf(key).floatValue();
			     frame_duration = value;
			    }
			     catch (java.lang.NumberFormatException event) {
				 JFrame frame = new JFrame("Warning");
				 String warningMessage = new 
				     String("The value entered for " + 
					    key + 
					    " is not a floating point number.");
				 JOptionPane.showMessageDialog(frame, warningMessage);			
			     }
			  
			}
	
    			else if (copyKey.equals("signal_duration")) {
			    try {
			     float value = Float.valueOf(key).floatValue();
			     signal_duration = value;
			    }
			     catch (java.lang.NumberFormatException event) {
				 JFrame frame = new JFrame("Warning");
				 String warningMessage = new 
				     String("The value entered for " + 
					    key + 
					    " is not a floating point number.");
				 JOptionPane.showMessageDialog(frame, warningMessage);			
			     }
			}	

			if(updateValue>=0) {
			    String type1 =""+inVertex.types.get(updateValue);
			    if(type1.equals("enum")) {
				paramInfo.add(key);   
			    }
			}

			if(isItemOfVertex(copyKey, inVertex)) {
			    readAlgorithmParams(key, line, file, 
						inVertex, copyKey, updateValue);
			}
			else {
			    if(inVertex.subparam.size() > 0) {
				readSubParams(key, line, 
					      file, inVertex, copyKey, updateValue, paramInfo);
			    }
			}
		    }
		}

	    }
	}

	catch(IOException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught IOException: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}
	catch(ArrayIndexOutOfBoundsException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught ArrayIndexOutOfBoundsException:2 " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}
	catch(NullPointerException e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught NullPointerException: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}	
	catch(Exception e) {
	    System.err.println();
	    System.err.println("---------------------------------------");
	    System.err.println("Caught Exception: " + e.getMessage());
	    System.err.println("Line Number: " + line_index);
	    System.err.println("File Line: " + line);
	    System.err.println("---------------------------------------");
	    System.exit(0);
	}

	iotype = -1;
    }

    // method:isItemOfVertex
    //
    // arguments:
    //   String copykey: (input) token from the input line
    //   Vertex vertex: (input) current recipe
    // return : boolean
    //
    boolean isItemOfVertex(String copyKey, Vertex vertex) {
	for(int i=0; i < vertex.names.size(); i++) {

	    // if enumerated type, get the first value
	    //	
	    if(vertex.names.get(i).equals(copyKey)){
		return true;
	    }
	}
	return false;
    }

    /**
     * reads the algorithm parameters
     * 
     * @param key         token from the input line
     * @param line        current line that was read
     * @param file        file handler
     * @param vertex      current recipe
     * @param token4      more tokens
     * @param updateValue int type updated values
     */ 
    public void readAlgorithmParams(String key, String line, 
				    BufferedReader file, Vertex vertex, 
				    String token4, int updateValue) {

	Vector<Object> subparamInfo =  new Vector<Object>(5,5);

	// take care of any subclasses
	//
	if (key.equals(ALGORITHM_BREAK_02)) {

	    try {

		// read the next line of the file
		//
		line = file.readLine();
		line_index++;

		// keep reading until we find a delimiter
		//
		while (!line.trim().equals(ALGORITHM_BREAK_01) &&
		       !line.trim().equals(ALGORITHM_BREAK_00)) {
		    
		    StringTokenizer subToken3 = 
			new StringTokenizer(line, "=");
		    
		    key = subToken3.nextToken();
		    key = key.trim();
		    String copyKey = new String(key);

		    if(!key.startsWith(COMMENT_TAG)){ 

			int n1 = vertex.names.indexOf(token4);
			int n2 = -1;

			for (int k=0; k < vertex.subclass.size(); k++){

			    if (((Vertex)vertex.subclass.get(k)).association.
				equals((vertex.values.get(n1)).toString())) {
				n2 = k;
			    }

			}
				
			int updateValue2 = ((Vertex)vertex.subclass.get(n2)).names.indexOf(key);
		       
			key = subToken3.nextToken();
			key = key.replace('\"',' ');
			key = key.replace(';', ' ');   
			key = key.trim(); 
				

			if(updateValue2>=0) {
			    String type1 =""+((Vertex)vertex.subclass.get(n2)).types.get(updateValue2);
			    if(type1.equals("enum")) {
				subparamInfo.add(key);   
			    }
			}
			if(isItemOfVertex(copyKey, (Vertex)vertex.subclass.get(n2))) {
			    ((Vertex)vertex.subclass.get(n2)).values.set(updateValue2, key); 
			    readAlgorithmParams(key, line, file, 
						(Vertex)vertex.subclass.get(n2), copyKey, updateValue2);
			}
			else {
			    if(((Vertex)vertex.subclass.get(n2)).subparam.size() > 0) {
				readSubParams(key, line, 
					      file, (Vertex)vertex.subclass.get(n2), copyKey, updateValue2, subparamInfo);
			    }
			}

			//((Vertex)vertex.subclass.get(n2)).values.set(updateValue2, key); 
		    }

		    // read the next line of the file
		    //
		    line = file.readLine();
		    line_index++;
		}
	    }
	    catch(IOException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught IOException: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }
	    catch(ArrayIndexOutOfBoundsException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught ArrayIndexOutOfBoundsException:3 " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }
	    catch(NullPointerException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught NullPointerException: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }	
	    catch(Exception e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught Exception: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }	    
	}
	else {

	    // update the value with the corresponding key
	    //
	    vertex.values.set(updateValue, key); 

	}
    }

    /**
     * reads the configuration information for any subclasses
     * 
     * @param key         token from the input line
     * @param line        current line that was read
     * @param file        file handler
     * @param vertex      current recipe
     * @param token4      more tokens
     * @param updateValue int type updated values
     */ 
    public void readSubParams(String key, String line, 
			      BufferedReader file, Vertex vertex, 
			      String token4, int updateValue, 
			      Vector subInfo) {

	Vertex subparam_copy = (Vertex)vertex.subparam.get(0);
	String transform = subparam_copy.association;
	boolean isParentType = false;
	int     subStart = -1;
	int     tmpStart = -1;
	int     subEnd = -1;
	String delimit = null; 

	for(int index = 0; index < subInfo.size(); index++) {
	    subparam_copy.identify.add(subInfo.get(index));
	}

	for(int j=data.association.indexOf(transform); 
	    j <= data.association.lastIndexOf(transform);
	    j++) {
	    if(j != -1) { 
		if(!data.association.get(j).equals(transform) && subStart >=0) {
		    subEnd = j;
		    break;
		}
		if(subStart < 0) {
		    for(int k=0; k< subInfo.size(); k++) {
			String tmp1 ="["+ subInfo.get(k) + "]";
			tmp1.trim();
			String tmp2 = ""+data.values.get(j);

			//fixing strings
			//
			if (tmp1.charAt(0) == '[' && tmp1.charAt(1) == ' ') {
			    
			    tmp1 = new String("[" + tmp1.substring(2));
			}

			if(tmp2.equals(tmp1)) {			
			    if(k == 0) {
				tmpStart =j;
				if(0 != subInfo.size()-1) {
				   
				}
			    }
			    if(k == subInfo.size()-1) {
				delimit = (data.name.get(tmpStart)).toString();
				subStart = tmpStart;
				j++;
				break;
			    }
			    j++;
			}
			else {
			    break;
			}
		    }
		}	     
		if(subEnd < 0) {
		    String tmp3 = ""+data.name.get(j);
		    if(tmp3.equals(delimit)) {
			subEnd =j;
			break;
		    }
		    if(subEnd < 0 && j == data.association.lastIndexOf(transform)) {
			subEnd = j+1;
		    }
		}
	    }
	}
	
	subparam_copy.values = new Vector<Object>(5,5);
	subparam_copy.names = new Vector<Object>(5,5);
	subparam_copy.types = new Vector<Object>(5,5);

	Vector<Object> subparamInfo =  new Vector<Object>(5,5);
		
	// keep reading until we find a delimiter
	//
	for(int index = subStart+subInfo.size(); index < subEnd; index++) {
	    
	    // get the key value pair
	    //
	    StringTokenizer tokens = new StringTokenizer(line, "=");
	    
	    // make sure there is a key value pair
	    //
	    if (tokens.countTokens() == 2) {
		String key1 = (tokens.nextToken()).trim();
		String copyKey1 = new String(key1);
		key1 = tokens.nextToken();
		key1 = key1.replace('\"',' ');
		key1 = key1.replace(';', ' ');   
		key1 = key1.trim();

		// take care of any subclasses
		//
		if (key1.equals(ALGORITHM_BREAK_02)) {

		    String image_association = ""+data.values.get(index);

		    String image_name = null;
		    // scans through the association until it finds the
		    // smallIcon key
		    //
		    for(int j=data.association.indexOf(image_association); 
			j <= data.association.lastIndexOf(image_association);
			j++) {
			if(j != -1) {
			
			    if(((data.name.get(j)).toString()).equals("iconSmall")) {
				
				// sets the image_name to the value 
				// held in small icon
				//
				image_name = (data.values.get(j)).toString();
			    }
			}
		    }

		    // check to see if the file exists. If it does not exist,
		    // use a default image.
		    //
		    if(image_name != null){
			File image_file = new File(image_name);
			if (image_file.exists() == false) {
			    image_name = DEFAULT_PATH + "default.gif";
			}
		    }
		    else {
			image_name = DEFAULT_PATH + "default.gif";
		    }

		    // create the icons for the config panel
		    // 
		    ImageIcon icon = new ImageIcon(image_name);
		    
		    // create the button for the config panel
		    //
		    Vertex button = new Vertex(icon, ALGORITHM);
				
		    // to simplify the creation, the data vectors will be
		    // trimmed to only include the transform we're looking at
		    // and saved into these three vectors for use in a bit
		    //
		    Vector<Object> labels2 = new Vector<Object>(5,5);
		    Vector<Object> types2 = new Vector<Object>(5,5);
		    Vector<Object> values2 = new Vector<Object>(5,5);
		    
		    for(int j=data.association.indexOf(image_association); 
			j <= data.association.lastIndexOf(image_association);
			j++) {
			if(j != -1) {
			    labels2.add(data.name.get(j));
			    types2.add(data.type.get(j));
			    values2.add(data.values.get(j));
			}
		    }

		    // initialize the vertex to the default values for its type
		    //
		    button.initializeConfig(labels2, values2, types2,
					    image_association, data);
		
		    // attach an action listener to the button
		    //
		    button.setActionCommand("class");
		    button.addActionListener(this);

		    // add subclass button to the vector
		    //
		    subparam_copy.subclass.add(button);
		    subparam_copy.subclass.add(button);
		    subparam_copy.values.add(key1);
		    subparam_copy.names.add(data.name.get(index));
		    subparam_copy.types.add(data.type.get(index));

		    try {

			int n2 = -1;

			for (int k=subparam_copy.subclass.size()-1; k>=0; k--){
			    
			    if (((Vertex) subparam_copy.subclass.get(k)).association.equals(image_association)) {
				n2 = k;
			    }
			}

			// read the next line of the file
			//
			line = file.readLine();
			line_index++;

			// keep reading until we find a delimiter
			//
			while (!line.trim().equals(ALGORITHM_BREAK_01) &&
			       !line.trim().equals(ALGORITHM_BREAK_00)) {
		    
			    StringTokenizer subToken3 = 
				new StringTokenizer(line, "=");
		    
			    key = subToken3.nextToken();
			    key = key.trim();
			    String copyKey = new String(key);

			    if(!key.startsWith(COMMENT_TAG)){ 

				int updateValue2 = ((Vertex) subparam_copy.subclass.get(n2)).names.indexOf(key);
				
				key = subToken3.nextToken();
				key = key.replace('\"',' ');
				key = key.replace(';', ' ');   
				key = key.trim(); 
				
				if(updateValue2>=0) {
				    String type1 =""+((Vertex) subparam_copy.subclass.get(n2)).types.get(updateValue2);
				    if(type1.equals("enum")) {
					subparamInfo.add(key);   
				    }
				}
				if(isItemOfVertex(copyKey, (Vertex) subparam_copy.subclass.get(n2))) {
				    ((Vertex) subparam_copy.subclass.get(n2)).values.set(updateValue2, key);
				/*     
				    readAlgorithmParams(key, line, file, 
							(Vertex) subparam_copy.subclass.get(n2), copyKey, updateValue2);
				*/  
				}
				else {
				    if(((Vertex) subparam_copy.subclass.get(n2)).subparam.size() > 0) {
					readSubParams(key, line, 
						      file, (Vertex) subparam_copy.subclass.get(n2), copyKey, updateValue2, subparamInfo);
				    }
				}

				//((Vertex)vertex.subclass.get(n2)).values.set(updateValue2, key); 
			    }

			    // read the next line of the file
			    //
			    line = file.readLine();
			    line_index++;
			}
		    }
		    catch(IOException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught IOException: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }
		    catch(ArrayIndexOutOfBoundsException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught ArrayIndexOutOfBoundsException:3 " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }
		    catch(NullPointerException e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught NullPointerException: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }	
		    catch(Exception e) {
			System.err.println();
			System.err.println("---------------------------------------");
			System.err.println("Caught Exception: " + e.getMessage());
			System.err.println("Line Number: " + line_index);
			System.err.println("File Line: " + line);
			System.err.println("---------------------------------------");
			System.exit(0);
		    }	    
		}

		else {			
		    subparam_copy.values.add(key1);
		    subparam_copy.names.add(data.name.get(index));
		    subparam_copy.types.add(data.type.get(index));
		}
	    }
	    if(index == subEnd - 1)
		break;

	    // read the next line of the file
	    //
	    try {
	    line = file.readLine();
	    line_index++;
	    }    
	    catch(IOException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught IOException: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }
	    catch(ArrayIndexOutOfBoundsException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught ArrayIndexOutOfBoundsException:3 " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }
	    catch(NullPointerException e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught NullPointerException: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }	
	    catch(Exception e) {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Caught Exception: " + e.getMessage());
		System.err.println("Line Number: " + line_index);
		System.err.println("File Line: " + line);
		System.err.println("---------------------------------------");
		System.exit(0);
	    }	    
	}
    }
	
    // ---------------------------------------------------
    //
    // class required methods
    //
    // ---------------------------------------------------

    /**
     * Handles a mouse click event
     * @param e event that was fired
     */
    public void mouseClicked(MouseEvent e) {

	// declare local variables
	//
	boolean forwardLink = false;
	boolean reverseLink = false;

	Vertex conChild = null;
	Vertex conParent = null;

	// did the user click on the WorkArea with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("WorkArea")) {
	    
	    // reset the current focus
	    //
	    currVertexFocus = null;

	    if (SwingUtilities.isLeftMouseButton(e)) {

		// declare local variables
		//
		double smallestDistance = Double.MAX_VALUE;
		Vertex smallestParent = null;
		Vertex smallestChild = null;

		// has the arc deletion option been enabled?
		//
		if (enableArcDeletion) {		   

		    // set the save flag to indicate the obvious
		    //
		    saveWork = true;		    

		    // iterate through all vertices
		    //
		    for (int i=0; i<vertices.size(); i++) {
			
			// get the vertex which we will call the parent
			//
			Vertex delParent = (Vertex)vertices.elementAt(i);
			Vector delChildren = delParent.vertexChildren;

			// get the children associated with the parent
			//
			for (int j=0; j<delChildren.size(); j++) {
			    
			    // get a child of the current parent
			    //
			    Vertex delChild = (Vertex)delChildren.elementAt(j);
			    
			    // find the distance to the point of intersection 
			    // between the arc and the normal to the arc
			    //
			    Point ploc = delParent.getVertexLocation();
			    Point cloc = delChild.getVertexLocation();

			    // get the arc start coordinates
			    //
			    int x1 = ploc.x + (delParent.getVertexWidth() / 2);
			    int y1 = ploc.y + (delParent.getVertexHeight() / 2);

			    // get the arc stop coordinates
			    //
			    int x2 = cloc.x + (delChild.getVertexWidth() / 2);
			    int y2 = cloc.y;
			    int ypnt1 = y2 - (delChild.getVertexHeight() / 2) - VERTEX_MARGIN;
			    int ypnt2 = y2 + (delChild.getVertexHeight() / 2) + VERTEX_MARGIN;
			    
			    // determine the closest destination to the parent
			    //
			    int destVal = -1;
			    double currMax = 0.0;
			    double maxDist = Double.MAX_VALUE;
			    
			    // determine the distance to the first point
			    //
			    currMax = Math.abs(distance(x1, y1, x2, ypnt1));
			    if (currMax < maxDist) {
				destVal = 1;
				maxDist = currMax;			
			    }
			    
			    // determine the distance to the second point
			    //
			    currMax = Math.abs(distance(x1, y1, x2, ypnt2));
			    if (currMax < maxDist) {
				destVal = 2;
				maxDist = currMax;			
			    }
			    
			    // draw a directed arc form the parent to the child
			    //
			    y2 = (destVal == 1) ? ypnt1 : ypnt2;

			    // get the slope of the line
			    //
			    double m1 = 0.00001;
			    double dy = (double)(y2-y1);
			    double dx = (double)(x2-x1);
			    if (x2 != x1) {
				m1 = dy/dx;
			    }
			    double m11 = -1/m1;

			    // get the coordinates of the mouse click
			    //
			    int x = e.getX();
			    int y = e.getY();

			    // get the point of intersection
			    //
			    double x0 = ((-m11*x)+y+(m1*x1)-y1)/(m1-m11);
			    double y0 = (m11*x0)-(m11*x)+y;

			    // get the distance from the mouse click to the 
			    // point where the norlam intersects the line
			    //
			    double dist = Math.sqrt(Math.abs(((x-x0)*(x-x0))+((y-y0)*(y-y0))));
			    if (dist < smallestDistance) {
				smallestDistance = dist;
				smallestParent = delParent;
				smallestChild = delChild;
			    }			  
			}
		    }

		    // delete the arc that matches the constraints
		    //
		    if (smallestDistance > 0) {
			if ((smallestParent != null) && 
			    (smallestChild != null)) {
			    smallestParent.removeChild(smallestChild);
			    smallestChild.removeParent(smallestParent);
			}
		    }

		    // reset and repaint
		    //
		    resetVertexFocus();
		    return;
		}
		
		if (iotype >=0) {
		    //createData();
		    iotype = -1;
		}

		// is the newly created vertex valid?
		//
		if (initVertexFocus != null) {		    

		    // set the save flag to indicate the obvious
		    //
		    saveWork = true;		    

		    // get the current cursor's location
		    //
		    Point location = e.getPoint();
		    
		    // retrieve the vertex dimensions
		    //
		    int vertexWidth = initVertexFocus.getVertexWidth();
		    int vertexHeight = initVertexFocus.getVertexHeight();
		    
		    // center the vertex around the mouse cursor
		    //
		    location.x = location.x - (vertexWidth / 2);
		    location.y = location.y - (vertexHeight / 2);
		    
		    // set the location of the vertex
		    //
		    initVertexFocus.setLocation(location);
		    
		    // add the vertex to the work area
		    //
		    workArea.add(initVertexFocus);
		    vertices.add(initVertexFocus);
		    
		    // Create an instance of java.awt.Cursor
		    Cursor c = new Cursor ( Cursor.DEFAULT_CURSOR );
		    this.setCursor (c);
		    
		    // reset the focus
		    //
		    resetVertexFocus();		    
		    return;
		}
	    }
	}

	// did the user click on a vertex with the right mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if(SwingUtilities.isRightMouseButton(e)) {

		// set the save flag to indicate the obvious
		//
		saveWork = true;

		// get the vertex that is being referenced
		//
		cfgVertexFocus = (Vertex)e.getSource();

		// display the popup menu based on the vertex type
		//
		popup.show(e.getComponent(), e.getX(), e.getY());

		// reset the focus
		//
		resetVertexFocus();
		return;
	    }
	}

	// did the user click on a vertex with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if (SwingUtilities.isLeftMouseButton(e)) {	    
		if(enableCompDeletion) {
		    
		    // get the vertex that is being referenced
		    //
		    cfgVertexFocus = (Vertex)e.getSource();
		    removeVertex(cfgVertexFocus);
		    return;
		}
		else {

		    // set the save flag to indicate the obvious
		    //
		    saveWork = true;

		    // updates the vertex focus to highlight the current parent
		    //
		    updateVertexFocus(e);
		    
		    // exit the method if the vertex child is not instantiated
		    //
		    if (vertexChild == null) { 
			return; 
		    }

		    // the input vertices cannot have incoming arcs
		    //
		    if (vertexChild.getVertexImpl() == INPUT) {
			Toolkit.getDefaultToolkit().beep();
			resetVertexFocus();
			return;
		    }

		    // the output vertices cannot have outgoing arcs
		    //
		    if(vertexParent.getVertexImpl() == OUTPUT) {
			Toolkit.getDefaultToolkit().beep();
			resetVertexFocus();
			return;
		    }

		    // check for self loops and exit if it exists
		    //
		    if (vertexChild == vertexParent) {
			
			if ((vertexParent.getVertexType() == CONTAINER) &&
			    (vertexChild.getVertexType() == CONTAINER)) {
			    expandContainer();
			    resetVertexFocus();
			    return;
			}
			else {
			    Toolkit.getDefaultToolkit().beep();
			    resetVertexFocus();
			    return;
			}
		    }
		
		    // make sure are drawing is enabled
		    //
		    if (!enableArcInsertion) {
			resetVertexFocus();
			return;
		    }

		    // check for forward and backward edges
		    //
		    if (vertexParent.containsChild(vertexChild)) {
			forwardLink = true;
		    }
		    if (vertexChild.containsChild(vertexParent)) {
			reverseLink = true;
		    }

		    // if neither a forward nor backward link exist add
		    // the connector
		    //
		    if (!forwardLink && !reverseLink) {

		    // add the parent from the child lis and vice-versa
		    //
		    vertexParent.addChild(vertexChild);
		    vertexChild.addParent(vertexParent);
		    }
		    
		    // reset the vertex parent and vertex child pointers
		    //
		    resetVertexFocus();
		} //if(enabledComp)
	    }// end if(SwingUtilities.isLeftMouseButton(e)) {	
	}

	// update the work area
	//
	workArea.repaint();
    }

    /**
     * Calculates the distance between points
     *
     * @param x1 x-coordinate of the first point
     * @param y1 y-coordinate of the first point
     * @param x2 x-coordinate of the second point
     * @param y2 y-coordinate of the second point
     * @return double value  of distance between the points
     */
    public double distance(int x1, int y1, int x2, int y2) {

        double distance = 0.0;

        // calculate the euclidean distance
        //
        double deltaX = x2 - x1;
        double deltaY = y2 - y1;
        double sqrX = deltaX * deltaX;
        double sqrY = deltaY * deltaY;

        distance = Math.sqrt((double)sqrX + (double)sqrY);

        // return the distance
        //
        return distance;
    }

    /**
     * Handles a mouse press event
     * @param e event that was fired
     */
    public void mousePressed(MouseEvent e) {

	// did the user click on a vertex with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if (SwingUtilities.isLeftMouseButton(e)) {
		if (currVertexFocus != null) {
		    currVertexFocus.getModel().setSelected(false);
		}
		currVertexFocus = (Vertex)e.getSource();
		currVertexFocus.getModel().setSelected(true);
	    }
	}

	// repaint the work area
	//
	workArea.repaint();
    }
        
    /**
     * Handles a mouse drag event
     * @param e event that was fired
     */
    public void mouseDragged(MouseEvent e) {	

	// declare local variables
	//
	int xdelta = 0;
	int ydelta = 0;
	int newWidth = 0;
	int newHeight = 0;
	boolean forwardLink = false;
	boolean reverseLink = false;

	// did the user click on a vertex with the left mouse button?
	//
	if (e.getSource().getClass().getName().equals("Vertex")) {
	    if (SwingUtilities.isLeftMouseButton(e)) {

		// get the current location of the vertex
		//
		if (currVertexFocus != null) {

		    // determine the location and width of the vertex
		    //
		    Point loc = currVertexFocus.getVertexLocation();
		    
		    int vertexWidth = currVertexFocus.getVertexWidth();
		    int vertexHeight = currVertexFocus.getVertexHeight();
		    
		    int xloc = (loc.x + e.getX() - (vertexWidth / 2));
		    int yloc = (loc.y + e.getY() - (vertexHeight / 2));
		    
		    int xloc1 = loc.x + e.getX() + (vertexWidth / 2);
		    int yloc1 = loc.y + e.getY() + (vertexHeight / 2);

		    // make sure the user does not move the vertex out of
		    // the work area
		    //
		    if ((xloc >= 0) && (yloc >= 0)) {
			
			// determine the new width for the work area
			//
			if (xloc1 > workArea.getWidth()) {

			    xdelta = xloc1 - workArea.getWidth();
			    newWidth = workArea.getWidth() + xdelta;
			}
			
			// determine the new height for the work area
			//
			if (yloc1 > workArea.getHeight()) {
                            
			    ydelta = yloc1 - workArea.getHeight();
			    newHeight = workArea.getHeight() + ydelta;
			}

			// update the scroll bars of the work area
			//
			if ((xloc1 >= workArea.getWidth()) || 
			    (yloc1 >= workArea.getHeight())) {

			    // scroll the work area to the new region
			    //
			    Rectangle rect = new Rectangle(xloc, yloc, 
							   vertexWidth, 
							   vertexHeight);
			    workArea.scrollRectToVisible(rect);
			    
			    // make sure that the width and does not
			    // decrease, i.e., it does not scroll back
			    //
			    if (newWidth <= maxWidth) {
				newWidth = maxWidth;
			    } else {
				maxWidth = newWidth;
			    }
			    
			    // make sure that the height and does not
			    // decrease, i.e., it does not scroll back
			    //
			    if (newHeight <= maxHeight) {
				newHeight = maxHeight;
			    } else {
				maxHeight = newHeight;
			    }
			    
			    // update client's preferred size because the area 
			    // taken up by the work area has gotten larger
			    //
			    workArea.setPreferredSize(new Dimension(newWidth, 
								   newHeight));
			    
			    // let the scroll pane know to update itself
			    // and its corresponding scroll bars
			    //
			    workArea.revalidate();
			}
			
			// drag the vertex to the location the user specifies
			//
			currVertexFocus.setLocation(xloc, yloc);
			currVertexFocus.updateLocation(xloc, yloc);
		    }
		}

		// when the arc insertion is enabled
		//
		if (enableArcInsertion) {
		    
		    // set the save flag to indicate the obvious
		    //
		    saveWork = true;
		    
		    // updates the vertex focus to highlight the current parent
		    //
		    updateVertexFocus(e);
		    
		    // exit the method if the vertex child is not instantiated
		    //
		    if (vertexChild == null) { 
			return; 
		    }
		    
		    // the input vertices cannot have incoming arcs
		    //
		    if (vertexChild.getVertexImpl() == INPUT) {
			Toolkit.getDefaultToolkit().beep();
			resetVertexFocus();
			return;
		    }
		    
		    // the output vertices cannot have outgoing arcs
		    //
		    if(vertexParent.getVertexImpl() == OUTPUT) {
			Toolkit.getDefaultToolkit().beep();
			resetVertexFocus();
			return;
		    }
		    
		    // check for self loops and exit if it exists
		    //
		    if (vertexChild == vertexParent) {
			
			if ((vertexParent.getVertexType() == CONTAINER) &&
			    (vertexChild.getVertexType() == CONTAINER)) {
			    expandContainer();
			    resetVertexFocus();
			    return;
			}
			else {
			    Toolkit.getDefaultToolkit().beep();
			resetVertexFocus();
			return;
			}
		    }
		    
		    // check for forward and backward edges
		    //
		    if (vertexParent.containsChild(vertexChild)) {
			forwardLink = true;
		    }
		    if (vertexChild.containsChild(vertexParent)) {
			reverseLink = true;
		    }
		    
		    // if neither a forward nor backward link exist add
		    // the connector
		    //
		    if (!forwardLink && !reverseLink) {
			
			// add the parent from the child lis and vice-versa
			//
			vertexParent.addChild(vertexChild);
			vertexChild.addParent(vertexParent);
		    }
		    
		    // reset the vertex parent and vertex child pointers
		    //
		    resetVertexFocus();
		}

		// repaint the work area
		//
		workArea.repaint();
	    }
        }
    }
    
    /**
     * Handles a mouse release event
     * @param e event that was fired
     */
    public void mouseReleased(MouseEvent e) {
	// not yet implemented
    }
    
    /**
     * Handles a mouse move event
     * @param e event that was fired
     */
    public void mouseMoved(MouseEvent e) {
	
	// update the location of the mouse coordinates
	//
	mouseXloc = e.getX();
	mouseYloc = e.getY();
    }
    
    /**
     * Handles a mouse exit event
     * @param e event that was fired
     */
    public void mouseExited(MouseEvent e) {
	// this method is required to be present
    }

    /**
     * Handles a mouse enter event
     * @param e event that was fired
     */
    public void mouseEntered(MouseEvent e) {
	// this method is required to be present
    }

    /**
     * listens for actions taking place on the components
     *
     * @param e event that was fired
     */
    public void actionPerformed(ActionEvent e) {

	// determine if the delete option was selected
	//
	if (e.getActionCommand().equals(delete)) {
	    removeVertex(cfgVertexFocus);
	}

	// determine if the expand option was selected
	//
	else if (e.getActionCommand().equals(expand)) {
  
	    // ckeck for validity
	    //
	    if (cfgVertexFocus == null) {
		return;
	    }

	    // declare the sub digraph
	    //
	    String title = new String("CONTAINER");
	    SubDiGraph subdigraph = new SubDiGraph(title, 
						   cfgVertexFocus.vertexContainer);
	    
	    // resize and set the frame dimensions
	    //
	    subdigraph.pack();
	    
	    // center the frame to the screen
	    //
	    Dimension screenDim = 
		Toolkit.getDefaultToolkit().getScreenSize(); 
	    Rectangle frameDim = subdigraph.getBounds(); 
	    subdigraph.setLocation((screenDim.width -
				    frameDim.width + 100) / 2,
				   (screenDim.height -
				    frameDim.height + 100) / 2); 
	    
	    // display the frame
	    //
	    subdigraph.setVisible(true);
	}
	
	// determine if the configuration option was selected
	//
	else if (e.getActionCommand().equals(ordering)) {

	    // create a new configuration box and display in a new frame
	    //
	    if (cfgVertexFocus != null) {
		ConfigBox config_box = new ConfigBox(this, data, cfgVertexFocus, workArea, 1);
		config_box.pack();
		config_box.setVisible(true);
	    }
	}

	// determine if the configuration option was selected
	//
	else if (e.getActionCommand().equals(configuration)) {

	    // create a new configuration box and display in a new frame
	    //
	    if (cfgVertexFocus != null) {
	
		// create the configuration window for the algorithm
		//
		if (cfgVertexFocus.getVertexType() == ALGORITHM) {

		    ConfigBox config_box = new ConfigBox(this,data, 
							 cfgVertexFocus, 
							 workArea, 0);

		    // added to automatically save current subconfigurations
		    //
		    config_box.actionPerformed(new ActionEvent(this, 1000,
		    				     "param"));
		    
		    config_box.pack();

		    if (config_box.isDisplayable())
			config_box.setVisible(true);
		}

		// create the configuration window for the data
		//
		else {		   
		    // create a frame to display the properties
		    //
		    if (config != null) {
			config.setVisible(false);
		    }
		    config = new JFrame("Label");
		    Point xy = getLocation();
		    config.setLocation((int)xy.getX() + 100,(int)xy.getY() + 200);
		    nameField = new JTextField(10);
		    
		    // add a key listener to the textfield
		    //
		    nameField.addKeyListener(new KeyAdapter() { 
			    public void keyPressed(KeyEvent e) { 
				
				// determine if the enter key was pressed
				//
				if (e.getKeyCode() == e.VK_ENTER) {
				    
				    // check to see if a vertex with
				    // this label exists
				    //
				    if (coeffLabels.contains(nameField.getText())) {
					// display a warning message
					// indicating that you cannot
					// have two vertices with the
					// same name
					//
					JFrame frame = new JFrame("Warning");
					JOptionPane.showMessageDialog(frame, 
					       "A node with the label " + 
					            nameField.getText() + 
						       " already exists");
					return;
				    }
				    if (cfgVertexFocus.getVertexImpl() == NONE) {
					if (dataLabels.contains(nameField.getText())) {
					    // display a warning message
					    // indicating that you cannot
					    // have two vertices with the
					    // same name
					    //
					    JFrame frame = new JFrame("Warning");
					    JOptionPane.showMessageDialog(frame, 
						    "A node with the label " + 
						         nameField.getText() + 
							    " already exists");
					    return;
					}
				    }

				    // remove the old and add the new label
				    //
				    if (cfgVertexFocus.getVertexImpl() == NONE) {
					coeffLabels.remove(cfgVertexFocus.getVertexName());
					coeffLabels.addElement(nameField.getText());
				    }
				    else {
					dataLabels.remove(cfgVertexFocus.getVertexName());
					dataLabels.addElement(nameField.getText());
				    }

				    // update the vertex text with
				    // what the user entered
				    //
				    if (nameField.getText().length() > 3) {
					cfgVertexFocus.setText(nameField.getText().substring(0, 3));
				    }
				    else {
					cfgVertexFocus.setText(nameField.getText());
				    }
				    cfgVertexFocus.setVertexName(nameField.getText());
				    
				    // if the block is of type OUTPUT then
				    // update the system target
				    //
				    if (cfgVertexFocus.getVertexImpl() == OUTPUT) {
					targetStr = "" + cfgVertexFocus.getVertexName();
				    }
				    
				    // remove the frame from the screen
				    //
				    config.setVisible(false);
				}
			    }
			});
		    
		    // create labels to be included in the frame
		    //
		    nameLabel = new JLabel("Label: ");
		    nameLabel.setFont(newFont);
		    nameLabel.setForeground(Color.black);
		    
		    // create buttons for the frame
		    //
		    update = new String("Update");
		    JButton done = new JButton(update);
		    done.setFont(newFont);
		    done.addActionListener(this);
		    
		    cancel = new String("Cancel");
		    JButton ignore = new JButton(cancel);
		    ignore.setFont(newFont);
		    ignore.addActionListener(this);

		    // retrieve the text from the vertex and set the textfield
		    //
		    String text = cfgVertexFocus.getVertexName();
		    nameField.setText(text);
		    
		    // declare the default layout for the frame
		    //
		    config.getContentPane().setLayout(new GridLayout(2,2));

		    // add the textfields, labels and buttons to the frame
		    //
		    config.getContentPane().add(nameLabel);
		    config.getContentPane().add(nameField);
		    config.getContentPane().add(done);
		    config.getContentPane().add(ignore);
		    
		    // display the frame
		    //
		    config.pack();
		    config.setVisible(true);
		}
	    }	    
	}

	// detremine if the update was selected
	//
	else if (e.getActionCommand().equals(update)) {

	    // check to see if a vertex with this label exists
	    //
	    if (coeffLabels.contains(nameField.getText())) {

		// display a warning message indicating that you cannot have
		// two vertices with the same name
		//
		JFrame frame = new JFrame("Warning");
		JOptionPane.showMessageDialog(frame, "#A node with the label " 
					      + nameField.getText() + 
					      " already exists");
		return;
	    }
	    if (cfgVertexFocus.getVertexImpl() == NONE) {
		if (dataLabels.contains(nameField.getText())) {
		    
		    // display a warning message
		    // indicating that you cannot
		    // have two vertices with the
		    // same name
		    //
		    JFrame frame = new JFrame("Warning");
		    JOptionPane.showMessageDialog(frame, 
						  "A node with the label " + 
						  nameField.getText() + 
						  " already exists");
		    return;
		}
	    }
	    
	    // remove the old and add the new label
	    //
	    if (cfgVertexFocus.getVertexImpl() == NONE) {
		coeffLabels.remove(cfgVertexFocus.getVertexName());
		coeffLabels.addElement(nameField.getText());
	    }
	    else {
		dataLabels.remove(cfgVertexFocus.getVertexName());
		dataLabels.addElement(nameField.getText());
	    }

	    // update the vertex text with what the user entered
	    //
	    if (nameField.getText().length() > 3) {
		cfgVertexFocus.setText(nameField.getText().substring(0, 3));
	    }
	    else {
		cfgVertexFocus.setText(nameField.getText());
	    }
	    cfgVertexFocus.setVertexName(nameField.getText());

	    // if the block is of type OUTPUT then
	    // update the system target
	    //
	    if (cfgVertexFocus.getVertexImpl() == OUTPUT) {
		targetStr = "" + cfgVertexFocus.getVertexName();
	    }
	    
	    // remove the frame from the screen
	    //
	    config.setVisible(false);
	}

	// detremine if the cancel was selected
	//
	else if (e.getActionCommand().equals(cancel)) {

	    // remove the frame from the screen
	    //
	    config.setVisible(false);
	}

	// repaint the work area
	//
	workArea.repaint();
    }


    /**
     * Called if the first character of a value is a [ character
     *
     * @param val String to be fixed
     * @return fixed String
     */
    String removeFrontBracket(String val) {

	String fixed_value = new String();

	int z = 0;

	while (val.charAt(++z) != ',' && val.charAt(z) != ']') {
	    
	    Character ch1 = val.charAt(z);
	    
	    fixed_value = new String(fixed_value.concat(ch1.toString()));
	}

	return fixed_value;

    }

}

//
// end of file








