import phases.*;
import phases.dPhasePackage.*;
import phases.PhaseManagerPackage.*;
import common.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.text.*;
import java.util.*;

import javax.naming.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.*;

/**
 * Phase Properties application.
 * This is a Java implementation of a CORBA client that uses functions defined in the phases IDL.
 * @version 3.0 (August 2007)
 * @author Mark S. Ghiorso, OFM-Research Inc.
 */
public class CalcClient extends JApplet {
  /**
   * Public declaration of applet container.
   */
  public Container cp;
  /**
   * Public declaration of applet frame.
   */
  public JFrame frame;
  /**
   * True if invoked as a standalone application; false if invoked as an applet.
   */
  public boolean isStandalone = false;
  /**
   * Command line arguments passed to application.
   */
  public String args[];
  /**
   * Phase factory server class instance.
   */
  public PhaseFactory pFactory;
  /**
   * Phase manager server class instance.
   */
  public PhaseManager pManager;
  /**
   * Phase class instance spawned on server by pFactory.
   */
  public phases.dPhase phase1;
  
  private JComboBox phaseChoice, actionChoice;
  private JPanel bcPanel;
  private JLabel minLabel[][], bcLabel[], muTitle;
  private JFormattedTextField bcEntry[], tEntry, pEntry, minEntry[], muField[];
  private JFormattedTextField cpField, gField, sField, hField, vField, mField;
  private String minBlank, compList[], compFormula[], genCompList[];
  private int ncomp, gncomp;
  
  private static final int MAXgncomp = 19;  // maximum number of generic components
  private static final int MAXncomp  = 19;  // maximum number of phase components
  
//private static final String nameServer = "localhost";      // local nameserver (development)
  private static final String nameServer = "216.231.56.159"; // OFM Research Inc.

  /**
   * Converts numbers in a string to subscripts.
   * @param input String to be converted. Content is not altered.
   * @return Converted string with numbers replaced by subscripts.
   */
  public static String makeSubscript (String input) {
    String out1, out2, output;
    out1   = input.replace('0', '\u2080');
    out2   =  out1.replace('1', '\u2081');
    out1   =  out2.replace('2', '\u2082');
    out2   =  out1.replace('3', '\u2083');
    out1   =  out2.replace('4', '\u2084');
    out2   =  out1.replace('5', '\u2085');
    out1   =  out2.replace('6', '\u2086');
    out2   =  out1.replace('7', '\u2087');
    out1   =  out2.replace('8', '\u2088');
    output =  out1.replace('9', '\u2089');
    return output;
  }

  /**
   * Generates class instance. Called by applet manager.
   */
  public CalcClient() {
  }
  
  /**
   * Generates class instance. Called when invoked as a standalone application. 
   * @param args String array of standard arguments used to initialize the class.
   */
  public CalcClient(String args[]) {
    this.isStandalone = true;
    this.args = args;
  }
  
