// file: $ISIP_IFC/class/java/ConfigPanel/PanelAudio.java
// version: $Id: PanelAudio.java 10227 2005-09-09 19:07:49Z stanley $

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

/* This is a PanelAudio class that show the actual game play
 * @author 
 * @see GameView */

public class PanelAudio extends ConfigPanel {

    
    //---------------------------------------
    //
    // public constants
    //
    //---------------------------------------
    
    // below are the min and max vlaues for the 
    // various audio parameters
    //
   
    /**
     * lower limit for sample rate.
     */
    public double min_sample_rate = 8000;
    
    /**
     * upper limit for sample rate.
     */
    public double max_sample_rate =  32000;
     
    /**
     * lower limit for sample size.
     */
    public double min_sample_size = 0;
    
    /**
     * upper limit for sample size.
     */
    public double max_sample_size = 32;
     
    /**
     * lower limit for number of channels.
     */
    public double min_num_channels = 1;
    
    /**
     * upper limit for sample size.
     */
    public double max_num_channels = 2;
     
    /**
     * lower limit for channel displayed.
     */
    public double min_channel_displayed = 1;
    
    /**
     * upper limit for sample size.
     */
    public double max_channel_displayed = 2;
    
    /**
     * lower limit for buffer size.
     */
    public double min_buffer_size = 0;
    
    /**
     * upper limit for sample size.
     */
    public double max_buffer_size = 10;
    
    /**
     * demo name
     */
    public String demo_name_d;
    
    /**
     * Main audio configuration panel.
     */    
    public PanelAudio() {

	// constructor for the class
	//
	super();

	association_d = "Audio";

	// initialise the string
	//
	demo_name_d = new String();
	
	JPanel config_panel = new JPanel();

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

	// create the border and set the proper font
	//
	BorderUIResource.TitledBorderUIResource border =
	    new BorderUIResource.TitledBorderUIResource("Energy Configuration");
	border.setTitleColor(Color.black);

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

	// defined some enum value for later use
	//
	scale_values_d.add("dB");
	scale_values_d.add("LINEAR");

	byte_order_values_d.add("LittleEndian");
	byte_order_values_d.add("BigEndian");

	encoding_values_d.add("PCM_SIGNED");
	encoding_values_d.add("PCM_UNSIGNED");
	encoding_values_d.add("ULAW");
	encoding_values_d.add("ALAW");
	file_format_d.add("RAW");
	file_format_d.add("WAV");
	file_format_d.add("SPHERE");
	file_format_d.add("SOF");

	// this enum value is to choose the mode of playback
	//
	playback_mode_d.add("ALL");
	playback_mode_d.add("SIGNAL_ONLY");    

	// define the labels, types default value, minimum value,
	// maximum value and action commands
	//
	// it will look like this in the panel
	//
	// label     textfield(default value) or enum
	//    
	labels_d.add("Sample rate (Hz)");
	labels_d.add("Sample size (bits)");
	labels_d.add("Number of channels");
	labels_d.add("Channel displayed");
	labels_d.add("Buffer Size (seconds)");

	labels_d.add("Byte order");
	labels_d.add("Encoding");
	labels_d.add("Scale");
	labels_d.add("Speaker / Headphones");
	labels_d.add("File format");
	labels_d.add("Playback mode");

	types_d.add("double");
	types_d.add("double");
	types_d.add("double");
       	types_d.add("double");
	types_d.add("double");

	types_d.add("enum");
	types_d.add("enum");
	types_d.add("enum");
	types_d.add("boolean");
	types_d.add("enum");
	types_d.add("enum");

	// default value
	//
	values_d.add("16000.0");
	values_d.add("16");
	values_d.add("1");
	values_d.add("1");
	values_d.add("1");

	values_d.add(byte_order_values_d);
	values_d.add(encoding_values_d);
	values_d.add(scale_values_d);
	values_d.add("true");
	values_d.add(file_format_d);
	values_d.add(playback_mode_d);

	// minimum value
	//
	min_values_d.add("0");
	min_values_d.add("0");
	min_values_d.add("0");
	min_values_d.add("0");
	min_values_d.add("0");

	min_values_d.add("0");
	min_values_d.add("0");
	min_values_d.add("0");
	min_values_d.add("0");

	// maximum value
	//
	max_values_d.add("32000");
	max_values_d.add("32");
	max_values_d.add("6");
	max_values_d.add("6");
	max_values_d.add("32000");

	max_values_d.add("4");
	max_values_d.add("0");
	max_values_d.add("0");
	max_values_d.add("0");

	// action command name
	//
	commands_d.add("SampleRate");
	commands_d.add("SampleSize");
	commands_d.add("NumChannels");
	commands_d.add("ChannelDisplayed");
	commands_d.add("BufferSize");
	
	commands_d.add("ByteOrder");
	commands_d.add("Encoding");
	commands_d.add("Scale");
	commands_d.add("Speaker");
	commands_d.add("FileFormat");
	commands_d.add("PlaybackMode");

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

	    // add a label for all labels
	    //
	    String configLabel = (String)labels_d.get(i);
	    JLabel jlabel = new JLabel(configLabel);

	    jlabel.setForeground(Color.black);
	    constrain(config_panel, jlabel, gridbag, 0, i,
		      1, 1, 1, 0, GridBagConstraints.WEST);

	    // creation of input box for double
	    //
	    if (types_d.get(i).equals("double")) {
		
		int x = (int)(Float.parseFloat((String)values_d.get(i)) * 100);

		int min = (int)(Float.parseFloat((String)min_values_d.get(i)) * 100);
		int max = (int)(Float.parseFloat((String)max_values_d.get(i)) * 100);

		Dimension size = new Dimension(WIDTH, HEIGHT);

		FloatTextField hourField;

		hourField = new FloatTextField((int)Float.parseFloat((String)values_d.get(i)), 7);

		inputed_data_d.add((String)values_d.get(i));
      
		text_field_d.add(hourField);

		constrain(config_panel, (FloatTextField)(text_field_d).get(i), gridbag, 10, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);

		entered_data_d.add(hourField);
		block_type_d.add("double");
	    }

	    // creation of input box for double
	    //
	    if (types_d.get(i).equals("integer")) {
		
		int x =  Integer.parseInt((String)values_d.get(i));

		int min = Integer.parseInt((String)min_values_d.get(i));

		int max = Integer.parseInt((String)max_values_d.get(i));


		Dimension size = new Dimension(WIDTH, HEIGHT);

		FloatTextField hourField;

		hourField = new FloatTextField((int)Float.parseFloat((String)values_d.get(i)), 7);

		inputed_data_d.add((String)values_d.get(i));
      
		text_field_d.add(hourField);

		constrain(config_panel, (FloatTextField)(text_field_d).get(i), gridbag, 10, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);

		entered_data_d.add(hourField);
		block_type_d.add("integer");
	    }
 

	    else if (types_d.get(i).equals("enum")){
		
		// create a drop down list to allow selection from
		//
		JComboBox select = new JComboBox();

		select.setForeground(Color.black);

		// retrieve and add all possible values to this list
		//
		Vector enum_values = (Vector)values_d.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, 10, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		entered_data_d.add(select);
		block_type_d.add("enum");
	    }

	    // make a check box for a boolean type
	    //
	    else if (types_d.get(i).equals("boolean")){
		
		// create the check box
		//
		String value = (String)values_d.get(i);
		
		// get the default value for the button
		//
		boolean value2;
		if (value.equals( "true"))
		    value2 = true;
		else
		    value2 = false;
		
		// instantiate and place check box on config panel
		//
		JCheckBox checkBox = new JCheckBox("", value2);

		constrain(config_panel, checkBox, gridbag, 10, i,
			  1, 1, 1, 0, GridBagConstraints.EAST);
		entered_data_d.add(checkBox);
		block_type_d.add("boolean");

	    }

	    if (!types_d.get(i).equals("double") && !types_d.get(i).equals("integer")) {
		// add dummy item to keep track the index
		//
		String x = "NULL";
		inputed_data_d.add(x);
		text_field_d.add(x);
	    }
	}

