// file: DataDisplay.java
//

// include the necessary system files
//
//import java.awt.*;
import java.lang.*;
import java.lang.Math;
import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.GridBagConstraints;
import javax.swing.border.*;
import java.awt.BorderLayout;
// import the necessary local files
//
//import Constants;

// class: DataDisplay
//
// this class implements a canvas which holds a list of poles 
// and zeros.
//
public class DataDisplayPanel extends SubPanel implements Constants{
    
    // set class constants
    //
    
    // constant default number of rows in the list boxes
    //
    public final static int DEFAULT_LIST_LENGTH = 3;
    
    // constant default number of pixels between list boxes
    //
    public final static int INSET_SIZE = 10;
    
    // list boxes to display the poles and zeros
    //
    DefaultListModel pole_listModel = new DefaultListModel();
    JList pole_list = new JList(pole_listModel); 
    DefaultListModel zero_listModel = new DefaultListModel();
    JList zero_list = new JList(zero_listModel); 
    JScrollPane poleScroll, zeroScroll;
    JSplitPane splitPane;
    
    // labels for the list boxes
    //
    private JLabel pole_label = new JLabel("Poles");
    private JLabel zero_label = new JLabel("Zeros");
    
    // variable to hold the design type
    //
    private int design_type = Constants.DEFAULT_DESIGN;
    
    // variables to hold the currently selected list and the
    // currently selected list index
    //
    private int selected_list;
    private int selected_index = -1;
    
    // boolean to determine if a list item is selected
    //
    private boolean is_selected = false;
    
    // declare the default fonts
    //
    Font currentFont = getFont();
    Font newFont = new Font(currentFont.getName(), currentFont.getStyle(), 12);
    
    // Define border
    //
    Border border;
    
    
    //*****************************************************************
    //
    // constructor methods
    //
    //*****************************************************************
    
    // method: DataDisplayPanel
    //
    // parameters: none
    // 
    // this method constructs a DataDisplayPanel of the default type
    //
    public DataDisplayPanel(int type) {
	
	// call the super-class's constructor
	//
	super();
	
	// set the design_type 
	//
	design_type = type;
	
	// add components to the layout
	//
	this.add_components();
	
    }
    
    
    //***************************************************************
    //
    // private methods
    //
    //***************************************************************
    
    
    // method: add_components
    //
    // parameters: none
    // 
    // this method initializes the gui components of the class
    //
    // returns: boolean
    //  
    
    //    public boolean add_pole(double frequency, double bandwidth) {
    
    private boolean add_components() {   
	
	
	pole_label.setFont(newFont);
	pole_label.setForeground(Color.black);
	
	zero_label.setFont(newFont);
	zero_label.setForeground(Color.black);
	
	pole_list.setBackground(Color.white);
	zero_list.setBackground(Color.white);
	
	poleScroll = new JScrollPane(pole_list);
	zeroScroll = new JScrollPane(zero_list);
	Dimension dim = new Dimension(150,50);
	poleScroll.setPreferredSize(dim);
	zeroScroll.setPreferredSize(dim);
	
	
	/*   
	     splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
	     poleScroll, zeroScroll);
	     splitPane.setOneTouchExpandable(true);
	     splitPane.setDividerLocation(150);
	     Dimension minimumSize = new Dimension(100, 50);
	     poleScroll.setMinimumSize(minimumSize);
	     zeroScroll.setMinimumSize(minimumSize);
	     splitPane.setPreferredSize(new Dimension(400, 200));
	*/
	
	// add components and labels to this panel while creating constraints 
	// for each
	//
	//constrain(this, pole_label, 0, 0, 1, 1, 
	//      GridBagConstraints.NONE, GridBagConstraints.NORTH, 
	//      1.0, 1.0, 0, 0, 0, 0);
	//constrain(this, zero_label, 1, 0, 1, 1, 
	//      GridBagConstraints.NONE, GridBagConstraints.NORTH, 1.0, 
	//      1.0, 0, 0, 0, 0);
	border =  new TitledBorder(new EmptyBorder(0,0,0,0),"Poles",
				   TitledBorder.LEFT,TitledBorder.LEFT,
				   new Font(currentFont.getName(), 
					    currentFont.getStyle(), 12),
				   Color.black);
	poleScroll.setBorder(border);
	constrain(this, poleScroll, 0, 0, 1, 1, GridBagConstraints.BOTH, 
		  GridBagConstraints.WEST, 0.5, 1.0, Constants.INSET_SIZE, 
		  Constants.INSET_SIZE, Constants.INSET_SIZE,
		  Constants.INSET_SIZE);
	border =  new TitledBorder(new EmptyBorder(0,0,0,0),"Zeros",
				   TitledBorder.LEFT,TitledBorder.LEFT,
				   new Font(currentFont.getName(), 
					    currentFont.getStyle(), 12),
				   Color.black);
	zeroScroll.setBorder(border);
	constrain(this, zeroScroll, 0, 1, 1, 1, GridBagConstraints.BOTH, 
		  GridBagConstraints.WEST, 0.5, 1.0, Constants.INSET_SIZE, 
		  Constants.INSET_SIZE, Constants.INSET_SIZE,
		  Constants.INSET_SIZE);
	
	// exit gracefully
	//
	return true;
	
    }
    