  /**
   * Applet method. Creates GUI interface.  
   */
  public void init() {

    String laf = UIManager.getCrossPlatformLookAndFeelClassName();

    try {
      UIManager.setLookAndFeel(laf);
    } catch(Exception ce) {
      System.err.println("Error loading" + laf + ":" +ce);
    }

    // ORB Call
    try {
      Connection c1 = new Connection();
      ORB orb;
      
      if (isStandalone) {
        java.util.Properties props = new java.util.Properties();
        props.put("org.omg.CORBA.ORBInitialPort", "2809");
        props.put("org.omg.CORBA.ORBInitialHost", nameServer);
        orb = c1.getORB(args, props);
      
      } else orb = c1.getORB(this); 
      pFactory = c1.getdPhaseFactory(orb);
      pManager = c1.getdPhaseManager(orb);
    } catch (Exception e) {
      System.out.println("ERROR in ORB initialization: " + e);
    }
    // ... End ORB Call

    //***************************
    // Create the Applet Instance
    //***************************
    frame = new JFrame("CORBA Phase Properties Applet");
    if (isStandalone) {
      frame.addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowClosing(java.awt.event.WindowEvent e) {
	  if (phase1 != null) phase1.remove();
    	  System.exit(0);
        }
      });
    }
    cp = frame.getContentPane();
    
    JApplet applet = new CalcClient();
    
    GridBagLayout gbl = new GridBagLayout();
    GridBagConstraints gbc = new GridBagConstraints();
    cp.setLayout(gbl);
    frame.setVisible(true);

    //*********************************************
    // Get list of available phases from the server
    //*********************************************
    String phaseList[] = pFactory.getPhaseNames();
    int phaseNum = phaseList.length;

    //*************************
    // Create the GUI interface
    //*************************
    JLabel label1 = new JLabel("Phase Properties Applet, v 3.0");
           label1.setFont(new Font("Helvetica", Font.BOLD, 24));
           label1.setForeground(Color.red);
	   label1.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, label1, 0, 0, 7, 1, GridBagConstraints.BOTH, GridBagConstraints.NORTHWEST);

    bcPanel = new JPanel();
    bcPanel.setLayout(new GridLayout(MAXgncomp, 2));

    bcLabel = new JLabel[MAXgncomp];
    
    bcEntry = new JFormattedTextField[MAXgncomp];
    NumberFormat bcFormat = NumberFormat.getNumberInstance();
                 bcFormat.setMaximumFractionDigits(3);

    // Blank string placeholder
    StringBuffer s1 = new StringBuffer("");
    for (int j=0; j<10; j++) s1.append("-");
    minBlank = s1.toString();
    
    for (int i=0; i<MAXgncomp; i++) {
        bcPanel.add(bcLabel[i] = new JLabel(minBlank));
        bcEntry[i] = new JFormattedTextField(bcFormat);
	bcEntry[i].setColumns(7); 
        bcEntry[i].setEditable(false);
        bcEntry[i].setHorizontalAlignment(JTextField.RIGHT);
        bcEntry[i].setValue(new Double(0.0));
	bcPanel.add(bcEntry[i]);
    }
    int bcLength = Math.max(MAXgncomp, 2+MAXncomp+1+3+2+MAXncomp/2);
    addComponent(cp, bcPanel, 0, 2, 2, bcLength+2, GridBagConstraints.BOTH, GridBagConstraints.CENTER);

    // GUI buttons
    JButton help = new JButton("Help");
      HelpHandler handler = new HelpHandler();
      help.addActionListener(handler);
      addComponent(cp, help, 7, 0, 1, 1, GridBagConstraints.BOTH, GridBagConstraints.EAST);

    // GUI labels and text entries
    JLabel wtLabel = new JLabel("Wt [%]:", JLabel.RIGHT);
           wtLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    JLabel  tLabel = new JLabel("T [K]:");
            tLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    JLabel  pLabel = new JLabel("P [bars]:");
            pLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    JLabel phLabel = new JLabel("Phase:");
           phLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    JLabel uaLabel = new JLabel("User action:"); 
           uaLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    addComponent(cp, wtLabel, 1, 1, 1, 1, GridBagConstraints.BOTH, GridBagConstraints.CENTER);
    addComponent(cp,  tLabel, 2, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    addComponent(cp,  pLabel, 4, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    addComponent(cp, phLabel, 2, 3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    addComponent(cp, uaLabel, 4, 3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);

    NumberFormat tFormat = NumberFormat.getNumberInstance();
                 tFormat.setMaximumFractionDigits(2);    
    tEntry = new JFormattedTextField(tFormat);
    tEntry.setHorizontalAlignment(JTextField.RIGHT);
    tEntry.setColumns(8); 
    tEntry.setValue(new Double(1273.15)); 
    tEntry.setEditable(true);
    addComponent(cp, tEntry, 3, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    NumberFormat pFormat = NumberFormat.getNumberInstance();
                 pFormat.setMaximumFractionDigits(0);    
    pEntry = new JFormattedTextField(pFormat);
    pEntry.setHorizontalAlignment(JTextField.RIGHT);
    pEntry.setColumns(8); 
    pEntry.setValue(new Double(1.0));
    pEntry.setEditable(true);
    addComponent(cp, pEntry, 5, 2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // Popup menu of selectable phases - note that the item listener instance is defined below
    phaseChoice = new JComboBox();
    phaseChoice.addItem("No Phase");
    for (int i=0; i<phaseNum; i++) phaseChoice.addItem(phaseList[i]);
    addComponent(cp, phaseChoice, 3, 3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);
    phaseChoice.addItemListener(phaseChoiceHandler);

    // Popup menu for user action
    actionChoice = new JComboBox();
    actionChoice.addItem("No user action");
    actionChoice.addItem("Convert Wt% -> X");
    actionChoice.addItem("Convert X -> Wt%");
    actionChoice.addItem("X ->Thermo Prop");
    addComponent(cp, actionChoice, 5, 3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);
    actionHandler userActionHandler = new actionHandler();
    actionChoice.addActionListener(userActionHandler);

    minLabel = new JLabel[2][MAXncomp];
    minEntry = new JFormattedTextField[MAXncomp];
    NumberFormat minFormat = NumberFormat.getNumberInstance();
                 minFormat.setMaximumFractionDigits(6);  
		   
    for (int i=0; i<MAXncomp; i++) {
      addComponent(cp, minLabel[0][i] = new JLabel(minBlank), 3, 4 + i, 2, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);
      addComponent(cp, minLabel[1][i] = new JLabel(minBlank), 4, 4 + i, 2, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);
      minEntry[i] = new JFormattedTextField(minFormat);
      minEntry[i].setHorizontalAlignment(JTextField.RIGHT);
      minEntry[i].setColumns(10);
      minEntry[i].setValue(new Double(0.0));
      minEntry[i].setEditable(false);
      addComponent(cp, minEntry[i], 5, 4 + i, 2, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    }

    addComponent(cp, new JLabel("   "), 4, 4+MAXncomp+2, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    Color c = new Color(112, 219, 219);

    // gibbs free energy
    JLabel gLabel = new JLabel("Gibbs [J]:");
           gLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, gLabel, 2, 4+MAXncomp+3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat gFormat = NumberFormat.getNumberInstance();
                 gFormat.setMaximumFractionDigits(0);
		 gFormat.setMinimumFractionDigits(0);  
    gField = new JFormattedTextField(gFormat);
    gField.setColumns(8);
    gField.setBackground(c);
    gField.setForeground(Color.black);
    gField.setEditable(false);
    gField.setHorizontalAlignment(JTextField.RIGHT);
    gField.setValue(new Double(0.0));
    addComponent(cp, gField, 3, 4+MAXncomp+3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // enthalpy
    JLabel hLabel = new JLabel("Enthalpy [J/K]:");
           hLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, hLabel, 4, 4+MAXncomp+3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat hFormat = NumberFormat.getNumberInstance();
                 hFormat.setMaximumFractionDigits(0);
		 hFormat.setMinimumFractionDigits(0);  
    hField = new JFormattedTextField(hFormat);
    hField.setColumns(8);
    hField.setBackground(c);
    hField.setForeground(Color.black);
    hField.setEditable(false);
    hField.setHorizontalAlignment(JTextField.RIGHT);
    hField.setValue(new Double(0.0));
    addComponent(cp, hField, 5, 4+MAXncomp+3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // entropy
    JLabel sLabel = new JLabel("Entropy [J/K]:");
           sLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, sLabel, 2, 4+MAXncomp+4, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat cpFormat = NumberFormat.getNumberInstance();
                 cpFormat.setMaximumFractionDigits(3);
		 cpFormat.setMinimumFractionDigits(3);  
    sField = new JFormattedTextField(cpFormat);
    sField.setColumns(8);
    sField.setBackground(c);
    sField.setForeground(Color.black);
    sField.setEditable(false);
    sField.setHorizontalAlignment(JTextField.RIGHT);
    sField.setValue(new Double(0.0));
    addComponent(cp, sField, 3, 4+MAXncomp+4, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // heat capacity
    JLabel cpLabel = new JLabel("Cp [J/K]:");
           cpLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, cpLabel, 4, 4+MAXncomp+4, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat sFormat = NumberFormat.getNumberInstance();
                 sFormat.setMaximumFractionDigits(3); 
		 sFormat.setMinimumFractionDigits(3); 
    cpField = new JFormattedTextField(sFormat);
    cpField.setColumns(8);
    cpField.setBackground(c);
    cpField.setForeground(Color.black);
    cpField.setEditable(false);
    cpField.setHorizontalAlignment(JTextField.RIGHT);
    cpField.setValue(new Double(0.0));
    addComponent(cp, cpField, 5, 4+MAXncomp+4, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // volume
    JLabel vLabel = new JLabel("Volume [cc]:");
           vLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, vLabel, 2, 4+MAXncomp+5, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat vFormat = NumberFormat.getNumberInstance();
                 vFormat.setMaximumFractionDigits(3);
		 vFormat.setMinimumFractionDigits(3);  
    vField = new JFormattedTextField(vFormat);
    vField.setColumns(8);
    vField.setBackground(c);
    vField.setForeground(Color.black);
    vField.setEditable(false);
    vField.setHorizontalAlignment(JTextField.RIGHT);
    vField.setValue(new Double(0.0));
    addComponent(cp, vField, 3, 4+MAXncomp+5, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    // total moles
    JLabel mLabel = new JLabel("total moles:");
           mLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    addComponent(cp, mLabel, 4, 4+MAXncomp+5, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    NumberFormat mFormat = NumberFormat.getNumberInstance();
                 mFormat.setMaximumFractionDigits(4);
		 mFormat.setMinimumFractionDigits(4);  
    mField = new JFormattedTextField(mFormat);
    mField.setColumns(8);
    mField.setBackground(c);
    mField.setForeground(Color.black);
    mField.setEditable(false);
    mField.setHorizontalAlignment(JTextField.RIGHT);
    mField.setValue(new Double(0.0));
    addComponent(cp, mField, 5, 4+MAXncomp+5, 1, 1, GridBagConstraints.NONE, GridBagConstraints.WEST);

    muTitle = new JLabel();
    muTitle.setText("mu [J/mol]:");
    muTitle.setVisible(true);
    addComponent(cp, muTitle,  7, 3, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);

    muField = new JFormattedTextField[MAXncomp];

    NumberFormat muFormat = NumberFormat.getNumberInstance();
                 muFormat.setMaximumFractionDigits(0);
		 muFormat.setMinimumFractionDigits(0);  

    for (int i=0; i<MAXncomp; i++) {
      muField[i] = new JFormattedTextField(muFormat);
      muField[i].setColumns(8);
      muField[i].setVisible(true);
      muField[i].setBackground(c);
      muField[i].setForeground(Color.black);
      muField[i].setHorizontalAlignment(JTextField.RIGHT);
      muField[i].setValue(new Double(0.0));
      muField[i].setEditable(false);
      addComponent(cp, muField[i], 7, 4+i, 1, 1, GridBagConstraints.NONE, GridBagConstraints.EAST);
    }
    cp.add(applet);
    
    phase1 = null;

    frame.setSize(900, 800);
    frame.setLocation(200, 100);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  }

  //*********************
  // Class public methods
  //*********************
  
  /**
   * Gets property from Applet manager or from the system.
   * @param key Property label.
   * @param def Property definition
   * @return Value of the specified property.
   */
  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) 
                        : (getParameter(key) != null ? getParameter(key) : def);
  }
  
  /**
   * Applet method.
   * @return null.
   */
  public String[][] getParameterInfo() {
    return null;
  }
  
  /**
   * Applet method.
   * @return String with brief description of the applet.
   */
  public String getAppletInfo() {
    return "CORBA Phase Properties Applet. v.3.0, August 2007";
  }
  
  /**
   * Applet method.
   */
  public void destroy() { if (phase1 != null) phase1.remove(); phase1 = null; }
  
  /**
   * Method to invoke an instance of the class as a standalone application.
   * @param args String array of command line arguments, which are passed to class initializer. .
   */
  public static void main(String[] args) {
    CalcClient applet = new CalcClient(args);
    applet.init();
  }
 
  /**
   * Method to layout a component in a container using GridBagConstraints.
   * @param container Instance of a container class.
   * @param component Instance of a component class to position in the container.
   * @param gx X-axis grid position.
   * @param gy Y-axis grid position.
   * @param gw Width of component in grid units.
   * @param gh Height of component in grid units.
   * @param fill Fill behavior for component.
   * @param anchor Anchor behavior for component.
   * @see java.awt.GridBagConstraints
   */
  public static void addComponent(Container container, Component component, 
    int gx, int gy, int gw, int gh, int fill, int anchor) {
    
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx      = gx;
    gbc.gridy      = gy;
    gbc.gridwidth  = gw;
    gbc.gridheight = gh;
    gbc.fill       = fill;
    gbc.anchor     = anchor;
    gbc.ipady      = 2;
    container.add(component, gbc);
  }

  //**********************
  // Class private methods
  //**********************
  
  // launches a help dialog box when the help button is pressed
  private class HelpHandler implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
      JFrame frame1 = new JFrame("Help");
      CalcHelp d = new CalcHelp(frame1, false);
      d.show();
      frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      Dimension dim = frame1.getSize();
      frame1.setSize(dim.width + 5, dim.height + 5);
    }
  }


  // listens for a selection in the "phase" popup menu
  ItemListener phaseChoiceHandler = new ItemListener() {
    public void itemStateChanged(ItemEvent e) {
      if (e.getStateChange() == ItemEvent.SELECTED) checkAndSetPhase();
    }
  };

  // listens for a selection in the "user action" popup menu
  private class actionHandler implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
      checkAndSetState();
    }
  }

  // a new phase has been selected from the popup
  /**
   * Method called when a new phase is selected from the popup menu.
   */
  public void checkAndSetPhase() {
    String phase = (phaseChoice.getSelectedItem()).toString();
    System.out.println("Call to checkAndSetPhase()");

    if ("No Phase".equals(phase)) {
      for (int i=0; i<MAXncomp; i++) {
        minLabel[0][i].setText(minBlank);
        minLabel[1][i].setText(minBlank);
        minEntry[i].setEditable(false);
        minEntry[i].setValue(new Double(0.0));
	 muField[i].setValue(new Double(0.0));
      }
      for (int j=0; j<MAXgncomp; j++) {
        bcLabel[j].setText(minBlank);
        bcEntry[j].setEditable(false);
        bcEntry[j].setValue(new Double(0.0));
      }
      gField.setValue(new Double(0.0));
      hField.setValue(new Double(0.0));
      sField.setValue(new Double(0.0));
      cpField.setValue(new Double(0.0));
      vField.setValue(new Double(0.0));
      mField.setValue(new Double(0.0));
    } else {
      for (int i=0; i<MAXncomp; i++) {
        minLabel[0][i].setText(minBlank);
        minLabel[1][i].setText(minBlank);
        minEntry[i].setEditable(false);
        minEntry[i].setValue(new Double(0.0));
	 muField[i].setValue(new Double(0.0));
      }
      for (int j=0; j<MAXgncomp; j++) {
        bcLabel[j].setText(minBlank);
        bcEntry[j].setEditable(false);
        bcEntry[j].setValue(new Double(0.0));
      }
      gField.setValue(new Double(0.0));
      hField.setValue(new Double(0.0));
      sField.setValue(new Double(0.0));
      cpField.setValue(new Double(0.0));
      vField.setValue(new Double(0.0));
      mField.setValue(new Double(0.0));

      // Get the phase object from the server
      if (phase1 != null) phase1.remove();
      String chn, ha, hn;
      try {
        chn = InetAddress.getLocalHost().getCanonicalHostName();
        ha  = InetAddress.getLocalHost().getHostAddress();
        hn  = InetAddress.getLocalHost().getHostName();
      } catch (UnknownHostException e) { 
        chn = "no host name"; 
	ha  = "no ip address";
	hn  = "no host name";
      }      
      ClientData cd = new ClientData(
        "Java", 
        System.getProperty("java.vendor"),
        System.getProperty("java.version"),
        System.getProperty("java.vendor"),
        System.getProperty("java.version"),
	"",
        System.getProperty("os.name"),
        System.getProperty("os.arch"),
        System.getProperty("os.version"),
        System.getProperty("user.name"),
        Locale.getDefault().getDisplayName(),
        TimeZone.getDefault().getDisplayName(),
        chn,
	ha,
        hn
      );
      phase1 = pFactory.spawnPhase(phase, cd);
        if (phase1 == null) JOptionPane.showMessageDialog(frame, "Lost server!  Try restarting the applet.");
      
      ncomp       = phase1.getNcomp();
      gncomp      = phase1.getGenericNcomp();
      compList    = phase1.getCompNames();
      compFormula = phase1.getCompFormulas();
      genCompList = phase1.getGenericCompFormulas();

      for (int i=0; i<ncomp; i++) {
        minLabel[0][i].setText(CalcClient.makeSubscript(compList[i]));
        minEntry[i].setEditable(true);
      }
      for (int k=0; k<ncomp; k++) minLabel[1][k].setText(CalcClient.makeSubscript(compFormula[k]));
      for (int j=0; j<gncomp; j++) {
        bcLabel[j].setText(CalcClient.makeSubscript(genCompList[j]));
        bcEntry[j].setEditable(true);
      }
    }
  }
 
  // The user has selected an action
  /**
   * Method called when a new action is selected from the popup menu.
   */
  public void checkAndSetState() {
    String request = (actionChoice.getSelectedItem()).toString();
    String phase   = (phaseChoice.getSelectedItem()).toString();

    if      ("Convert Wt% -> X".equals(request)) displayWTtoX();
    else if ("Convert X -> Wt%".equals(request)) displayXtoWT();
    else if ( "X ->Thermo Prop".equals(request)) displayXtoThermo();
  }

  /**
   * Method called when processing a convert Wt% to mole fraction request.
   */
  public void displayWTtoX() {
    double[] genCompSeq = new double[gncomp];

    for (int i=0; i<gncomp; i++) genCompSeq[i] = ((Number) bcEntry[i].getValue()).doubleValue();
    
    try {
      phase1.setGenericWts(genCompSeq);
    } catch(phases.dPhasePackage.PhaseError pe) {
      JOptionPane.showMessageDialog(frame, pe.description, "Wt% -> X server error",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }

    double[] compSeq = new double[ncomp];
    compSeq = phase1.getComps();
    
    double mTotal = 0.0;
    for (int i=0; i<ncomp; i++) mTotal += compSeq[i];
    
    for (int i=0; i<ncomp; i++) {
      if (mTotal == 0.0) minEntry[i].setValue(new Double(0.0));
      else               minEntry[i].setValue(new Double(compSeq[i]/mTotal));
    }

     gField.setValue(new Double(0.0));
     hField.setValue(new Double(0.0));
     sField.setValue(new Double(0.0));
    cpField.setValue(new Double(0.0));
     vField.setValue(new Double(0.0));
     mField.setValue(new Double(phase1.getMoles()));

    for (int i=0; i<MAXncomp; i++) {
       muField[i].setValue(new Double(0.0));
    }
  }

  /**
   * Method called when processing a convert mole fraction to Wt% request.
   */
  public void displayXtoWT() {
    double[] compSeq = new double[ncomp];
    for (int i=0; i<ncomp; i++) compSeq[i] = ((Number) minEntry[i].getValue()).doubleValue();
    
    try {
      phase1.setComps(compSeq);
    } catch(phases.dPhasePackage.PhaseError pe) {
      JOptionPane.showMessageDialog(frame, pe.description, "X -> Wt% server error",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }
    
    double[] genCompSeq = new double[gncomp];
    genCompSeq = phase1.getGenericWts();
    
    double wtotal = 0.0;
    for (int i=0; i<gncomp; i++) wtotal += genCompSeq[i];
    
    for (int i=0; i<gncomp; i++) {
      if (wtotal == 0.0) bcEntry[i].setValue(new Double(0.0));
      else		 bcEntry[i].setValue(new Double(100.0*genCompSeq[i]/wtotal));
    }
  }

  /**
   * Method called when processing a calculate thermodynamic properties request.
   */
  public void displayXtoThermo() {
    double[] compSeq = new double[ncomp];
    for (int i=0; i<ncomp; i++) compSeq[i] = ((Number) minEntry[i].getValue()).doubleValue();

    try {
      phase1.setComps(compSeq);
    } catch(phases.dPhasePackage.PhaseError pe) {
      JOptionPane.showMessageDialog(frame, pe.description, "Set generic components server error",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }

    double tk;
    try {
      tk = ((Number) tEntry.getValue()).doubleValue();
    } catch (NumberFormatException ne) {
      JOptionPane.showMessageDialog(frame, "Invalid temperature", "Number Exception",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }
    
    double pa;
    try {
      pa =  100000.0*((Number) pEntry.getValue()).doubleValue();
    } catch (NumberFormatException ne) {
      JOptionPane.showMessageDialog(frame, "Invalid pressure", "Number Exception",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }

    try {
      phase1.setTk(tk);
    } catch(phases.dPhasePackage.PhaseError pe) {
      JOptionPane.showMessageDialog(frame, pe.description, "Set temperature server error",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }
    
    try {
      phase1.setPa(pa);
    } catch(phases.dPhasePackage.PhaseError pe) {
      JOptionPane.showMessageDialog(frame, pe.description, "Set pressure server error",  
        JOptionPane.ERROR_MESSAGE);
      return;
    }
    
     gField.setValue(new Double(phase1.getG()));
     hField.setValue(new Double(phase1.getH()));
     sField.setValue(new Double(phase1.getS()));
    cpField.setValue(new Double(phase1.getCp()));
     vField.setValue(new Double(phase1.getV()*1000000.0));
     mField.setValue(new Double(phase1.getMoles()));

    double[] muValue = new double[ncomp];
    muValue = phase1.getMu();

    for (int i = 0; i < ncomp; i++) {
      muField[i].setValue(new Double(muValue[i]));
    }
  }

}
