// file: ConfigBox.java
//

// 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 javax.swing.plaf.*;


/**
 * class that handles Configuration Box actions
 */
public class ConfigBox extends JDialog implements ActionListener, 
						 ItemListener, Constants {

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

    /**
     * data from the parsed text file
     */
    Data data = null;
    
    /**
     * scroll pane to hold all the parameter fields
     */
    JScrollPane scroll_pane = null;

    /**
     * panel to hold all the config data fields
     * to be mounted in a scrollable pane
     */
    JPanel config_panel = null;
    
    // Button to get values an return to process design box
    //
    JButton save_button = null;
    JButton cancel_button = null;
    JButton default_button = null;
    JButton help_button = null;
    JButton config_button = null;    

    /**
     * Vector to store information for determing subclass
     */
    Vector<Object> subparamInfo =  new Vector<Object>(5,5);

    /**
     * Vector of data
     */
    Vector<Object> enteredData = null;

    /**
     * Vector of data blocks
     */
    Vector<Object> blockType = null;

    /**
     * Vector of labels
     */
    Vector<Object> labelReference = null;

    /**
     * Vector of subclass vertices
     */
    Vector<Object> config_vertices = null;

    /**
     * Type of configuration box
     */
    int cfgType = 0;

    /**
     * Max number of subclasses
     */
    int max_subclass = 0;

    /**
     * Max number of subparam
     */
    int max_subparam = 0;

    /**
     * parameter button
     */
    Vertex buttonParam = null;

    /**
     * vertex that is being configured
     */
    Vertex cfgVertexFocus = null;

    /**
     * WorkArea that allows the return button to do a proper repaint
     */
    WorkArea workArea = null;

    /**
     * jlabels used to lable each of the items in the config box
     */
    public Vector<Object> labels = null;

    /**
     * digraph variable
     */
    public DiGraph par = null;

    /**
     * vectors user in a connector box configuration
     */
    Vector<JComboBox> connBox = null;

    /**
     * vectors user in a connector box configuration
     */
    Vector<JLabel> connLabels = null;

    /**
     * vectors user in a connector box configuration
     */
    Vector<Object> connection_order = null;

    SubConfigBoxParam class_config_panel = null;

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

    /**
     * default class constructor
     * @param parent  assigned to class par variable
     * @param d       assigned to class data variable
     * @param b       assigned to class cfgVertexFocus variable
     * @param area    assigned to class workArea variable
     * @param type    assigned to class cfgType variable
     */
    public ConfigBox(DiGraph parent, Data d, Vertex b, WorkArea area, int type) {

	// invoke the parent default constructor
	//
	super(parent,"Configuration Box", true);
	Point xy = parent.getLocation();
	setLocation((int)xy.getX() + 100,(int)xy.getY() + 200);

	// Set the configuration type
	//
	cfgType = type;

	// Make the passed Data object available globally
	//
	data = d;

	par = parent;

	// Initialize the enteredData and labelReference vectors for use
	//
	enteredData = new Vector<Object>(5,5);
	labelReference = new Vector<Object>(5,5);
	blockType = new Vector<Object>(5,5);
	
	// This is the vertex that is being configured
	//
	cfgVertexFocus = b;

	//Create this new panel with gridbag layout
	//
	config_panel =  new JPanel();
	addConfig();

	// make reference available globally for work area
	//
	workArea = area;
		
	//Set the sizes of the scroll pane and configuration panel
	//
	int height = labelReference.size() * 25;
	int width =  335 + 55;
	
	if (cfgType == 1) {
	    height = labelReference.size() * 25 + 75;
	    width =  335 + 55;
	}    
	
	config_panel.setSize(width,height);
	config_panel.setMinimumSize(new Dimension(width,height));
	config_panel.setPreferredSize(new Dimension(width,height));
	config_panel.setMaximumSize(new Dimension(width,height));

	//  create the appropriate string for the border
	//
	String border_title = null;
	if(cfgType == 0)
	    border_title = 
		new String(cfgVertexFocus.association + " Configuration:");
	else if (cfgType == 1){
	    border_title = 
		new String("Connector Configuration:");
	}

	// create the border and set the proper font
	//
	BorderUIResource.TitledBorderUIResource border =
	    new BorderUIResource.TitledBorderUIResource(border_title);
	border.setTitleFont(newFont);
	border.setTitleColor(Color.black);

	// make the config panel use the proper border
	//
	config_panel.setBorder(border);

	//Add the scroll pane to the frame
	//
	this.getContentPane().add(config_panel, BorderLayout.NORTH);
    }

    
    // ---------------------------------------------------
    //
    // declare class methods
    //
    // ---------------------------------------------------


    /**
     *  dynamically adds and constrains all objects on the JPanel
     */
    public void addConfig() {

	//  make this config panel use grid bag layout
	//
	GridBagLayout gridbag = new GridBagLayout();
	config_panel.setLayout(gridbag);

	// add the appropriate input values depending on whether the 
	// vertex being configured in a transform or a connector
	//
	if(cfgType == 0) {
	    addTransformConfig(gridbag);
	}
	else if (cfgType == 1){
	    addConnectorConfig(gridbag);
	}

	JPanel button_panel = new JPanel();
	if( max_subparam > 0) {

	    // create a button panel to place all buttons on so proper spacing 
	    // can be acheived
	    //	
	    button_panel.setLayout(new GridLayout(1,4, 1, 1));
	    
	    // create configure button and add the appropriate action handler
	    //
	    config_button = new JButton("Configure");
  	    button_panel.add(config_button);
	    config_button.addActionListener(this);
	    config_button.setActionCommand("param");
	    config_button.setFont(newFont);
	
	    // create the return button and add the appropriate action handler
	    //
	    save_button = new JButton("Save");
	    button_panel.add(save_button);
	    save_button.addActionListener(this);
	    save_button.setActionCommand("update");
	    save_button.setFont(newFont);
	
	    // create the cancel button and add to subpanel
	    //
	    cancel_button = new JButton("Cancel");
	    button_panel.add(cancel_button);
	    cancel_button.addActionListener(this);
	    cancel_button.setActionCommand("cancel");
	    cancel_button.setFont(newFont);

	    // create the help button and add to subpanel
	    //
	    help_button = new JButton("Help");
	    button_panel.add(help_button);
	    help_button.addActionListener(this);
	    help_button.setActionCommand("help");
	    help_button.setFont(newFont);
	}
	else {

	    // create a button panel to place all buttons on so proper spacing 
	    // can be acheived
	    //	
	    button_panel.setLayout(new GridLayout(1,4, 1, 1));
	    
	    // create the return button and add the appropriate action handler
	    //
	    save_button = new JButton("Save");
	    button_panel.add(save_button);
	    save_button.addActionListener(this);
	    save_button.setActionCommand("update");
	    save_button.setFont(newFont);
		
	    // create the cancel button and add to subpanel
	    //
	    cancel_button = new JButton("Cancel");
	    button_panel.add(cancel_button);
	    cancel_button.addActionListener(this);
	    cancel_button.setActionCommand("cancel");
	    cancel_button.setFont(newFont);
		
	    // create the default button and add to subpanel
	    //
	    default_button = new JButton("  Default ");
	    button_panel.add(default_button);
	    default_button.addActionListener(this);
	    default_button.setActionCommand("default");
	    default_button.setFont(newFont);
		
	    // create the help button and add to subpanel
	    //
	    help_button = new JButton("Help");
	    button_panel.add(help_button);
	    help_button.addActionListener(this);
	    help_button.setActionCommand("help");
	    help_button.setFont(newFont);		
	}
	
	// place the button panel onto the config panel
	//
	constrain(config_panel, button_panel, gridbag, 0, labels.size()+1,
		  GridBagConstraints.REMAINDER,1,1,1,
		  GridBagConstraints.SOUTH);

    }
   



    /**
     *  places all the proper input items onto the config panel 
     *  for configuring a connector box
     *
     * @param gridbag  gridbag layout for config panel
     */
    public void addConnectorConfig(GridBagLayout gridbag)  {
	
	// get the number of parents this connector vertex has
	//
	int size = cfgVertexFocus.getInDegree();
	
	// create a vector containing the names of all the connector's 
	// parents
	//
	labels = new Vector<Object>(5,5);

	// populate the names vector
	//
	for(int i=0; i < size; i++) {
	    Vertex vertex_parent = (Vertex)cfgVertexFocus.vertexParents.get(i);
	    String vertex_name = vertex_parent.getVertexName();
	    labels.add((i + 1) + ":" + vertex_name);
	}

	// create a vector of JLabels and JComboBox for use in swapping
	//
	connLabels = new Vector<JLabel>(size,1);
	connBox = new Vector<JComboBox>(size,1);
	connection_order = new Vector<Object>(size,1);

	// populate the vector's for display 
	//
	for(int i=0; i < labels.size(); i++) {
	    connLabels.add(new JLabel("Position " + (i+1)));
	    connBox.add(new JComboBox(labels));
	    ((JComboBox)connBox.get(i)).setSelectedIndex(i);
	    ((JComboBox)connBox.get(i)).addItemListener(this);
	}
	
	for(int i=0; i < labels.size(); i++) {
	  
	    // place the label onto the screen
	    //
	    ((JLabel)connLabels.get(i)).setForeground(Color.black);
	    constrain(config_panel,(JLabel)(connLabels.get(i)), gridbag, 0, i,
		      1, 1, 1, 0, GridBagConstraints.WEST);
	    ((JLabel)connLabels.get(i)).setFont(newFont);
	    labelReference.add((JLabel)connLabels.get(i));

	    // place the JComboBox on the screen
	    //
	    ((JComboBox)connBox.get(i)).setForeground(Color.black);
	    constrain(config_panel,((JComboBox)connBox.get(i)), gridbag, 1, i,
		      1, 1, 1, 0, GridBagConstraints.EAST);
	    ((JComboBox)connBox.get(i)).setFont(newFont);

	    // populate a vector to tell me connections made
	    //
	    Integer integer = new Integer(i);
	    connection_order.add(integer);
	}
    }

    /**
     * places all the proper input items onto the config panel 
     *  for configuring any transform
     *
     * @param gridbag  gridbag layout for config panel
     */
    public void addTransformConfig(GridBagLayout gridbag)  {
	
	// 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
	//
	labels = new Vector<Object>(5,5);
	Vector<Object> types = new Vector<Object>(5,5);
	Vector<Object> values = new Vector<Object>(5,5);
	String transform = cfgVertexFocus.association;
	int subclassIndex = 0;
	int subcparamIndex = 0;

	for(int j=data.association.indexOf(transform); 
	    j <= data.association.lastIndexOf(transform);
	    j++) {
	    if(j != -1) {
		labels.add(data.name.get(j));
		types.add(data.type.get(j));
		values.add(data.values.get(j));
	    }
	}
	
	// calculate the total number of subclasses
	//
	for(int i =0; i < types.size(); i++){
	    if(types.get(i).equals("class"))
		max_subclass++;
	}
	cfgVertexFocus.max_subclass = max_subclass;
	
	// calculate the total number of subparams
	//
	for(int i =0; i < types.size(); i++){
	    if(types.get(i).equals("param"))
		max_subparam++;
	}

	// maximum width of any JTextField or JComboBox
	// will set all to this width once they have been added
	//
	int maxwidth = 0;
	int maxheight = 0;
	
	// run through these and add labels and input fields as appropriate
	//
	for(int i=0; i < labels.size(); i++) {

	    // add a label for all labels except the images
	    //
	    if(types.get(i).equals("image") == false){
		String configLabel = (String)labels.get(i);
		JLabel jlabel = new JLabel((String)labels.get(i));
		if(configLabel.equals("configuration")) {
		    jlabel = new JLabel("");
		}
		jlabel.setForeground(Color.black);
		constrain(config_panel,jlabel, gridbag, 0, i,
			  1, 1, 1, 0, GridBagConstraints.WEST);
		labelReference.add(jlabel);
		jlabel.setFont(newFont);
	    }
	    else {
	
		// keep data alligned so changing values is done easily
		// while holding onto these image files
		//
		enteredData.add("image");
		labelReference.add("image");
		blockType.add("image");
	    }
	    	    
	    // add a drop down list for the enumerated values with first
	    // option from file being initially selected
	    //
	    if(types.get(i).equals("enum")){
		
		// create a drop down list to allow selection from
		//
		JComboBox select = new JComboBox();
		select.setFont(newFont);
		select.setForeground(Color.black);

		// retrieve and add all possible values to this list
		//
		Vector<Object> enum_values = new Vector<Object>();
		
		enum_values.add(values.get(i));

		Vector<String> enum_values_2 = new Vector<String>();

		String enum_n = new String(values.get(i).toString());
	
		enum_values_2 = convertEnums(enum_n);
	
		
		for(int j=0; j < enum_values_2.size(); j++) {
		    
		    select.addItem(enum_values_2.get(j));
		
		}
		
		Vertex selectedVertex = cfgVertexFocus;
		select.setSelectedItem(selectedVertex.values.get(i).toString());	
		enteredData.add(select);


		// add the combo box to the panel
		//
		constrain(config_panel,select, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);

		blockType.add("enum");

	    }
	    
	    // make a check box for a boolean type
	    //
	    else if (types.get(i).equals("boolean")){
		
		// create the check box
		//
		String value = (String)(cfgVertexFocus.values.get(i));
		
		// get the default value for the button
		//
		boolean value2;
		if (value.equals( "true"))
		    value2 = true;
		else
		    value2 = false;
		
		// instantiate and place chack box on config panel
		//
		JCheckBox checkBox = new JCheckBox("", value2);
		constrain(config_panel, checkBox, gridbag, 3, i,
			  1,1,1,0,GridBagConstraints.EAST);
		enteredData.add(checkBox);
		blockType.add("boolean");
	    }
	    
	    // add another pop up frame to set parameters for the class
	    //
	    else if (types.get(i).equals("param")) {

		    String image_name = null;
		    String image_association= null;

		    // tells the program which transform it is looking to match
		    //
		    image_association = (String)values.get(i);

		    // 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(((String)(data.name.get(j))).
			       equals("iconSmall")) {
		
				// sets the image_name to the value 
				// held in small icon
				//
				image_name = (String)data.values.get(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 = GUI_PATH + "/images_small/default.gif";
		    }
		    else {
			image_name = GUI_PATH + "/images_small/default.gif";
		    }

		    image_name = GUI_PATH+"/lib/images/isip_transform_builder/icons/algorithm_00.gif";
		    
		    // create the icons for the config panel
		    //
		    ImageIcon icon = new ImageIcon(image_name);
		    
		    		    
		    // create the button for the config panel
		    //
		    buttonParam = new Vertex("Configure");
		    buttonParam.association = image_association;

		    // 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);
		   
		    // add subparam button to the vector
		    //
		    cfgVertexFocus.subparam.add(buttonParam);
		    
		    enteredData.add(buttonParam);
		    blockType.add("Vertex");
		 
	    }
	    
	    // add another pop up frame to set parameters for the class
	    //
	    else if (types.get(i).equals("class")) {

		Vertex button;
		if(cfgVertexFocus.max_subclass > cfgVertexFocus.subclass.size()) {
		    String image_name = null;
		    String image_association= null;

		    // tells the program which transform it is looking to match
		    //
		    image_association = (String)values.get(i);

		    // 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(((String)(data.name.get(j))).
			       equals("iconSmall")) {
		
				// sets the image_name to the value 
				// held in small icon
				//
				image_name = (String)data.values.get(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 = GUI_PATH + "/images_small/default.gif";
		    }
		    else {
			image_name = GUI_PATH + "/images_small/default.gif";
		    }

		    if(image_association.equals("FourierTransform"))
			image_name = GUI_PATH +"/lib/images/isip_transform_builder/icons/fourier_01.gif";

		    // create the icons for the config panel
		    //
		    ImageIcon icon = new ImageIcon(image_name);
		    
		    // create the button for the config panel
		    //
		    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);
		   
		    // add subclass button to the vector
		    //
		    cfgVertexFocus.subclass.add((Vertex)button);
		    
		    // attach an action listener to the button
		    //
		    button.setActionCommand("class");
		    button.addActionListener(this);
		}
		else {
		    
		    // bring back the saved button if all class button's have 
		    // been previously saved
		    //
		    button = (Vertex)cfgVertexFocus.subclass.get(subclassIndex);
		    if (button.actionAdded == false){
			button.addActionListener(this);
			button.actionAdded = true;
		    }
		    subclassIndex++;
		}
		
		// add the vertex to the button panel
		//
		constrain(config_panel,button, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(button);
		blockType.add("Vertex");
	    }
    
	    // do nothing if the type is image
	    //
	    else if (types.get(i).equals("image")) {
	    }
	    
	    // take care of type text
	    //
	    else if (types.get(i).equals("text")) {
		JTextField textField = 
		    new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		textField.setFont(newFont);
		textField.setForeground(Color.black);
		constrain(config_panel,textField, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(textField);
		blockType.add("text");
	    }

	    // take care of type vector
	    //
	    else if (types.get(i).equals("vector")) {
		JTextField textField = 
		    new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		textField.setFont(newFont);
		textField.setForeground(Color.black);
		constrain(config_panel,textField, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(textField);
		blockType.add("vector");
	    }
	    
	    // creation of input box for unsigned int
	    //
	    else if (types.get(i).equals("unsigned-integer")) {
		JTextField textField = 
		    new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		textField.setFont(newFont);
		textField.setForeground(Color.black);
		constrain(config_panel,textField, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(textField);
		blockType.add("unsigned-integer");
	    }

	    // creation of input box for float
	    //
	    else if (types.get(i).equals("float")) {
		JTextField textField = 
		    new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		textField.setFont(newFont);
		textField.setForeground(Color.black);
		constrain(config_panel,textField, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(textField);
		blockType.add("float");
	    } 

	    // creation of input box for double
	    //
	    else if (types.get(i).equals("double")) {
		JTextField textField = 
		    new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		textField.setFont(newFont);
		textField.setForeground(Color.black);
		constrain(config_panel,textField, gridbag, 3, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(textField);
		blockType.add("double");
	    } 

	    // creation of input box for int
	    //
	     else if (types.get(i).equals("integer")) {
		 JTextField textField = 
		     new JTextField(((String)cfgVertexFocus.values.get(i)), 8);
		 textField.setFont(newFont);
		 textField.setForeground(Color.black);
		 constrain(config_panel,textField, gridbag, 3, i,
			   1, 1, 1, 0, GridBagConstraints.EAST);
		 enteredData.add(textField);
		 blockType.add("integer");
	     } 

	    // !!! unexpected data type
	    //
	    else {
		System.err.println();
		System.err.println("---------------------------------------");
		System.err.println("Error - Unexpected data type in file resource.txt: " + types.get(i));
		System.err.println("---------------------------------------");
		System.exit(0);
	    }

	    // check to see if the width of a JComboBox or JTextField
	    // is wider than maxwidth and if it is, give that value to 
	    // maxwidth
	    //
	    String type = (String)blockType.get(i);
	    if((!type.equals("Vertex") &&
		(!type.equals("image")) &&
		(!type.equals("boolean")))) {
		
		Dimension size = (Dimension)((JComponent)enteredData.
					     get(i)).getPreferredSize();
		int width = (int)size.getWidth();
		int height = (int)size.getHeight();
		if( width > maxwidth) {
		    maxwidth = width;
		    maxheight = height;
		}
	    }
	}
	
	// make all of the JComboBoxes and JTextFields be of equal length
	//
	for(int i = 0; i < blockType.size(); i++) {
	    String type = (String)blockType.get(i);
	    if((!type.equals("Vertex") &&
		(!type.equals("image")) &&
		(!type.equals("boolean")))) {
		Dimension size = new Dimension(maxwidth, maxheight);
		((JComponent)enteredData.get(i)).
		    setPreferredSize(size);
		((JComponent)enteredData.get(i)).
		    setMinimumSize(size);
	    }
	}
    }

    /**
     *  places all the proper input items onto the config panel 
     *  for configuring any transform
     *
     * @param container  panel being added to
     * @param button     what is being added to the panel
     * @param gridbag    gridbag layout for config panel
     * @param gridx      the x grid position of the constraint
     * @param gridy      the y grid position of the constraint
     * @param gridwidth  the number of gridspaces wide to constrain
     * @param gridheight the number of gridspaces tall to constrain
     * @param weightx    the horizontal weighting of the constraint
     * @param weighty    the vertical weighting of the constraint
     * @param anchor     which side of the constraint to anchor to
     */
    public void constrain(JPanel container,Component button, 
			  GridBagLayout gridbag, int gridx,int gridy, 
			  int gridwidth, int gridheight,
			  int weightx, int weighty, int anchor){
	GridBagConstraints c = new GridBagConstraints();
	c.gridx = gridx;
	c.gridy = gridy;
	c.gridwidth = gridwidth;
	c.gridheight = gridheight;
	c.weightx = weightx;
	c.weighty = weighty;
	c.anchor = anchor;
	gridbag.setConstraints(button, c);
	container.add(button);
    }

    /**
     * checks to make sure that all configuration data has been input properly
     * and if it has, make the changes to the referrign vertex 
     * @throws NumberFormatException text is given in where a number is asked
     * @return true if valid, false if an exception or invalid data
     */ 
    public boolean validation() {

	subparamInfo =  new Vector<Object>(5,5);
	
	for(int i=0; i < labelReference.size(); i++) {
	    
	    if(blockType.get(i).equals("Vertex")) {
		break;
	    }
	    
	    if(blockType.get(i).equals("enum")) {
		
		// set the vertex's value to match the newly selected one
		//
		subparamInfo.add(((JComboBox)enteredData.get(i)).
				     getSelectedItem());
	    }
	}

	for(int i=0; i < labelReference.size(); i++) {


	    // code to use if the data is an enumerated type
	    //
	    if(blockType.get(i).equals("enum")) {
		
		// set the vertex's value to match the newly selected one
		//
		cfgVertexFocus.values.set(i,
					  ((JComboBox)enteredData.get(i)).
					  getSelectedItem());
	    }

	    // code to use if the data is a text field
	    //
	    if(blockType.get(i).equals("text")) {
		String text =((JTextField)enteredData.get(i)).getText();
		text = text.trim();
		cfgVertexFocus.values.set(i,text);
	    }

	    // code to use if the data is a vector field
	    //
	    if(blockType.get(i).equals("vector")) {
		String text =((JTextField)enteredData.get(i)).getText();
		text = text.trim();
		cfgVertexFocus.values.set(i,text);
	    }

	    // code to get information from a check box
	    //
	    if(blockType.get(i).equals("boolean")) {
		
		boolean status = ((JCheckBox)enteredData.get(i)).isSelected();
		String value = new String();
		if(status){
		    value = "true";
		}
		else {
		    value = "false";
		}
		cfgVertexFocus.values.set(i,value);
	    }
	    
	    // code to get information from a float variable
	    //
	    if(blockType.get(i).equals("float")) {
		String text = ((JTextField)enteredData.get(i)).getText();
		try {
		    float value = Float.valueOf(text).floatValue();
		    cfgVertexFocus.values.set(i, text);
		    String tmp = ""+cfgVertexFocus.names.get(i);
		    if(tmp.equals("signal_duration") && !cfgVertexFocus.association.equals("AudioFrontEnd")) {
			// ISIP_BUG: the next 3 if condition's causes
			// problems when setting parameters, so removed them
			//
			// if(par.signal_duration < value)
			par.signal_duration = value;
		    }
		    if(tmp.equals("frame_duration") && !cfgVertexFocus.association.equals("AudioFrontEnd")) {
			//if(par.frame_duration < value)
			par.frame_duration = value;
		    }
		    if(tmp.equals("sample_frequency") && !cfgVertexFocus.association.equals("AudioFrontEnd")) {
			//if(par.sample_frequency < value)
			par.sample_frequency = value;
		    }
		}
		catch (java.lang.NumberFormatException event) {
		    JFrame frame = new JFrame("Warning");
		    String warningMessage = new 
			String("The value entered for " + 
			       cfgVertexFocus.names.get(i) + 
			       " is not a floating point number.");
		    JOptionPane.showMessageDialog(frame, warningMessage);
		    return false;
		}
	    }

	    // code to get information from a double variable
	    //
	    if(blockType.get(i).equals("double")) {
		String text = ((JTextField)enteredData.get(i)).getText();
		try {
		    double value = Double.valueOf(text).doubleValue();
		    cfgVertexFocus.values.set(i, text);
		}
		catch (java.lang.NumberFormatException event) {
		    JFrame frame = new JFrame("Warning");
		    String warningMessage = new 
			String("The value entered for " + 
			       cfgVertexFocus.names.get(i) + 
			       " is not a floating point number.");
		    JOptionPane.showMessageDialog(frame, warningMessage);
		    return false;
		}
	    }
	    
	    // code to get information from an unsigned integer variable
	    //
	    if(blockType.get(i).equals("unsigned-integer")) {
		String text = ((JTextField)enteredData.get(i)).getText();
		try {
		    int value = Integer.valueOf(text).intValue();
		    if (value >= 0) {
			cfgVertexFocus.values.set(i, text);
		    } else {
			JFrame frame = new JFrame("Warning"); 
			String warningMessage = new 
			    String("The value entered for " + 
				   cfgVertexFocus.names.get(i) + 
				   " is not an unsigned integer.");
			JOptionPane.showMessageDialog(frame,warningMessage);
			return false;
		    }
		}
		catch (java.lang.NumberFormatException event) {
		    JFrame frame = new JFrame("Warning");
		    String warningMessage = new 
			String("The value entered for " + 
			       cfgVertexFocus.names.get(i) + 
			       " is not an unsigned integer.");
		    JOptionPane.showMessageDialog(frame, warningMessage);
		    return false;
		}
	    }

	    // code to get information from an integer variable
	    //
	    if(blockType.get(i).equals("integer")) {
		String text = ((JTextField)enteredData.get(i)).getText();
		try {
		    int value = Integer.valueOf(text).intValue();
		    cfgVertexFocus.values.set(i, text);
		}
		catch (java.lang.NumberFormatException event) {
		    JFrame frame = new JFrame("Warning");
		    String warningMessage = new 
			String("The value entered for " + 
			       cfgVertexFocus.names.get(i) + 
			       " is not an integer.");
		    JOptionPane.showMessageDialog(frame, warningMessage);
		    return false;
		}
	    }
	}
	return true;
    }

    /**
     * prevents duplicates from being formed when changing the order in 
     * a connector configuration screen
     *
     * @param e  event thrown when one of the combo boxes is changed
     */
    public void itemStateChanged(ItemEvent e) {
	
	// the combo box that caused the event to fire
	//
	JComboBox changedBox = (JComboBox)e.getSource();
	
	// the value that the box was changed to
	//
	int newSetting = changedBox.getSelectedIndex();
	
	// holds the index of the combo box that called this even handler
	//
	int newSettingIndex = -1;
	
	// the value the box was changed from
	//
	int oldSetting = -1;
	
	// the index of the combo box that is set to what the other combo box
	// was changed to
	//
	int oldSettingIndex = -1;

	for(int i=0; i < connBox.size(); i++) {
	    
	    // gets the value of the currently selected combo box
	    //
	    int needToChange = ((JComboBox)connBox.get(i)).getSelectedIndex();
	    
	    // if the new setting is equal to the value that the box is being
	    // changed to, this is either the box that was changed or the one
	    // that needs to be changed 
	    //
	    if (newSetting == needToChange) {
		// gets the value that the combobox was set to before changes
		// were made to it
		//
		int change = ((Integer)connection_order.get(i)).intValue();
		
		// if these are equal, we are dealing with the combo box
		// that was not changed
		//
		if ((newSetting == change) && (newSettingIndex == -1)) {
		    newSettingIndex = i;
		}
		
		// if these are not equal, then this is the one that was 
		// changed
		//
		if ((newSetting != change ) && (oldSettingIndex == -1)) {
		    oldSettingIndex = i;
		    oldSetting = change;
		}
		
		// if we've found both the one that are involved in the change
		// make the changes
		//
		if ((newSettingIndex != -1)&&(oldSettingIndex != -1)) {
		
		    // changes the combo box so that there are no 
		    // duplicate inputs
		    //
		    ((JComboBox)connBox.get(newSettingIndex)).
			setSelectedIndex(oldSetting);
					    
		    // corrects the connection order vector to show the 
		    // new order of the inputs
		    //
		    Integer value = new Integer(oldSetting);
		    connection_order.set(newSettingIndex, value);
		    
		    Integer value2 = new Integer(newSetting);
		    connection_order.set(oldSettingIndex, value2);
		    
		    return;
		}
	    }
	}
    }
    

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

	//System.out.println("ConfigBox " + e.getActionCommand() + 
	//		   " ID: " + e.getID());
	
	if(e.getActionCommand().equals("update")){
	
	    // if the block we've configured is a transform
	    //
	    if(cfgType == 0) {
		
		// validate the inputs and if they are all valid, 
		// dispose of the box
		//		
		if(validation()) {
		    this.dispose();
		    workArea.repaint();
		}
	    }
	    
	    // if the block being congifured is a connector block
	    //
	    else if(cfgType == 1) {
		
		// make a copy of the parent vector for this connector
		//
		Vector<Object> parentCopy = new Vector<Object>(cfgVertexFocus.getParents());
	
		// change all connections as the config box has told
		//
		for(int i=0; i < connBox.size(); i++) {
		    
		    // get the combo box in question
		    //
		    JComboBox focus = (JComboBox)connBox.get(i);
		    int selected_index = focus.getSelectedIndex();

		    // change the connector from the selected source to 
		    // the position it wanted in
		    //
		    cfgVertexFocus.changeConnectors((i + 1),
						    (Vertex)parentCopy.
						    get(selected_index));
		}
		
		// close the window and repaint the workArea
		//
		this.dispose();
		workArea.repaint();
	    }
	}
	
	if(e.getActionCommand().equals("cancel")){
	    
	    // dispose of the changes and revert to the old ways
	    //
	    /*
	    if(class_config_panel != null)
		{
		    if(class_config_panel.isDisplayable())
			{
			}
		    else
			{
			    this.dispose();
			}
		}
	    else {
		this.dispose();
	    }
	    */
	    this.dispose();
	}
	
	if(e.getActionCommand().equals("default")){
	    defaultSettings();
	}
	
	if(e.getActionCommand().equals("revert")){
	    revertSettings();
	}
	
	if(e.getActionCommand().equals("help")){
		
	    // display a help message: "under construction"
	    //
	    JFrame frame = new JFrame("Help");
	    JOptionPane.showMessageDialog(frame, 
					  "The help message is under construction");
	}

	// create config window if dealing with a nested class for config
	//
	if(e.getActionCommand().equals("class")){
	    Vertex temp = (Vertex)e.getSource();
		if(isModal()) {
		    setModal(false);
		    SubConfigBox class_config_panelc = 
			new SubConfigBox(this, data, temp, cfgVertexFocus);
		    class_config_panelc.pack();
		    class_config_panelc.setVisible(true);
		}
	}

	// create config window if dealing with a nested param for config
	//
	if(e.getActionCommand().equals("param")){

	    // if the block we've configured is a subparam
	    //
	    if(validation()) {	

		for (int z = 0; z < subparamInfo.size(); z++) {


		    String fixed_param = new String(subparamInfo.elementAt(z).toString());
		    fixed_param = new String(fixed_param.substring(0));
		
		    subparamInfo.removeElementAt(z);
		    subparamInfo.insertElementAt(fixed_param, z);
		}

		Vertex temp = (Vertex)cfgVertexFocus.subparam.get(cfgVertexFocus.subparam.size()-1);
		if(isModal()) {
		    setModal(false);
		class_config_panel = 
		    new SubConfigBoxParam(this, data, temp, cfgVertexFocus, subparamInfo);


		}		

		if (e.getID() == 1000) {
		     class_config_panel.actionPerformed(new ActionEvent
							(this,
							 1000,
							 "update"));
		     class_config_panel.dispose();
		    
		}
		else {
		
		    class_config_panel.pack();
		    class_config_panel.setVisible(true);
		}
		

	    }
	}
    }

  
    /**
     *  resets all configuartion items to the default values as given in 
     *  the gui configuration file
     */
    public void defaultSettings() {

	if(cfgType == 0) {
	    int subclass_index = 0;
	    
	    // get the name of the class we're working on
	    //
	    String association = cfgVertexFocus.association;

	    // get the beginning and end of my search for default data
	    // 
	    int begin = data.association.indexOf(association);
	    int end = data.association.lastIndexOf(association);
	    
	    // change all values back to the default
	    //
	    for(int i= begin; i <= end; i++) {
		
		// set enum type back to default value
		//
		if(data.type.get(i).equals("enum")) {
		    Vector<Object> enum_values = new Vector<Object>();

		    enum_values.add(data.values.get(i));
		    
		    // actually change the enum to the default setting
		    //
		    JComboBox select = (JComboBox)enteredData.get(i - begin);

		    select.setSelectedItem((String)enum_values.get(0));
		}
		
		// make the check box revert to its previous state
		//
		else if (data.type.get(i).equals("boolean")){
		    
		    // get the value for the check box
		    //
		    String value = (String)(data.values.get(i));
		    
		    boolean value2;
		    if (value.equals("true"))
			value2 = true;
		    else
			value2 = false;
		    
		    // actually make the change to the check box
		    //
		    JCheckBox checkBox = 
			(JCheckBox)enteredData.get(i - begin); 
		    checkBox.setSelected(value2);
		}
		
		// do nothing if the type is image
		//
		else if (data.type.get(i).equals("image")) {
		}
		// do nothing if type is param
		//
		else if (data.type.get(i).equals("param")) {
		    /*
		    Vertex subparam = 
			(Vertex)cfgVertexFocus.subparam.get(subparam_index);
		    
		    // get the name of the class we're working on
		    //
		    String association2 = subparam.association;
		    
		    // get the beginning and end of my search for default data
		    //
		    int begin2 = data.association.indexOf(association2);
		    int end2 = data.association.lastIndexOf(association2);
		    
		    // change all values back to the default
		    //
		    for(int j= begin2; j <= end2; j++) {
			
			// set enum type back to default value
			//
			if(data.type.get(j).equals("enum")) {
			    Vector<Object> enum_values = (Vector<Object>)data.values.get(j);
			    subparam.values.
				set(j - begin2, enum_values.get(0));
			}
			
			// make the check box revert to its default state
			//
			else if (data.type.get(j).equals("boolean")){
			  
			    // get the value for the check box
			    //
			    subparam.values.
				set(j - begin2, data.values.get(j));
			}
			
			// do nothing if the type is image
			//
			else if (data.type.get(j).equals("image")) {
			}
			
			// set all text field back to defaults
			//
			else {
			    subparam.values.
				set(j - begin2, data.values.get(j));
			}
		    }
		    subparam_index++;
		    */
		}

		// do nothing if type is class
		//
		else if (data.type.get(i).equals("class")) {
		    
		    Vertex subclass = 
			(Vertex)cfgVertexFocus.subclass.get(subclass_index);
		    
		    // get the name of the class we're working on
		    //
		    String association2 = subclass.association;
		    
		    // get the beginning and end of my search for default data
		    //
		    int begin2 = data.association.indexOf(association2);
		    int end2 = data.association.lastIndexOf(association2);
		    
		    // change all values back to the default
		    //
		    for(int j= begin2; j <= end2; j++) {
			
			// set enum type back to default value
			//
			if(data.type.get(j).equals("enum")) {
			    Vector<Object> enum_values = new Vector<Object>();
			    enum_values.add(data.values.get(j));
			    subclass.values.
				set(j - begin2, enum_values.get(0));
			}
			
			// make the check box revert to its default state
			//
			else if (data.type.get(j).equals("boolean")){
			  
			    // get the value for the check box
			    //
			    subclass.values.
				set(j - begin2, data.values.get(j));
			}
			
			// do nothing if the type is image
			//
			else if (data.type.get(j).equals("image")) {
			}
			
			// set all text field back to defaults
			//
			else {
			    subclass.values.
				set(j - begin2, data.values.get(j));
			}
		    }
		    subclass_index++;
		    
		}
	    
		// set all text field back to defaults
		//
		else {
		    
		    JTextField text_box
			= (JTextField)enteredData.get(i - begin);
		    text_box.setText((String)data.values.get(i));	
		}
	    }
	}
	else if(cfgType == 1) {
	    for(int i=0; i < connBox.size(); i++) {
		
		// set all the combo boxes to show their original values
		//
		((JComboBox)connBox.get(i)).setSelectedIndex(i);
		
		// reset the connection order vector to the original setting
		//
		Integer value = new Integer(i);
		connection_order.set(i, value);
	    }
	}
    }

    /**
     *  resets all configuartion items to the values that were stored in the 
     *  referring vertex before the configuration began 
     */    
    public void revertSettings() {
	
	// changes all of the settings back to what they were before the 
	// user started changing things
	//
	if(cfgType == 1) {
	    for(int i=0; i < connBox.size(); i++) {
		
		// set all the combo boxes to show their original values
		//
		((JComboBox)connBox.get(i)).setSelectedIndex(i);
		
		// reset the connection order vector to the original setting
		//
		Integer value = new Integer(i);
		connection_order.set(i, value);
	    }
	}
	else if(cfgType == 0) {
	
	    // now run through these and add labels and input 
	    // fields as appropriate
	    //
	    for(int i=0; i < cfgVertexFocus.values.size(); i++) {
		// make the selected option revert to its previous state
		//
		if(cfgVertexFocus.types.get(i).equals("enum")){
		    
		    JComboBox select = (JComboBox)enteredData.get(i);
		    select.setSelectedItem(cfgVertexFocus.values.get(i));
		}
		
		// make the check box revert to its previous state
		//
		else if (cfgVertexFocus.types.get(i).equals("boolean")){
		
		    // get the value for the check box
		    //
		    String value = (String)(cfgVertexFocus.values.get(i));
		    JCheckBox checkBox = (JCheckBox)enteredData.get(i); 

		    boolean value2;
		    if (value.equals("true"))
			value2 = true;
		    else
			value2 = false;
		    checkBox.setSelected(value2);
		}
		
		// do nothing if the type is image
		//
		else if (cfgVertexFocus.types.get(i).equals("image")) {
		}
		
		// do nothing if type is class
		//
		else if (cfgVertexFocus.types.get(i).equals("param")) {
		}	
		
		// do nothing if type is class
		//
		else if (cfgVertexFocus.types.get(i).equals("class")) {
		}
		
		// take care of anything of type text
		//
		else if (cfgVertexFocus.types.get(i).equals("text")) {
		    
		    JTextField text_box = (JTextField)enteredData.get(i);
		    String text = (String)cfgVertexFocus.values.get(i);
		    text_box.setText(text);
		    
		}

		// creation of input box for unsigned int
		//
		else if (cfgVertexFocus.types.get(i).equals("unsigned-integer")) {
		    
		    JTextField text_box = (JTextField)enteredData.get(i);
		    String text = (String)cfgVertexFocus.values.get(i);
		    text_box.setText(text);	    
		}
		
		// creation of input box for float
		//
		else if (cfgVertexFocus.types.get(i).equals("float")) {
		    
		    JTextField text_box = (JTextField)enteredData.get(i);
		    String text = (String)cfgVertexFocus.values.get(i);
		    text_box.setText(text);
		}
		
		// creation of input box for int
		//
		else if (cfgVertexFocus.types.get(i).equals("integer")) {
		    
		    JTextField text_box = (JTextField)enteredData.get(i);
		    String text = (String)cfgVertexFocus.values.get(i);
		    text_box.setText(text);	    
		}
	    }
	} 
    }

    /**
     * Converts a string of enums to a vector of strings
     *
     * @param enum_n all the options in a drop down menu
     * @return a division of enumerations in parameter
     */
    Vector<String> convertEnums(String enum_n) {

	Vector<String> enum_values_temp = new Vector<String>();
	
	String enum_1 = new String();
	String enum_2 = new String();
	String enum_3 = new String();
	String enum_4 = new String();
	
	int which_enum = 1;
	
	for (int j = 0; j < 1000; j++) {
	    
	    Character ch = enum_n.charAt(j);
	    
	    if (ch == ','){
		
		which_enum++;
	    }			
	    else if (ch == '[' || ch == ' ') { }
	    else if (ch == ']') {
		
		j = 1000;
	    }
	    else {

		switch (which_enum) {
		    
		case 1: 
		    
		    if (enum_values_temp.size() == 0) {

			enum_values_temp.addElement(new String(""));
		    }
		    
		    String str = enum_values_temp.elementAt(0);
		    enum_values_temp.removeElementAt(0);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		    
		case 2: 
		    
		    if (enum_values_temp.size() == 1) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(1);
		    enum_values_temp.removeElementAt(1);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 3: 

		    if (enum_values_temp.size() == 2) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(2);
		    enum_values_temp.removeElementAt(2);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 4: 
		    
		    if (enum_values_temp.size() == 3) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(3);
		    enum_values_temp.removeElementAt(3);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 5: 
		    
		    if (enum_values_temp.size() == 4) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(4);
		    enum_values_temp.removeElementAt(4);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 6: 
		    
		    if (enum_values_temp.size() == 5) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(5);
		    enum_values_temp.removeElementAt(5);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 7: 
		    
		    if (enum_values_temp.size() == 6) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(6);
		    enum_values_temp.removeElementAt(6);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 8: 
		    
		    if (enum_values_temp.size() == 7) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(7);
		    enum_values_temp.removeElementAt(7);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 9: 
		    
		    if (enum_values_temp.size() == 8) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(8);
		    enum_values_temp.removeElementAt(8);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 10: 
		    
		    if (enum_values_temp.size() == 9) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(9);
		    enum_values_temp.removeElementAt(9);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 11: 
		    
		    if (enum_values_temp.size() == 10) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(10);
		    enum_values_temp.removeElementAt(10);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 12: 
		    
		    if (enum_values_temp.size() == 11) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(11);
		    enum_values_temp.removeElementAt(11);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 13: 
		    
		    if (enum_values_temp.size() == 12) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(12);
		    enum_values_temp.removeElementAt(12);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		case 14: 
		    
		    if (enum_values_temp.size() == 13) {
			
			enum_values_temp.addElement(new String(""));
		    }
		    
		    str = enum_values_temp.elementAt(13);
		    enum_values_temp.removeElementAt(13);
		    str = new String(str.concat(ch.toString()));
		    enum_values_temp.addElement(str);
		    
		    break;
		    
		}
	    }
	}
	
	return enum_values_temp;

    }

}

//
// end of file