    //****************************************************************
    //
    // public methods
    //
    //****************************************************************
    
    // method: clear_all
    //
    // parameters:
    //
    // this is a method to clear all poles and zeros from the lists
    //
    // returns: boolean
    //
    public boolean clear_all() {
	
	// clear the lists [if they are non empty (fix by RJD, 5/21/98)]
	//
	
	if (pole_listModel.getSize() > 0) {
	    pole_listModel.removeAllElements();
	}
	
	if (zero_listModel.getSize() > 0) {
	    zero_listModel.removeAllElements();
	}
	
	// exit gracefully
	//
	return true;
    }
    
    
    // method: add_zero
    //
    // parameters: 
    //     double frequency: (input) frequency of zero to add
    //     double bandwidth: (input) bandwidth of zero to add
    //
    // this is a method to add a zero to the pzmap
    //
    // returns: boolean
    //
    public boolean add_zero(double frequency, double bandwidth) {
	
	// add item to the zero list
	//
	int zero_index = zero_list.getSelectedIndex();
	int zero_size = zero_listModel.getSize();
	
	double temp_freq,temp_band;
	
	temp_freq=SetDecimal(frequency,2);
	temp_band=SetDecimal(bandwidth,2);
	
	if (zero_index == -1 || (zero_index + 1 == zero_size) ) {
	    zero_listModel.addElement("f = " + temp_freq + 
				      " BW = " + temp_band);
	    zero_list.setSelectedIndex(zero_size);
	}
	// exit gracefully
	//
	return true;
    }
    
    
    // method: add_pole
    //
    // parameters: 
    //     frequency: (input) frequency of pole to be added
    //     bandwidth: (input) bandwidth of pole to be added  
    //
    // this is a method to add a pole to the pzmap
    //
    // returns: boolean
    //
    public boolean add_pole(double frequency, double bandwidth) {
	
	// add item to the pole list
	//
	int pole_index = pole_list.getSelectedIndex();
	int pole_size = pole_listModel.getSize();
	
	double temp_freq,temp_band;
	
	temp_freq=SetDecimal(frequency,2);
	temp_band=SetDecimal(bandwidth,2);
	
	
	if (pole_index == -1 || (pole_index + 1 == pole_size) ) {
	    pole_listModel.addElement("f = " + temp_freq + 
				      " BW = " + temp_band);
	    pole_list.setSelectedIndex(pole_size);
	}
	// exit gracefully
	//
	return true;
    }
    
    
    // method: set_design_type 
    //
    // parameters:
    //     integer new_type: (input) design type to change to
    //
    // this is a method to set the design type.  the design type will
    // be set to the value passed in to new_type
    //
    // returns: boolean
    //
    public boolean set_design_type(int new_type) {
	
	// make sure the new_type is valid, then set the design_type
	// variable, and return a boolean value which indicates whether
	// or not the new_type was valid.  note:  this assumes that 
	// the design_type is currently a valid value
	//
	if((new_type == Constants.DIGITAL) || (new_type == Constants.ANALOG)) {
	    design_type = new_type;
	    this.clear_all();
	    return true;
	}
	else {
	    return false;
	}
    }
    
    
    // method: reset_selected
    //
    // parameters: 
    //
    // this is a method resets the lists so that both are deselected
    //
    // returns: boolean
    //
    public boolean reset_selected() {
	
	// deselect item from the appropriate list
	//
	if (selected_list == Constants.POLE_INDICATOR) {
	    pole_list.clearSelection();
	    //      pole_list.deselect(selected_index);
	}
	else {
	    zero_list.clearSelection();
	    //      zero_list.deselect(selected_index);
	}
	
	// set variables to be invalid
	//
	is_selected = false;
	selected_index = -1;
	
	// exit gracefully
	//
	return true;
	
    }
    
    
    // method: remove_selected
    //
    // parameters: 
    //
    // this is a method removes the current pole/zero from its list
    //
    // returns: boolean
    //
    public boolean remove_selected() {
	
	// deselect item from the appropriate list
	//
	if (selected_list == Constants.POLE_INDICATOR) {
	    pole_list.remove(pole_list.getSelectedIndex());
	}
	else {
	    zero_list.remove(zero_list.getSelectedIndex());
	}
	
	// set variables to be invalid
	//
	is_selected = false;
	selected_index = -1;
	
	// exit gracefully
	//
	return true;
	
    }
    
    
    // method: select_item
    //
    // parameters: 
    //     double frequency: old frequency
    //     double bandwidth: old bandwidth
    //     int type: is it a pole or a zero
    //
    // this is a method to set the selected item in one of the lists
    //
    // returns: boolean
    //
    public boolean select_item(double frequency, double bandwidth, int type) {
	
	// declare local variables
	//
	String old_string;
	int length;
	
	// assign the string
	//
	old_string = new String("f = " + frequency +  "  BW = "+ bandwidth);
	
	// find the item in the appropriate list
	//
	if (type == Constants.POLE_INDICATOR) {
	    length = pole_listModel.getSize();
	    is_selected = false;
	    for (int i = 0; (is_selected == false) && (i < length); i++) {
		if (old_string.equals(pole_listModel.elementAt(i))) {
		    pole_list.setSelectedIndex(i);
		    is_selected = true;
		    selected_list = Constants.POLE_INDICATOR;
		    selected_index = i;
		}
	    }
	}
	else {
	    length = zero_listModel.getSize();
	    is_selected = false;
	    for (int i = 0; (is_selected == false) && (i < length); i++) {
		if (old_string.equals(zero_listModel.elementAt(i))) {
		    zero_list.setSelectedIndex(i);
		    is_selected = true;
		    selected_list = Constants.ZERO_INDICATOR;
		    selected_index = i;
		}
	    }
	}
	
	// exit gracefully
	//
	return true;
    }
    
    
    // method: change_value
    //
    // parameters: 
    //     double new_freq: new real or frequency
    //     double new_band: new imaginary or bandwidth
    //
    // this is a method to change a pole or zero in the map
    //
    // returns: boolean
    //
    public boolean change_value(double new_freq, double new_band) {
	
	// declare local variables
	//
	String new_string;
	
	// determine if anything is selected
	//
	if (is_selected) {
	    // assign the string
	    //
	    new_string = new String("f = " + new_freq +  "  BW = "+ new_band);
	    
	    // determine the list to update and do so
	    //
	    if (selected_list == Constants.POLE_INDICATOR) {
		pole_listModel.setElementAt(new_string, selected_index);
		//	pole_list.replaceItem(new_string, selected_index);
	    }
	    else {
		zero_listModel.setElementAt(new_string, selected_index);
		//	zero_list.replaceItem(new_string, selected_index);
	    }
	}
	
	// exit gracefully
	//
	return true;
    }
    
