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

public class ConfigBox extends JDialog implements ActionListener, 
						 ItemListener, Constants {

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

    // flag to let program know to exit the program when the main window's 
    // cancel button has been hit.
    //
    public boolean isRecognizer = false;

    // main menu, i.e. | File | | Help | ...
    //
    MainMenu main_menu = null;

    // 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;    

    // Button to open file selection window
    //
    JButton file_button = null;

    // FileChooser to browse for a file
    //
    JFileChooser file_chooser = null;
    
    //Vector to store information for determing subclass
    //
    Vector subparamInfo =  new Vector(5,5);

    //Vector of labels and data blocks (text fields, selection blocks,
    //check boxes, etc..)
    // *** add get function for enteredData instead of making public?
    //
    public Vector enteredData = null;
    public Vector blockType = null;
  
    // jlabels used to lable each of the items in the config box
    //
    public Vector labels = null;
    public Vector types = null;
    public Vector values = null;

    //*** may be obsolete
    Vector labelReference = null;

    //Vector of subclass vertices
    //
    Vector 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
    // what to replace this with?
    //*** WorkArea workArea = null;
    JPanel panel = null;
    
  

    //*** replace par with mainWnd
    public MainWindow par = null;

    // vectors user in a connector box configuration
    // *** unnecessary?
    Vector connBox = null;
    Vector connLabels = null;
    Vector connection_order = null;

    SubConfigBoxParam class_config_panel = null;

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

    // method: ConfigBox
    //
    // arguments: none
    // returns  : none
    //
    public ConfigBox(MainWindow parent, Data d, Vertex b, JPanel 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;

	// save the parent window
	//
	par = parent;

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


	// 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
	//
	String transform = cfgVertexFocus.association;
	labels = new Vector(5,5);
	types = new Vector(5,5);
	values = new Vector(5,5);

	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));
	    }
	}


	//Create this new panel with gridbag layout
	//
	config_panel =  new JPanel();
	addConfig(); // *** what does this do? 

	// make reference available globally for work area
	// *** this and some of the following code may no longer be necessary
	panel = area;
		
	//Set the sizes of the scroll pane and configuration panel
	//
	int height = (labelReference.size()+5) * 25;
	int 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:");
	
	// 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
    //
    // ---------------------------------------------------

    // method:  addConfig()
    //
    // arguments:  none
    // return: none
    //
    //  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); // *** will rename buildwindow-ish
	}
	
	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 the 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
	    // *** discrepancy between button label and action command? 
	    save_button = new JButton(saveStr);
	    button_panel.add(save_button);
	    save_button.addActionListener(this);
	    save_button.setActionCommand(updateStr);
	    save_button.setFont(newFont);
	
	    // create the cancel button and add to subpanel
	    //
	    cancel_button = new JButton(cancelStr);
	    button_panel.add(cancel_button);
	    cancel_button.addActionListener(this);
	    cancel_button.setActionCommand(cancelStr);
	    cancel_button.setFont(newFont);

	    // create the help button and add to subpanel
	    //
	    help_button = new JButton(helpStr);
	    button_panel.add(help_button);
	    help_button.addActionListener(this);
	    help_button.setActionCommand(helpStr);
	    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
	    //*** discrepancy between button label and action command?
	    save_button = new JButton(saveStr);
	    button_panel.add(save_button);
	    save_button.addActionListener(this);
	    save_button.setActionCommand(updateStr);
	    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()+2,
		  GridBagConstraints.REMAINDER,1,1,1,
		  GridBagConstraints.SOUTH);
	
    }
   
    // method: addTransformConfig
    //
    // arguments:
    //    GridBagLayout gridbag:  gridbag layout for config panel
    //
    // return   : none
    //
    //  places all the proper input items onto the config panel 
    //  for configuring any transform
    //
    public void addTransformConfig(GridBagLayout gridbag)  {
	
	
	
	int subclassIndex = 0;
	int subcparamIndex = 0;
	
	// for use with constraint function. increments after each row is added so that
	// window is filled with components in a top-to-bottom fashion
	//
	int yPosition = 0;

	JLabel jlabel = null;

	
	
	// 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++;
	}

	// addthe main menu
	// define the main menu above
	// 
	main_menu = new MainMenu(par);
	
	// add the components
	//
	// yPosition should increment AFTER the menu is added at the current yPosition
	//
	main_menu.add_components();
        constrain(config_panel, main_menu, gridbag, 0, yPosition++, GridBagConstraints.REMAINDER, 
	  1, 1, 1, GridBagConstraints.NORTH);

	// 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
	    //*** there will be no images. change condition
	    if(types.get(i).equals("image") == false){
		String configLabel = (String)labels.get(i);
		
		jlabel = new JLabel((String)labels.get(i));

		if(configLabel.equals("configuration")) {
		    jlabel = new JLabel("");
		}
		jlabel.setForeground(Color.black);
		constrain(config_panel,jlabel, gridbag, 0, yPosition,
			  1, 1, 1, 0, GridBagConstraints.WEST);
		labelReference.add(jlabel);
		jlabel.setFont(newFont);
	    }
	    else {
		//*** also unnecessary. must understand arrays so that all fluff 
		// like this can be removed
		//
		// 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 FileChooser button. first must create button and add action
	    // command. then add file chooser code in event handling.
	    // *** this will need to be modified so that an edit button
	    // can exist beside the file button on the layout. perhaps make a panel
	    // of two buttons side-by-side
	    // | File | | Edit | <display of selected file name>
	    //
	    if(types.get(i).equals("file")){
		//*** need to create a panel that will hold 4 items:
		// 1. association label
		// 2. file chooser button
		// 3. a text field to display the selected file
		// 4. a configure button which will open an edit window for the file
		// this panel should have a border to distinguish it from other items

      		// create the button
		//
		file_button = new JButton("Select File");
		file_button.addActionListener(this);
		file_button.setActionCommand("file");
		file_button.setFont(newFont);
		
		
       		// add the button to the window
		//
		constrain(config_panel, file_button, gridbag, 3,
			  yPosition++,1, 1, 1, 0, GridBagConstraints.EAST);

		//***
		//constrain(config_panel,jlabel, gridbag, 0, yPosition,
		//  1, 1, 1, 0, GridBagConstraints.WEST);
	
		
		// register the button
		//
		enteredData.add(file_button);
		blockType.add("file");

	    }

	    // add a drop down list for the enumerated values with first
	    // option from file being initially selected
	    //
	    else 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 enum_values = (Vector)values.get(i);
		for(int j=0; j < enum_values.size(); j++) {
		    select.addItem(enum_values.get(j));
		}
		
		// add the combo box to the panel
		//
		constrain(config_panel,select, gridbag, 3, yPosition++,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(select);
		blockType.add("enum");
		//		Vertex selectedVertex = cfgVertexFocus;
		select.setSelectedItem(values.get(i));
	    }
	    
	    // make a check box for a boolean type
	    //
	    else if (types.get(i).equals("boolean")){
		
		// create the check box
		//
		String value = (String)(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, yPosition++,
			  1,1,1,0,GridBagConstraints.EAST);
		enteredData.add(checkBox);
		blockType.add("boolean");
	    }
	    
	    // add another pop up frame to set parameters for the class
	    // *** use this for the configure button for the file type parameters
	    //
	    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
		    // *** this is just the association, has nothing to do with "image"
		    image_association = (String)values.get(i);

		    // scans through the association until it 
		    // finds the smallIcon key
		    // *** necessary?
		    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 labels2 = new Vector(5,5);
		    Vector types2 = new Vector(5,5);
		    Vector values2 = new Vector(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
	    // *** useful for "edit" button that will go with FileChoosers. instead of
	    // adding a window with a button that opens a transform config window, skip
	    // the intermediate window and open the new config window.
	    //
	    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
		    // *** necessary?
		    //
		    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.
		    // *** review this. will it break the code to remove it?
		    //
		    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 labels2 = new Vector(5,5);
		    Vector types2 = new Vector(5,5);
		    Vector values2 = new Vector(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(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, yPosition++,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		enteredData.add(button);
		blockType.add("Vertex");
	    }
    
	    // do nothing if the type is image
	    // *** remove
	    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, yPosition++,
			  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, yPosition++,
			  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, yPosition++,
			  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, yPosition++,
			  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, yPosition++,
			  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)values.get(i)), 8);
		 TextField.setFont(newFont);
		 TextField.setForeground(Color.black);
		 constrain(config_panel,TextField, gridbag, 3, yPosition++,
			   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);
	    }
	}
    }

    // method: constrain
    //
    // arguments:
    //    JPanel container      :  panel being added to
    //    Component button      :  what is being added to the panel
    //    GridBagLayout gridbag :  gridbag layout for config panel
    //    int gridx             :  the x grid position of the constraint
    //    int gridy             :  the y grid position of the constraint
    //    int gridwidth         :  the number of gridspaces wide to constrain
    //    int gridheight        :  the number of gridspaces tall to constrain
    //    int weightx           :  the horizontal weighting of the constraint
    //    int weighty           :  the vertical weighting of the constraint
    //    int anchor            :  which side of the constraint to anchor to
    //
    // return  :  none
    //
    //  places all the proper input items onto the config panel 
    //  for configuring any transform
    // 
    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);
    }

    // method: validation
    // *** not verified
    // arguments:  none
    //
    // return:  boolean 
    //
    // checks to make sure that all configuration data has been input properly
    // and if it has, make the changes to the referrign vertex 
    // 
    public boolean validation() {
	/*
	subparamInfo =  new Vector(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((String)((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,
			(String)((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")) {
			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;
    }

    // method: itemStateChanged
    //*** necessary?
    // arguments:  
    //     ItemEvent e:  event thrown when one of the combo boxes is changed
    //
    // return:  boolean 
    //
    // prevents duplicates from being formed when changing the order in 
    // a connector configuration screen
    // 
    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;
		}
	    }
	}
    }
    
    // method: actionPerformed
    //
    // arguments:
    //    ActionEvent e: event that was fired
    //
    // return   : none
    //
    // listens for actions taking place on the components
    //
    public void actionPerformed(ActionEvent e) {
	
	if(e.getActionCommand().equals("update")){
	
	    // if the block we've configured is a transform
	    // *** condition unnecessary
	    if(cfgType == 0) {
		
		// validate the inputs and if they are all valid, 
		// dispose of the box
		//		
		if(validation()) {
		    this.dispose();
		    panel.repaint();
		}
	    }
	}
	
	if(e.getActionCommand().equals("file")){
	    
	    String cwd = System.getProperty("user.dir");
	    file_chooser = new JFileChooser(cwd);
	    
	    // set the font and button text for the load chooser
	    //
	    file_chooser.setFont(newFont);
	    String loadApprove = new String("Load");//*** the point of this line is?
	    file_chooser.setApproveButtonText(loadApprove);
	    
	    // display the file chooser object
	    // "this" is the parent window
	    //
	    int returnVal = file_chooser.showOpenDialog(this);
	    
	    //*** need to correct "approve option" check below.
	    // place this code within the if.
	    //
	    ((JButton)e.getSource()).setText(file_chooser.getSelectedFile().toString());
	    ((JButton)e.getSource()).repaint();
	    ((JButton)e.getSource()).setVisible(true);
	    
	    // check to see if a file was selected by the user
	    //
	    if (returnVal == JFileChooser.APPROVE_OPTION) {
		
		// retrieve the selected file
		//
		par.paramFile = file_chooser.getSelectedFile();
		
		// read the parameters to file
		//
		par.read();
	    } 
	}
	if(e.getActionCommand().equals("cancel")){
	    this.dispose();

	    // if it is the main window that has been cancelled, exit.
	    // *** put an "are you sure?" window here
	    //
	    if(isRecognizer) System.exit(0);
	}
	
	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()) {	
		Vertex temp = (Vertex)cfgVertexFocus.subparam.get(cfgVertexFocus.subparam.size()-1);
		if(isModal()) {
		    setModal(false);
		class_config_panel = 
		    new SubConfigBoxParam(this, data, temp, cfgVertexFocus, subparamInfo);
		}		
		class_config_panel.pack();
		class_config_panel.setVisible(true);
	    }
	}
    }

    // method: defaultSettings
    // *** not verified. Likely doesn't work. 
    // arguments:  none
    //
    // return:  none
    //
    //  resets all configuartion items to the default values as given in 
    //  the gui configuration file
    //
    public void defaultSettings() {
	
	
	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 enum_values = (Vector)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
	    // *** should this reset subwindows to default also?
	    //
	    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 enum_values = (Vector)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 enum_values = (Vector)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));	
	    }
	}
    }

    // method: revertSettings
    // *** not verified
    // arguments:  none
    //
    // return:  none
    //
    //  resets all configuartion items to the values that were stored in the 
    //  referring vertex before the configuration began 
    //    
    public void revertSettings() {
	
	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);	    
		}
	    }
	} 
    }
}

//
// end of file























