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

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

/**
 * Handles updates to the table of phases present in the equilibrium assemblage.  Controls entries of the phase popup menu,
 * which in turn determines phases available for peroperties display.
 * @version 1.0 (August 2007)
 * @author Mark S. Ghiorso, OFM-Research Inc.
 */
public class UpdatePhaseTable {

private rock.dRock rockRef;
private PhaseTableModel pTableModel;
private JComboBox phasePopupMenu;

  /**
   * Creates the GUI and initializes the class.
   * @param rockRef Instance of server-side rock object.
   * @param pTableModel Instance of a PhaseTableModel class to populate and control. Must exist prior to instantiating this class.
   * @param phasePopupMenu Instance of a JComboBox class to populate and control. Must exist prior to instantiating this class.
   */
  public UpdatePhaseTable(rock.dRock rockRef, PhaseTableModel pTableModel, JComboBox phasePopupMenu) {
    this.rockRef        = rockRef;
    this.pTableModel    = pTableModel;
    this.phasePopupMenu = phasePopupMenu;
  }

  // rows = number of solid phases + (liquids)  maximum is 100!
  // cols = 4 + 2 x (components) maximum is 24
  //  "phase", "grams", "affinity", "formula", 
  //  "component", "mol frac", "component", "mol frac", "component", "mol frac", 
  //  "component", "mol frac", "component", "mol frac" };
  
  /**
   * Updates the phase table and the phase popup menu.
   */
  public void update() {
    try {
      if (rockRef != null && pTableModel != null) {
        int np = (int) rockRef.getNSolPhases();
        int ns = (int) rockRef.getNSatSolid();
        short list[] = rockRef.getSatSolidList();
        
        phasePopupMenu.removeAllItems();
        phasePopupMenu.addItem("none");
        
        double liqMass = rockRef.getLiquidMass();
        if (liqMass != 0.0) {
          phasePopupMenu.addItem("liquid");
          pTableModel.setValueAt("liquid",					 0,   0);
          pTableModel.setValueAt(new Double(liqMass),				 0,   1);
          pTableModel.setValueAt(new Double(0.0),				 0,   2);
        }
        
        for (int i=0, k=0; i<ns; i++) {
          String name = rockRef.getSolPhaseName(list[i]);
    	  short  ni   = rockRef.getNumberCoexistPhase(list[i]);

    	  for (short pInstance=0; pInstance<ni; pInstance++, k++) {
    	    if (ni == 1) {
    	      phasePopupMenu.addItem(name);
              pTableModel.setValueAt(name,						    k+1, 0);
    	    } else {
    	      phasePopupMenu.addItem(name + ":" + pInstance);
              pTableModel.setValueAt(name + ":" + pInstance,				    k+1, 0);
    	    }
            pTableModel.setValueAt(new Double(rockRef.getSolPhaseMass(list[i], pInstance)), k+1, 1);
            pTableModel.setValueAt(new Double(0.0),					    k+1, 2);
            pTableModel.setValueAt(rockRef.getSolPhaseFormula(list[i], pInstance),	    k+1, 3);
    	    int na = (int) rockRef.getNSolComp(list[i]);
    	    if (na > 1) {
    	      double x[] = new double[na];
    	      DoubleSeqHolder xDS = new DoubleSeqHolder(x);
    	      System.out.println("getSolComp call returns " + rockRef.getSolComp(list[i], pInstance, xDS));
    	      for (int j=0; j<na; j++) {
    	  	pTableModel.setValueAt(rockRef.getSolPhaseCompName(list[i], (short) j), k+1, 4+2*j);
    	  	pTableModel.setValueAt(new Double(xDS.value[j]),			k+1, 5+2*j);
    	      }
    	    }
    	  }

        }
        
haveSolid:
        for (int i=0, row=ns+1; i<np; i++) {
          for (int j=0; j<ns; j++) if (i == (int) list[j]) continue haveSolid;
    	  int na = (int) rockRef.getNSolComp((short) i);
    	  double x[] = new double[na];
    	  DoubleSeqHolder xDS = new DoubleSeqHolder(x);
    	  double affinity = rockRef.getAffinity((short) i, xDS);

          pTableModel.setValueAt(rockRef.getSolPhaseName((short) i),			row, 0);
          pTableModel.setValueAt(new Double(0.0),					row, 1);
          pTableModel.setValueAt(new Double(affinity/1000.0),				row, 2);
          pTableModel.setValueAt(rockRef.getSolPhaseFormula((short) i, (short) 0),	row, 3);

    	  if (na > 1) {
    	    for (int j=0; j<na; j++) {
    	      pTableModel.setValueAt(rockRef.getSolPhaseCompName((short) i, (short) j), row, 4+2*j);
    	      pTableModel.setValueAt(new Double(xDS.value[j]),  			row, 5+2*j);
    	    }
    	  }

    	  row++;

        }

      }
    } 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);
    }
  }
  
}
  