    // method: update
    //
    // parameters: 
    //     PoleZero pz_array - array of poles and zeros to be put into 
    //                         the display
    //
    // this is a method to put all poles and zeros in the display
    //
    // returns: boolean
    //
    public boolean update(PoleZero pz_array[]) {
	
	// declare local variables
	//
	int i;
	
	// clear all of the old values
	//
	this.clear_all();
	
	// loop through all poles and zeros
	//
	i = 0;
	while (pz_array[i] != null) {
	    double freq = pz_array[i].frequency;
	    double band = pz_array[i].bandwidth;
	    
	    // add the item to the display area
	    //
	    if (pz_array[i].pz_indicator == Constants.POLE_INDICATOR) {
		add_pole(freq, band);
		
		// check for a conjugate
		//
		if (pz_array[i].conj_flag) {
		    add_pole(-freq, band);
		}
	    }
	    else {
		add_zero(freq, band);
		
		// check for a conjugate
		//
		if (pz_array[i].conj_flag) {
		    add_zero(-freq, band);
		}
	    }
	    
	    // increment array index
	    //
	    i++;
	}
	
	// exit gracefully
	//
	return true;
    }
    
    // method: setDecimal
    //
    // arguments:
    //   double doubleNumber: input digit to be rounded off
    //   int decimalPlaces: number of significant to round the input digit 
    //
    // return :
    //    double result: the rounded off input digit
    //
    // method takes in a input digit (double) and rounds the input digit
    // to the number of speified significant places specified
    //
    public double SetDecimal(double doubleNumber, int decimalPlaces) {
	int wholeNumber,roundedDecimal,combine;
	double pastDecimal,result;
	
	wholeNumber = (int)doubleNumber;
	pastDecimal = ((doubleNumber - wholeNumber) * 
		       Math.pow(10,decimalPlaces));
	roundedDecimal = (int) Math.round(pastDecimal);
	combine = (int)(wholeNumber * 
			Math.pow(10,decimalPlaces)+roundedDecimal);
	result = combine / Math.pow(10,decimalPlaces);
	return result;
    }
    
} // end class DataDisplay