	this.setLayout(new BorderLayout());

	add(config_panel,  "North");
    }


    /**
     * Method to verify the input value
     * 
     * @param parameter the value of the parameter that is checked
     * @param min_value the minimum value of the parameter
     * @param max_value the maximum value of the parameter
     * @param parameter_name the name of the parameter to be displayed on the
     *                       warning screen
     * @return  a boolean value indicating status.
     *
     */
    public boolean checkRange(double parameter, double min_value, double max_value, String parameter_name ) {
    
	if (min_value == 0) {
	    if (parameter <= min_value || parameter > max_value) {
	 
	    JFrame frame = new JFrame("Warning"); 
	    String warningMessage = new 
		String(parameter_name + " :" + " Please enter a value greater than " + min_value 
		       + " and less than or equal to " + max_value + ".");
	    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
	    
	    return false;
	    }
	}

	    else {
		if (parameter < min_value || parameter > max_value) {
		    
		    JFrame frame = new JFrame("Warning"); 
		    String warningMessage = new 
			String(parameter_name + " :" + " Please enter a value between " + min_value 
			       + " and " + max_value + ".");
		    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
		    
		    return false;
		}
		
	    }
		return true;
    }
	    
    /**
     * Method to verify the input value
     *     
     * @return  a boolean value indicating status.
     *
     */
    public boolean apply() {

	update();

	// local variables to hold the parsed value
	//
	boolean success = true;
	float sample_rate = 0;
	int sample_size = 0;
        int num_channels = 0;
	int channel_displayed = 0;
	int buffer_size = 0;
	String file_format = new String();
	String encoding =  new String();
	
	for (int i = 0; i < cfg_data_d.getAssociation().size(); i++) {

	    if (cfg_data_d.getName().get(i).equals("SampleRate")) {
	        sample_rate = Float.parseFloat((String)(cfg_data_d.getValue().get(i)));
	    }
	    else if (cfg_data_d.getName().get(i).equals("SampleSize")) {
	        sample_size = (int)Float.parseFloat((String)(cfg_data_d.getValue().get(i)));
	    }
	    else if (cfg_data_d.getName().get(i).equals("NumChannels")) {
		num_channels = (int)Float.parseFloat((String)(cfg_data_d.getValue().get(i)));
	    }
	    else if (cfg_data_d.getName().get(i).equals("ChannelDisplayed")) {
		channel_displayed = (int)Float.parseFloat((String)(cfg_data_d.getValue().get(i)));
	
	    }
	    else if (cfg_data_d.getName().get(i).equals("BufferSize")) {
		buffer_size = (int)Float.parseFloat((String)(cfg_data_d.getValue().get(i)));

	    }
	    
	    else if (cfg_data_d.getName().get(i).equals("FileFormat")) {
		file_format = (String)(cfg_data_d.getValue().get(i));
		
	    }
	    
	    else if (cfg_data_d.getName().get(i).equals("Encoding")) {
		encoding = (String)(cfg_data_d.getValue().get(i));
		
	    }
	    
	    else {
		// do nothing
	    }

	}

	System.out.println("sample_rate = " + sample_rate);
	System.out.println("sample_size = " + sample_size);
	System.out.println("num_channels = " + num_channels);
	System.out.println("channel_displayed = " + channel_displayed); 
	System.out.println("buffer_size = " + buffer_size);


	//----------------------------------------------------
	//
	// range checking
	//
	//----------------------------------------------------

	if (!(checkRange(sample_rate, min_sample_rate, max_sample_rate, "SampleRate"))) {

		success = false;
	    }

	if (!(checkRange(sample_size, min_sample_size, max_sample_size, "SampleSize"))) {

		success = false;
	     }   
	     

	if (!(checkRange(buffer_size, min_buffer_size, max_buffer_size, "BufferSize"))) {
	    
	    success = false;
	}
	
	if ( num_channels < min_num_channels || num_channels > max_num_channels) {
	    
	    JFrame frame = new JFrame("Warning"); 
	    String warningMessage = new 
		String("NumOfChannels: " + "Please enter 1(mono) or 2(stereo)");
	    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
	    
	    success = false;

	}
	
	if ( channel_displayed < min_channel_displayed || channel_displayed > max_channel_displayed) {
		
		
		JFrame frame = new JFrame("Warning"); 
		String warningMessage = new 
		    String("ChannelToBeDisplayed: " + "Please enter 1(mono) or 2(stereo)");
		JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
		
		success = false;
	}

	//-------------------------------------------------------------
	//
	// dependency checking
	//
	//-------------------------------------------------------------
	
	// make sure the channel to be displayed is greater than number of channels
	// 
	if (channel_displayed > num_channels) {
	    
	    JFrame frame = new JFrame("Warning"); 
	    String warningMessage = new 
		String("ChannelDisplay: The channel to be displayed cannot be greated than the number of channels.");
	    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
	    
	    success = false;
	}

	// checking for specific options
	//
	if ((demo_name_d.equals("SpeechRecognition")||demo_name_d.equals("DialogNavigation")||
	     demo_name_d.equals("SpeakerVerification")) 
	    && !(file_format.equals("SOF"))) {
		 
		 JFrame frame = new JFrame("Warning"); 
		 String warningMessage = new 
		     String("FileFormat: SOF is the only supported format.");
		 JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
		 
		 success = false;
	     }
	     
	     // checking for specific options
	     //
	     else if (file_format.equals("WAV")) {
		 
		 JFrame frame = new JFrame("Warning"); 
		 String warningMessage = new 
		     String("FileFormat: WAV file format is not supported.");
		 JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
		 
		 success = false;
	     }

	// checking for specific options
	//
	if (file_format.equals("WAV")) {
	    
	    JFrame frame = new JFrame("Warning"); 
	    String warningMessage = new 
		String("FileFormat: WAV file format is not supported.");
	    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
	    
	    success = false;
	}

	// checking for specific options
	//
	if (!(encoding.equals("PCM_SIGNED"))) {
	    
	    JFrame frame = new JFrame("Audio Panel Warning"); 
	    String warningMessage = new 
		String("Encoding: PCM SIGNED is the only supported encoding type.");
	    JOptionPane.showMessageDialog(frame, warningMessage, "Audio Panel", JOptionPane.WARNING_MESSAGE);
	    
	    success = false;
	    }

	return success;
    }


    /**
     * Get the name of the demo.
     *
     * @return a String variable containing the demo
     * name
     */
    public String getDemoName() {
	return demo_name_d;
    }
    
    /**
     * Set the name of the demo.
     *
     * @return a boolean value
     */
    public boolean setDemoName(String demo_name_a) {
	demo_name_d = new String();
	demo_name_d = demo_name_a;
	return true;
    }
    
}
