import rock.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.net.URL;

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

/**
 * Creates a popup dialog box to allow selection of phases that are allowed to form in the system.
 * @version 1.0 (August 2007)
 * @author Mark S. Ghiorso, OFM-Research Inc.
 */
public class PhaseHandler implements ActionListener{
  private JFrame frame;
  private rock.dRock rockRef;
  private JCheckBox phaseList[];
  private int np;
  private boolean phaseState[];
  
  /**
   * Creates the GUI and initializes the class.
   * @param rockRef Instance of server-side rock object.
   */
  public PhaseHandler(rock.dRock rockRef) {
    this.rockRef = rockRef;
    Border etchedBdr2 = BorderFactory.createEtchedBorder();
	  
    frame = new JFrame("Solid Phases");
    frame.addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowClosing(java.awt.event.WindowEvent e) {
          Frame f = (Frame) e.getSource();
    	  f.setVisible(false);
        }
      });
    Container cp2 = frame.getContentPane();

    GridBagLayout gbl2 = new GridBagLayout(); cp2.setLayout(gbl2);
    
    JPanel pPanel1 = new JPanel();
	   pPanel1.add(new JLabel("Checked phases will be allowed to precipitate from the liquid."));
	   pPanel1.setBorder(etchedBdr2);
    addComponent(cp2, pPanel1, 0, 0, 1, 1, GridBagConstraints.BOTH);
    
    JPanel pPanel2 = new JPanel();
           pPanel2.setLayout(new GridLayout(0,5));
	   pPanel2.setBorder(etchedBdr2);
    
    try {
      String name[];
      if (rockRef == null) {
        np = 15;
	name = new String[15];
	for (int i=0; i<np; i++) name[i] = "name" + i+1;
      } else {
        np = (int) rockRef.getNSolPhases();
	name = new String[np];
	for (int i=0; i<np; i++) name[i] = rockRef.getSolPhaseName( (short) i);;
      }
      PhaseInclusionHandler handler = new PhaseInclusionHandler();
      
      phaseList = new JCheckBox[np];
      phaseState = new boolean[np];
      for (int i=0; i<np; i++) {
        phaseList[i] = new JCheckBox(name[i]);
	phaseList[i].setSelected(true);
	phaseList[i].addItemListener(handler);
	pPanel2.add(phaseList[i]);
	if (rockRef != null) rockRef.enablePhase((short) i);
	phaseState[i] = true;
      }
    } catch (org.omg.CORBA.COMM_FAILURE     noServer) {
      JOptionPane.showMessageDialog(null, 
    	"Lost contact with server. Server is most likely down.\nPlease wait a few minutes and reload applet or restart application.",
    	"CORBA Server Error", JOptionPane.ERROR_MESSAGE);
    } catch (org.omg.CORBA.OBJECT_NOT_EXIST noObject) {
      JOptionPane.showMessageDialog(null, 
    	"Lost contact with server. Server has deleted your process.\nPlease reload applet or restart application.",
    	"CORBA Server Error", JOptionPane.ERROR_MESSAGE);
    }

    
    addComponent(cp2, pPanel2, 0, 1, 1, 1, GridBagConstraints.BOTH);
    
    JPanel pPanel3 = new JPanel();
	   pPanel3.setBorder(etchedBdr2);
           
    JButton pb1 = new JButton("Done");
	    pb1.addActionListener(new DoneHandler());
    pPanel3.add(pb1);
            
    JButton pb2 = new JButton("Std Set");
	    pb2.addActionListener(new StdSetHandler());
    pPanel3.add(pb2);
            
    JButton pb3 = new JButton("No Solid Solns");
	    pb3.addActionListener(new NoSolutionsHandler());
    pPanel3.add(pb3);
            
    JButton pb4 = new JButton("All Solids");
	    pb4.addActionListener(new AllSolidsHandler());
    pPanel3.add(pb4);
    
    addComponent(cp2, pPanel3, 0, 2, 1, 1, GridBagConstraints.BOTH);
    
    frame.pack();
    frame.setLocation(100, 100);
  }

  /**
   * Displays the popup dialog box.
   * @param e Action event that triggered the display request.
   */
  public void actionPerformed(ActionEvent e) {
    frame.setVisible(true);
  }
    
  /**
   * Includes a phase in the system.  By default all phases are included when the Melts class is instantiated.
   * This method is provided for setting the inclusion of a phase as specified in an input file. The method
   * emulates a user selection in the dialog box GUI. 
   * @param i Index number of phase to be included.
   */
  public void  enablePhase(short i) { 
    if(!phaseState[i]) phaseList[i].doClick();  
    return;
  }

  /**
   * Removes a phase from the system.  By default all phases are included when the Melts class is instantiated.
   * This method is provided for setting the exclusion of a phase as specified in an input file. The method
   * emulates a user selection in the dialog box GUI. 
   * @param i Index number of phase to be excluded.
   */
  public void disablePhase(short i) { 
    if(phaseState[i]) phaseList[i].doClick();; 
    return; 
  }  
  
  /**
   * Retrieves the inclusion state of a phase. 
   * @param i Index number of phase to be queried.
   * @return True if phase is included in the system; false if phase is excluded.
   */
  public boolean getPhaseState(short i) { 
    return phaseState[i]; 
  }  
  
  /**
   * 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.
   * @see java.awt.GridBagConstraints
   */
  public static void addComponent(Container container, Component component, int gx, int gy, int gw, int gh, int fill){
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx      = gx;
    gbc.gridy      = gy;
    gbc.gridwidth  = gw;
    gbc.gridheight = gh;
    gbc.fill       = fill;
    container.add(component, gbc);
  }
  
  private class PhaseInclusionHandler implements ItemListener {
    public void itemStateChanged(ItemEvent e) {
      JCheckBox source = (JCheckBox) e.getItemSelectable();
      try {
        for (int i=0; i<np; i++) if (source == phaseList[i]) {
          if (e.getStateChange() == ItemEvent.SELECTED) {
	    if (rockRef != null) { phaseState[i] = true;  rockRef.enablePhase((short) i);  }
	  } else {
	    if (rockRef != null) { phaseState[i] = false; rockRef.supressPhase((short) i); }
	  }
	  return;
        }
      } catch (org.omg.CORBA.COMM_FAILURE     noServer) {
        JOptionPane.showMessageDialog(null, 
          "Lost contact with server. Server is most likely down.\nPlease wait a few minutes and reload applet or restart application.",
          "CORBA Server Error", JOptionPane.ERROR_MESSAGE);
      } catch (org.omg.CORBA.OBJECT_NOT_EXIST noObject) {
        JOptionPane.showMessageDialog(null, 
          "Lost contact with server. Server has deleted your process.\nPlease reload applet or restart application.",
          "CORBA Server Error", JOptionPane.ERROR_MESSAGE);
      }
    }
  }

  private class DoneHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
      frame.setVisible(false);
    }
  }
  
  private class StdSetHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
      System.out.println("Entering the Std Set Button ActionListener.");
      JOptionPane.showMessageDialog(frame, "Option not yet implemented.");
      // TODO - Implementation
      
    }
  }
  
  private class NoSolutionsHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
      if (rockRef == null) return;
      try {
        for (int i=0; i<np; i++) {
          if (rockRef.getNSolComp((short) i) == 1) { phaseList[i].setSelected(true);  phaseState[i] = true;  }
	  else                                     { phaseList[i].setSelected(false); phaseState[i] = false; }
        }
      } catch (org.omg.CORBA.COMM_FAILURE     noServer) {
        JOptionPane.showMessageDialog(null, 
          "Lost contact with server. Server is most likely down.\nPlease wait a few minutes and reload applet or restart application.",
          "CORBA Server Error", JOptionPane.ERROR_MESSAGE);
      } catch (org.omg.CORBA.OBJECT_NOT_EXIST noObject) {
        JOptionPane.showMessageDialog(null, 
          "Lost contact with server. Server has deleted your process.\nPlease reload applet or restart application.",
          "CORBA Server Error", JOptionPane.ERROR_MESSAGE);
      }
    }
  }
  
  private class AllSolidsHandler implements ActionListener{
    public void actionPerformed(ActionEvent e){
      if (rockRef == null) return;
      for (int i=0; i<np; i++) { phaseList[i].setSelected(true); phaseState[i] = true; }
    }
  }
  
}
