// file: $ISIP_IFC/util/demo/isip_comm_client_dilaog_navigation/DialogNavigationUIFrame.java
// version: $Id: DialogNavigationUIFrame.java 10572 2006-06-26 21:54:34Z rei5 $ 
//

// import necessary java libraries
//
import java.net.*;
import java.io.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.border.*;

// import galaxy libraries
//
import galaxy.lang.*;
import galaxy.server.*;
import galaxy.server.ui.ServerUI;

/**
 * This class is used as the user interface for an <code>
 * DialogNavigationServer </code> object.
 */
public class DialogNavigationUIFrame extends JFrame implements
							ComponentListener,
							ActionListener,
							MenuListener {
   
    //-------------------------------------------------------------------------
    //
    // public constants
    //
    //-------------------------------------------------------------------------
    
    /**
     * Default UI height.
     */
    public static final int MAX_UI_HEIGHT = 700;
    
    /**
     * Default UI width.
     */
    public static final int MAX_UI_WIDTH = 1000;

    /**
     * Append the text.
     */
    public static final int APPEND = 0;
    
    /**
     * Clear the document.
     */
    public static final int CLEAR = 1;

    /**
     * Append a new line ("\n") at the end of file.
     */
    public static final int APPEND_NEWLINE = -1;
      
    /**
     * Default UI height.
     */
    public static final int DEFAULT_UI_HEIGHT = 700;

    /**
     * a boolean value
     */
    public static boolean debug = true;
    
    /**
     * Default UI width.
     */
    public static final int DEFAULT_UI_WIDTH = 1000;
    
    /**
     * Speech display plot.
     */
    public SpeechDisplay speech_plot_d;
    
    /**
     * Text field.
     */
    public JTextField input_field_d;
    
    /**
     * Buttons.
     */
    public JButton record_button_d;
    
    /**
     * Buttons.
     */
    public JButton playback_button_d;
    
     /**
     * Buttons.
     */
    public JButton stop_button_d;
    
     /**
     * Buttons.
     */
    public JButton clear_button_d;
    
     /**
     * Buttons.
     */
    public JButton quit_button_d;

    /**
     * TextArea for message window
     */
    public JTextArea message_window_textarea_d;
    
    /**
     * TextArea for message window
     */
    public JTextArea dialog_info_textarea_d;

    //------------------------------------------------------------------------
    //
    // protected data
    //
    //-----------------------------------------------------------------------
    
    /**
     * The port number of the dialog_navigation. 
     */
    protected int dialog_navigation_port_d;
    
    /**
     *  The port number of the process manager. 
     */
    protected int process_manager_port_d;
    
    /**
     *  The ip address of the process manager. 
     */    
    protected String process_manager_ip_d;
  
    /**
     * client object to take care connection with control server.
     */
    protected ConnectionManager conn_d;

    /**
     * Test if this client is get connected with control server
     */
    protected boolean connected_d = true;

    /**
     * Indicate if the recording is progrss or not.
     */
    protected static boolean recording_d = false;  

    /**
     * The Configuration pop up window.
     */    
    protected Configuration dialog = null;

    /**
     * Configuration data for audio parameters.
     */
    protected ConfigData cfg_audio_d;

    /**
     * Configuration data for energy parameters.
     */
    protected ConfigData cfg_energy_d;

    /**
     * Configuration data for spectrogram parameters.
     */
    protected ConfigData cfg_spectrogram_d;

    /**
     * Configuration data for  waveform parameters.
     */
    protected ConfigData cfg_waveform_d;

    /**
     * Configuration data for display parameters.
     */
    protected ConfigData cfg_display_d;
    
    /**
     * Configuration data for detector parameters.
     */
    protected ConfigData cfg_detector_d;

    /**
     * Menu items.
     */
    protected JMenuItem ConfigAudio;

    /**
     * Menu items.
     */
    protected JMenuItem ConfigEnergy;
    
    /**
     * Menu items.
     */
    protected JMenuItem ConfigWaveform;
    
    /**
     * Menu items.
     */
    protected JMenuItem ConfigSpectrogram;
    
    /**
     * Menu items.
     */
    protected JMenuItem ConfigDisplay;
    
    /**
     * Menu items.
     */
    protected JMenuItem ConfigDetector;

    /**
     * Panel items.
     */
    protected JPanel text_input;
    
    /**
     * Panel items.
     */
    protected JPanel left_buttons;
    
    /**
     * Panel items.
     */
    protected JPanel right_buttons;
    
    /**
     * Panel items.
     */
    protected JPanel bottom_left_window_d;
    
    /**
     * Panel items.
     */
    protected JPanel bottom_right_window_d;
    
    /**
     * Panel items.
     */
    protected JPanel main_bottom_window_d;
    
    /**
     * The pane that contains both buttons and text input as cards
     */
    protected JPanel buttons_or_input_pane_d;
    
    /**
     * The names of the panels the above panel contains
     */
    protected String[] card_panes_names_d = new String[] {
	"button_card_pane",
	"text_input_card_pane"
    };
    
    /**
     * Current number of pane that the card pane is on
     */
    protected int current_card_pane_d = 0;
	
    /**
     * a debug window object
     */
    protected DebugWindow debug_window = new DebugWindow(this);
    
    /**
     * Method required by MenuListener, but do not use in this class
     */  
    public void menuSelected(MenuEvent evt) {
	// empty
    }
   
    /**
     * Method required by MenuListener, but do not use in this class
     */  
    public void menuDeselected(MenuEvent evt) {
	// empty
    }
   
    /**
     * Method required by MenuListener, but do not use in this class
     */  
    public void menuCanceled(MenuEvent evt) {
	// empty
    }

    /**
     * the constructor of the class. 
     */
    public DialogNavigationUIFrame() {
	
	final DialogNavigationUIFrame thisAR = this;
	
	//make GUI
	//
	makeGUI();
	
	// add component listener
	// 
        addComponentListener(this);
	addWindowListener(new WindowAdapter() {
		
		public void windowActivated(WindowEvent e) {
		    speech_plot_d.repaint();
		}
		public void windowDeactivated(WindowEvent e) {
		    speech_plot_d.repaint();
		}
	    });
	addComponentListener(new ComponentListener() {
		public void componentResized(ComponentEvent e) {
		    System.out.println("Resized!");
		    speech_plot_d.run();
		}
		public void componentMoved(ComponentEvent e) {
		    System.out.println("Moved!");
		}
		public void componentShown(ComponentEvent e) {
		    System.out.println("Shown!");
		    speech_plot_d.run();
		}
		public void componentHidden(ComponentEvent e) {
		    
		}
	    });
	
	setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
	
    }
    
    
    /**
     * the constructor of the class. 
     */
    public DialogNavigationUIFrame(int dialog_navigation_port_a, 
				   int process_port_a, 
				   String process_ip_a,
				   boolean server_mode_a) {
	
	dialog_navigation_port_d = dialog_navigation_port_a;
	process_manager_port_d = process_port_a;
	process_manager_ip_d = process_ip_a;
	
	final DialogNavigationUIFrame thisAR = this;
	
	//make GUI right here
	//
	makeGUI();
	
	conn_d = new ConnectionManager(dialog_navigation_port_d, 
				       process_manager_port_d, 
				       process_manager_ip_d,
				       server_mode_a,
				       (String)"DIALOG_NAVIGATION");
	
	conn_d.addWindowListener(new WindowAdapter() {
		
		public void windowClosed(WindowEvent e) {
		    if (connected_d) {
			connected_d = false;
			
			// Get the error message from the connection manager
			// and display and exit
			//
			JOptionPane.showMessageDialog
			    (thisAR, conn_d
			     .getDisconnectErrorMessage());

			thisAR.actionPerformed(new
					       ActionEvent(this, 0, "Quit"));
		    }// end if connected_d
		}
	    });
	
	conn_d.setThread(new Thread(conn_d));
	conn_d.getThread().start();
    }
    
    /** 
     * This method is used to either add items to an existing
     * <code>JMenu</code> or to create a new <code>JMenu</code>
     * using the supplied <code>String</code> and then add the items.
     *
     * @param parent Existing <code>JMenu</code> to add items to or
     *               <code>String</code> that contains the text for a
     *               new <code>JMenu</code>.
     * @param items Array of <code>String</code>s and/or
     *              <code>JMenuItem</code>s to be added to the menu.
     * @param target Action listener to use for the added menu items.
     *
     * @return JMenu item.
     */
    public static JMenu makeMenu(Object parent,
				 Object[] items, Object target) {
	JMenu m = null;
	if (parent instanceof JMenu)
	    m = (JMenu)parent;
	else if (parent instanceof String)
	    m = new JMenu((String)parent);
	else
	    return null;
	
	for (int i = 0; i < items.length; i++) {
	    if (items[i] == null)
		m.addSeparator();
	    else
		m.add(makeMenuItem(items[i], target));
	}
	
	return m;
    }
    
    /** 
     * This method is used by the <code> makeMenu() </code> method to
     * create <code> JMenuItem </code>s with a specified <code>
     * ActionListener </code>.
     * 
     * @param item
     * @param target
     */
    public static JMenuItem makeMenuItem(Object item,
					 Object target) {
	JMenuItem r = null;
	if (item instanceof String)
	    r = new JMenuItem((String)item);
	else if (item instanceof JMenuItem)
	    r = (JMenuItem)item;
	else return null;
	
	if (target instanceof ActionListener)
	    r.addActionListener((ActionListener)target);
	return r;
    }


    // these methods are needed if the class implements an component
    // listener. These methods need to be overrided by the UIFrame
    // class eventhough we dont use it.
    //
    public void componentHidden(ComponentEvent e) {
	
    }
    
    public void componentMoved(ComponentEvent e) {
        
    }
    
    public void componentShown(ComponentEvent e) {
 
    }
       
    /**
     * This method detects resizing of the UIFrame and recalcultes the
     * energy and waveform display and repaints the display.
     * 
     * @param e The event which is generated when the
     * component is resized
     *
     */
    public void componentResized(ComponentEvent e) {
	    
	// if the window is resized, the speech display is 
	// replotted
	//
	if(!speech_plot_d.realtime_d) {
	    speech_plot_d.redrawOverallPlot();
	speech_plot_d.repaint();
	System.out.println("Component resized");
	}
    }
	
    /**
     * This method detects a new user request, clears the current
     * display history, and displays the current request.
     *
     * @param request_a The request to add to the display.
     * @param mode_a The mode in which to add the request.
     *
     * @return a boolean value indicating status.
     */
    public boolean setText(String request_a, int mode_a) {

	/*SwingUtilities.invokeLater(new RunnableJTextPane(textData_d,
							 textBuffer_d,
							 doc_d,
							 rows_d,
							 request_a,
							 mode_a));
	*/
	if (message_window_textarea_d == null || request_a == null)
	    return false;

	if (mode_a == APPEND)
	    message_window_textarea_d.append(request_a);
	else if (mode_a == CLEAR)
	    message_window_textarea_d.setText(request_a);
	else if (mode_a == APPEND_NEWLINE)
	    message_window_textarea_d.append(request_a + "\n");
	
	// exit gracefully
	//
	return true;
    }

    /**
     * This method detects a new user request, clears the current
     * display history, and displays the current request.
     *
     * @param request_a The request to add to the display.
     * @param mode_a The mode in which to add the request.
     *
     * @return a boolean value indicating status.
     */
    public boolean setTextDialog(String request_a, int mode_a) {

	if (dialog_info_textarea_d == null || request_a == null)
	    return false;

	// layout changes: If begins with PARSE_ then need to make it pretty
	//
	if (request_a.startsWith("PARSE_")) {
	    System.out.println("ENTERED changeParseText with [" + request_a +
			       "]");
	    request_a = changeParseText(request_a);
	    System.out.println("EXITED changeParseText with [" + request_a +
			       "]");
	}
	
	if (mode_a == APPEND)
	    dialog_info_textarea_d.append(request_a);
	else if (mode_a == CLEAR)
	    dialog_info_textarea_d.setText(request_a);
	else if (mode_a == APPEND_NEWLINE)
	    dialog_info_textarea_d.append(request_a + "\n");

	// exit gracefully
	//
	return true;
    }
    
    public String changeParseText(String in_a) {
	String ret_str = "";
	
	// Change the "3" here to change the number of spaces per indent
	//
	String spaces_str = make_duplicate_string(" ", 3);
	int level_in = 1;
	
	//example: 
	/*
	  PARSE_0:
	  Query_Address:[Query_Address].query_where [Arrive_Loc].[Place_Name].[Supermarket_Name].WALMART 
	  END_PARSE
	  
	  to
	  PARSE_0:
	  Query_Address:
	  [Query_Address].
	  query_where
	  
	  [Arrive_Loc].
	  [Place_Name].
	  [Supermarket_Name].
	  WALMART 
	  END_PARSE
	*/
	
	// find begin of PARSE_
	//
	int parse_begin = in_a.indexOf("PARSE_", 0);
	if (parse_begin == -1)
	    return in_a;

	// find first ':' past the "PARSE_0:"
	//
	int parse_colon = in_a.indexOf(':', parse_begin);
	if (parse_colon == -1)
	    return in_a;

	// found the parse colon so now find the frame name colon
	//
	int frame_name_colon = in_a.indexOf(':', parse_colon+1);
	if (frame_name_colon == -1)
	    return in_a;

	// put from PARSE_X to the colon into the return string
	//
	ret_str = in_a.substring(parse_begin, frame_name_colon + 1);

	// add a new line
	//
	ret_str += "\n";

	// mark begin of the [name] at the [
	//
	int begin = frame_name_colon+1;
	
	// bool is set to true when it is the leaf parse
	//
	boolean leaf_parse_value = false;
	int end = 0;
	
	for (;;) {
	    if (leaf_parse_value) {
		leaf_parse_value = false;
		
		// find either next "[" or "END_PARSE"
		//
		int end_brace = in_a.indexOf('[', begin);
		int end_parse = in_a.indexOf("END_PARSE", begin);
		
		// if neither are found that's a major problem, so just pass
		// back what was passed in
		//
		if (end_brace == -1 && end_parse == -1) {
		    return in_a;
		}
		
		// found the end of this [name].thing (found "thing")
		// ex. [Store].WALMART [Place] -- Found beginning of [Place]
		//
		if (end_brace != -1 && end_brace < end_parse) {
		    // put the required number of spaces
		    //
		    ret_str += make_duplicate_string(spaces_str, level_in);
		    // put in the "thing"
		    // end-1 is used because end points to the [ which is 2
		    // past the end of string.
		    //
		    ret_str += in_a.substring(begin, end_brace - 1);
		    ret_str += "\n\n";
		    
		    // reset the level
		    //
		    level_in = 1;
		    // go back to loop
		    //
		    begin = end_brace;
		    continue;
		}
		
		// if get here end_brace == -1 so last word in a parse
		// put in the "thing"					
		//
		ret_str += make_duplicate_string(spaces_str, level_in);
		ret_str += in_a.substring(begin, end_parse - 1);
		// now put a single "\n"
		//
		ret_str += "\n";
		
		// need to determine if another PARSE is after this
		//
		int next_parse = in_a.indexOf("PARSE_", end_parse);
		if (next_parse == -1) {
		    // no more parses so just put END_PARSE and exit
		    // this line includes the final --------------
		    //
		    ret_str += in_a.substring(end_parse);
		    return ret_str;
		}
		// if there are more, then we need to call this function
		// recursively with the string starting from here
		//
		ret_str += "END_PARSE\n";//in_a.substring(end_parse);
		ret_str += changeParseText(in_a.substring(next_parse));
		return ret_str;
	    }
	    
	    end = in_a.indexOf(']', begin);
	    if (end == -1) {
		// if not another [ then break out
		//
		break;
	    }
	    
	    // move +=2 to that we get the ']' and the '.'
	    //
	    end += 1;
	    
	    // and the the required number of spaces
	    //
	    ret_str += make_duplicate_string(spaces_str, level_in);
	    
	    // then put in the "[text]." and the new line
	    //
	    ret_str += in_a.substring(begin, end+1);
	    ret_str += "\n";
	    
	    // increase level
	    //
	    level_in++;
	    
	    // find out if the thing after the period is another [
	    //
	    if (in_a.charAt(end+1) != '[') {
		// this means we dont have another detail and is the leaf
		//
		leaf_parse_value = true;
	    }
	    // move begin to one past the .
	    //
	    begin = end + 1;
	}
	System.out.println("Exiting changeParseText() through the bottom" +
			   "using text [" + in_a + "]. Check it out.\n");
	return ret_str;
    }
     
    /**
     * This method detects a new user request, clears the current
     * display history, and displays the current request.
     *
     * @param request_a The request to add to the display.
     * @param mode_a The mode in which to add the request.
     *
     * @return a boolean value indicating status.
     */
    public boolean setTextDebug(String request_a, int mode_a) {

	if (debug_window == null || request_a == null)
	    return false;

	if (mode_a == APPEND)
	    debug_window.addLogEntry(request_a, true);
	else if (mode_a == CLEAR) {
	    debug_window.clearLog();
	    debug_window.addLogEntry(request_a);
	}
	else if (mode_a == APPEND_NEWLINE)
	    debug_window.addLogEntry(request_a, true);

	// exit gracefully
	//
	return true;
    }

    /**
     * This performs the respective actions whenever a menu item
     * or button is pressed.
     *
     * @param evt event the represents the chosen button or menu item.
     *
     */
    public void actionPerformed(ActionEvent evt) {
	String arg = evt.getActionCommand();
	System.out.println("ActionPeformed UIFrame - " + arg);
	
	//int height = DEFAULT_UI_HEIGHT;
	//int width = DEFAULT_UI_WIDTH;
	boolean redraw = false;
	
	// if the button pressed was exit then exit the window
	//
	// if the button pressed was exit then exit the window
	//
	if (arg.equals("Exit")) {
	    if (!recording_d) {
		setVisible(false);
		dispose();
	    }
	}
	
	// if quit button was pressed then dispose the window
	//
	if (arg.equals("Quit")) {
	    if (!recording_d) {
		setVisible(false);
		dispose();
	    }
	}

	if (arg.equals("Show Debug Window")) {
	    debug_window.showDialog();
	}

	if (arg.equals("Insert Random Text")) {
	    debug_window.addLogEntry( new Random().nextInt() + "", true);
	}
	
	if (arg.equals("Toggle")) {
	    // This code switches between the cards for
	    // the 'record\etc' buttons and the input text area
	    //
	    current_card_pane_d = (current_card_pane_d+1) % 
		card_panes_names_d.length;
	    CardLayout card_layout = (CardLayout)
		(buttons_or_input_pane_d.getLayout());
	    card_layout.show(buttons_or_input_pane_d, 
			     card_panes_names_d[current_card_pane_d]);
  	    
	}	

	if (arg.equals("Show Text Input")) {
	
	    // This code switches between the cards for
	    // the 'record\etc' buttons and the input text area
	    //
	    current_card_pane_d = 1;
	    CardLayout card_layout = (CardLayout)
		(buttons_or_input_pane_d.getLayout());
	    card_layout.show(buttons_or_input_pane_d, 
			     card_panes_names_d[current_card_pane_d]);
  	    
	}	

	if (arg.equals("Hide Text Input")) {
	   
	    // This code switches between the cards for
	    // the 'record\etc' buttons and the input text area
	    //
	    current_card_pane_d = 0;
	    CardLayout card_layout = (CardLayout)
		(buttons_or_input_pane_d.getLayout());
	    card_layout.show(buttons_or_input_pane_d, 
			     card_panes_names_d[current_card_pane_d]);
  	    
	}	

	if (arg.equals("Stop")) {
	    if (debug) {
		right_buttons.setVisible(false);
	    }
	    else {
		right_buttons.setVisible(true);		
	    }
	    debug = !debug;
	}
	if (arg.equals("Record")) {
	    if (debug) {
		bottom_right_window_d.setVisible(false);
	    }
	    else {
		bottom_right_window_d.setVisible(true);		
	    }
	    debug = !debug;
	}

    }
    
    //-------------------------------------------------------------------------
    //
    // class-specific public methods:
    //  set methods
    //
    //-------------------------------------------------------------------------

    /**
     * Set the recording to specified value.
     *
     * @param recording_a boolean value for recording flag.
     *
     * @return a boolean value indicating status.
     */
    public static boolean setRecording(boolean recording_a) {

	recording_d = recording_a;

	// exit gracefully
	//
	return true;
    }

    /**
     * Set the connection flag with process manager.
     *
     * @param connected_a boolean value for connection flag.
     *
     * @return a boolean value indicating status.
     */
    public boolean setConnection(boolean connected_a) {

	connected_d = connected_a;

	// exit gracefully
	//
	return true;
    }


    //-------------------------------------------------------------------------
    //
    // class-specific public methods:
    //  get methods
    //
    //-------------------------------------------------------------------------
 
    /**
     * Get the audio data after the user sets the configuration.
     *
     * @return a ConfigData object 
     */
    public ConfigData getAudioData() {
	
	return cfg_audio_d;
    }
    
    /**
     * Get the signal detector after the user sets the configuration.
     *
     * @return a ConfigData object 
     */
    public ConfigData getDetectorData() {
	
	return cfg_detector_d;
    }

   /**
    * Get the recording flag.
    *
     * @return a boolean value indicating to recording flag.
     */
    public static boolean getRecording() {
	return recording_d;
    }

    /**
     * Get the connection flag.
     *
     * @return a boolean value indicating to connection flag.
     */
    public boolean getConnection() {
	return connected_d;
    }

    /**
     * Get the connection manager object.
     *
     * @return a ConnectionManager object.
     */
    public ConnectionManager getConnectionManager() {
	return conn_d;
    }

    /**
     *  The Connect action pops up the configuration dialog.
     */    
    protected class ConnectAction implements ActionListener {
	
	public int mode = 0;
	
	public ConnectAction(int mode_a) {
	    mode = mode_a;
	}
	
	public void actionPerformed(ActionEvent event) {
	    
	    //define config tab object
	    //
	    ConfigTabPanel cfg_tab_d;
	    
	    // if first time, construct dialog
	    //
	    if (dialog == null) 
		dialog = new  Configuration();
	    else {
		cfg_tab_d = dialog.getPanel();
		cfg_tab_d.setSelectedIndex(mode);
	    }
	    
	    // set the name of the demo to the audio panel object
	    //
	    dialog.setDemoName((String)"DialogNavigation");
	    
	    // pop up dialog
	    //
	    if (dialog.showDialog(DialogNavigationUIFrame.this, 
				  "Configuration")) {
		
		cfg_tab_d = dialog.getPanel();
		cfg_audio_d = cfg_tab_d.getAudioData();
		cfg_energy_d = cfg_tab_d.getEnergyData();
		cfg_spectrogram_d = cfg_tab_d.getSpectrogramData();
		cfg_waveform_d = cfg_tab_d.getWaveformData();
		cfg_display_d = cfg_tab_d.getDisplayData();
		cfg_detector_d = cfg_tab_d.getDetectorData();
		
		speech_plot_d.setConfigData(cfg_display_d);
		speech_plot_d.setConfigData(cfg_energy_d);
		speech_plot_d.setConfigData(cfg_waveform_d);
		
		// if the configuration is changed replot the display
		// and repaint it.
		// 
		if(!speech_plot_d.realtime_d) {
		    speech_plot_d.redrawOverallPlot();
		    speech_plot_d.repaint();
		}
		else {
		    speech_plot_d.setData(null);
		    speech_plot_d.run();
		    speech_plot_d.repaint();
		}		
		
		printData(cfg_audio_d);
		printData(cfg_detector_d);
		printData(cfg_energy_d);
		printData(cfg_spectrogram_d);
		printData(cfg_waveform_d);
		printData(cfg_display_d);
		
		cfg_tab_d.setSelectedIndex(mode);
	    }
	}
	
	/**
	 * Print data inside this config data
	 *
	 * @param cfg_data_a a ConfigData object.
	 *
	 * @return a boolean value indicating status.
	 */
	public boolean printData(ConfigData cfg_data_a) {
	    
	    for (int i = 0; i < cfg_data_a.getAssociation().size(); i++) {
		
		System.out.println("ith item=" + i);
		System.out.println(cfg_data_a.getAssociation().get(i));
		System.out.println(cfg_data_a.getName().get(i));
		System.out.println(cfg_data_a.getType().get(i));
		System.out.println(cfg_data_a.getValue().get(i));
	    }
	    
	    return true;
	}
    }  
    
    /**
     * Print data inside this config data
     *
     * @param args a string argument.
     */
    public static void main(String[] args) {
	new DialogNavigationUIFrame().setVisible(true);
    }
    
//-------------------------------------------------------------------------
//
// class-specific protected methods:
//
//-------------------------------------------------------------------------


/**
 * Gui related method.
 */
protected void makeGUI() {
    
    // main panel properties
    //
    setTitle("Dialog Navigation System");
    
    // set the size for this frame
    //
    setSize(DEFAULT_UI_WIDTH, DEFAULT_UI_HEIGHT);
    
    // main panel menu
    //
    JMenuBar mbar = new JMenuBar();
    setJMenuBar(mbar);
    
    // file menu with "exit" in it
    //
    JMenu fileMenu = new JMenu("File");
    fileMenu.addMenuListener(this);
    
    // add the exit option
    //
    mbar.add(makeMenu(fileMenu,
		      new Object[] {
			  "Exit"
		      },
		      this));
    
    
    // create the configuration menu
    //
    JMenu monitor_menu = new JMenu("Monitor");
    mbar.add(makeMenu(monitor_menu,
		      new Object[] {
			  "Show Debug Window",
			  "Insert Random Text",
			  null,
			  "Show Text Input",
			  "Hide Text Input"
		      },
		      this));			      
    
    // create the configuration menu
    //
    JMenu fileMenu3 = new JMenu("Configuration");
    
    // make the speech_plot
    //
    speech_plot_d = new SpeechDisplay();
    
    // set the menu item to "configuration"
    //
    JMenuItem ConfigAudio = new JMenuItem("Audio");
    JMenuItem ConfigEnergy = new JMenuItem("Energy");
    JMenuItem ConfigWaveform = new JMenuItem("Waveform");
    JMenuItem ConfigSpectrogram = new JMenuItem("Spectrogram");
    JMenuItem ConfigDisplay = new JMenuItem("Display");
    JMenuItem ConfigDetector = new JMenuItem("Detector");
    
    ConfigAudio.addActionListener(new ConnectAction(ConfigTabPanel.AUDIO));
    ConfigEnergy.addActionListener(new 
				   ConnectAction(ConfigTabPanel.ENERGY));
    ConfigWaveform.addActionListener(new
				     ConnectAction(ConfigTabPanel.WAVEFORM));
    ConfigSpectrogram.addActionListener(new
					ConnectAction(ConfigTabPanel.SPECTROGRAM));
    ConfigDisplay.addActionListener(new
				    ConnectAction(ConfigTabPanel.DISPLAY));
    ConfigDetector.addActionListener(new
				     ConnectAction(ConfigTabPanel.DETECTOR));
    
    
    mbar.add(makeMenu(fileMenu3,
		      new Object[]
	{ 
	    null,
	    ConfigAudio,
	    ConfigEnergy,
	    ConfigWaveform,
	    ConfigSpectrogram,
	    ConfigDisplay,
	    ConfigDetector
	},
		      this));
    
    // add a help menu
    //
    JMenu fileMenu4 = new JMenu("Help");
    fileMenu4.addMenuListener(this);
    
    // help has no item in it
    //
    mbar.add(makeMenu(fileMenu4,
		      new Object[]
	{ 
	    null
	},
		      this));
    
	// Start making the content
	//
	Container contentPane = getContentPane();
	contentPane.setLayout(new GridLayout(2,1));

	message_window_textarea_d = new JTextArea("");
	dialog_info_textarea_d = new JTextArea("");

	// Create window that has "Dialog Navigation System" written in it
	// and will contain the energy\waveform\spectrogram
	//
	JPanel graphical_window_d = new JPanel();
	graphical_window_d.setLayout(new BorderLayout());
	graphical_window_d.setBorder(new TitledBorder(new EtchedBorder(), 
						  "Dialog Navigation System"));
	// Scope for the graphical energy\waveform\spec window
	{
	  
	    JScrollPane speech_plot_pane_d = new 
		JScrollPane(
			    speech_plot_d,
			    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
			    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	    graphical_window_d.add(speech_plot_pane_d, "Center");
	}

	// Create the window that has the bottom two text areas
	//
	main_bottom_window_d = new JPanel();
	main_bottom_window_d.setLayout(new GridLayout(1,2));
	//main_bottom_window_d.setLayout(new BorderLayout());
	
	// Create each the left and right areas and assign the
	// needed layouts
	//
	bottom_left_window_d = new JPanel();
	bottom_right_window_d = new JPanel();

	bottom_left_window_d.setLayout(new BorderLayout());
	bottom_left_window_d.setBorder(new TitledBorder(new EtchedBorder(), 
						   "Message Window"));

	bottom_right_window_d.setLayout(new BorderLayout());
	bottom_right_window_d.setBorder(new TitledBorder(new EtchedBorder(), 
						   "NLP\\Dialog Information"));

	// Scope for the bottom left window
	//
	{
	    JScrollPane bottom_left_pane_d = new
		JScrollPane(
			    message_window_textarea_d,
			    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
			    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
			    );
	    bottom_left_window_d.add(bottom_left_pane_d, BorderLayout.CENTER);
	   
	    JPanel bottom_left_button_panel = new JPanel(new BorderLayout());
	    
	    // Left panel of buttons
	    //
	    left_buttons = new JPanel(new BorderLayout());

	    // Right panel of buttons
	    //
	    right_buttons = new JPanel(new BorderLayout());    

	    // Panel of Text Input from User
	    //
	    text_input = new JPanel(new BorderLayout());

	    // Panel of (Left Buttons or Text Input)
	    //
	    buttons_or_input_pane_d = new JPanel(new CardLayout());
	    buttons_or_input_pane_d.add(left_buttons, card_panes_names_d[0]);
	    buttons_or_input_pane_d.add(text_input, card_panes_names_d[1]);

	    // Create all the buttons
	    // These do not need to be members of this class
	    // because they are only ever referenced when they
	    // create an action.
	    //
	    record_button_d = new JButton("Record");
	    playback_button_d = new JButton("Playback");
	    stop_button_d = new JButton("Stop");
	    clear_button_d = new JButton("Clear");
	    quit_button_d = new JButton("Quit");
	    JLabel input_label = new JLabel("String to input: ");
	    input_field_d = new JTextField(20);
	    
	    //add listeners to each button
	    //
	    //record_button_d.addActionListener(this);
	    //playback_button_d.addActionListener(this);
	    //stop_button_d.addActionListener(this);
	    clear_button_d.addActionListener(this);
	    quit_button_d.addActionListener(this);
	    //input_field_d.addActionListener(this);

	    // Insert each of the buttons into the correct panel
	    //
	    left_buttons.add(record_button_d, BorderLayout.WEST);
	    left_buttons.add(playback_button_d, BorderLayout.CENTER);
	    left_buttons.add(stop_button_d, BorderLayout.EAST);

	    right_buttons.add(clear_button_d, BorderLayout.WEST);
	    right_buttons.add(quit_button_d, BorderLayout.EAST);

	    // This puts the "Record\Playback\Stop" and
	    // box where user can into text into the same frame
	    //
	    text_input.add(input_label, BorderLayout.WEST);
	    text_input.add(input_field_d, BorderLayout.EAST);

	    bottom_left_button_panel.add(buttons_or_input_pane_d,
					 BorderLayout.WEST);
	    bottom_left_button_panel.add(right_buttons, BorderLayout.EAST);
	    
	    bottom_left_window_d.add(bottom_left_button_panel,
				     BorderLayout.SOUTH);
	}

	// Scope for the bottom right window
	//
	{
	    JScrollPane bottom_right_pane_d = new
		JScrollPane(
			    dialog_info_textarea_d,
			    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
			    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	    bottom_right_window_d.add(bottom_right_pane_d, "Center");
	}    

	main_bottom_window_d.add(bottom_left_window_d);
	main_bottom_window_d.add(bottom_right_window_d);


	// Add the windows to the main pane
	//
	contentPane.add(graphical_window_d);
	contentPane.add(main_bottom_window_d);
    }

/**
 * duplicate a string
 *
 * @param string_a string object.
 * @param times_a  number of duplicates
 *
 * @return string object
 */
protected String make_duplicate_string(String string_a, int times_a) {
    String ret = "";
    for (int i = 0; i < times_a; i++) {
	ret += string_a;
    }
    return ret;
}

}