package com.sun.solarisinstall.panels;

import com.sun.wizards.core.*;
import com.sun.wizards.awt.*;
import com.sun.install.products.*;
import com.sun.solarisinstall.*;
import com.sun.solarisinstall.core.*;
import java.awt.*;
import java.io.*;
import java.util.*;

/**
 * The SolarisClusterPanel allows the user to set and browse
 * a set of profile settings
 */
public class SolarisClusterPanel extends WizardLeaf
{
  /**
   * The panel that will display the cluster choices
   */
  private Panel listPanel = null;
  private ScrollPane scrollPane = null;
  
  private CheckboxGroup cbgroup;
  private Vector osCheckBoxList = null;
  private boolean okToLeavePanel = false;
  private DataCheckbox curOSCheckbox = null;
      private int selected = 0;
      private static String clusterString = null;


  /**
   * Creates a SolarisClusterPanel with no name.
   */
  public SolarisClusterPanel()
    {
    }


  /**
   * Creates a SolarisClusterPanel with the specified name,
   * and contains profile entries indexed by the specified key list.
   *
   * @param wizardState	The buildtime WizardState.
   * @param name		The name for this SolarisClusterPanel.
   */
  public SolarisClusterPanel(WizardState wizardState, String name)
    {
      super(wizardState, name);
    }

  /**
   * Creates a SolarisClusterPanel with the specified name, the specified
   * route and wizard manager.
   *
   * @param name	The name for this SolarisClusterPanel.
   * @param route	The route to the appropriate server side object.
   * @param wizardManager	The wizardManager responsible for this component.
   */
  public SolarisClusterPanel(String name, Route route, WizardTreeManager wizardManager)
    {
      super(name, route, wizardManager);
    }

  /**
   * This method creates the user interface.
   */
  public void createUI()
  {
    super.createUI();
    WizardTreeManager wizardManager = getTreeManager(); 

    setLayout(new BorderLayout());

    /*
     * Add the header.
     */
    String heading = MsgCat.getString("com.sun.solarisinstall.SolarisInstall",
                            SolarisInstallResources.MSG_HDR_SELECT_CLUSTER);
    add(new HeaderPanel(heading, null), "North");


    /*
     * Add the text.
     */
    Panel textPanel = new Panel(new VerticalLayout());
    Label textLabel = 
         new Label(clusterString = MsgCat.getString("com.sun.solarisinstall.SolarisInstall", 
         SolarisInstallResources.MSG_SELECT_SOFTWARE_GROUP));
    // if (wizardManager.hasGUI())
    // {
    //   textLabel.setFont(new Font(getFont().getName(),
        //Font.BOLD, getFont().getSize()));
    // }
    textPanel.add(textLabel, "0");

    scrollPane = new ScrollPane();
    textPanel.add(scrollPane, "30");
    if (getParent() != null)
    {
       scrollPane.setSize(100, (getParent().getSize().height) - 175);
    }

    add(textPanel, "Center");
  }

  public void beginDisplay()
  {
    if (listPanel != null)
      scrollPane.remove(listPanel);
    listPanel = null;
    super.beginDisplay();
    listPanel = new Panel(new ColumnLayout());

    WizardTreeManager wizardManager = getTreeManager();

    Route objectRoute = getRoute().getChildServerRoute("profileObject");

    // get os distribution list from product list
    cbgroup = new CheckboxGroup();

    Vector prodList =
         (Vector)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileUtilProductList", null, null);

    String cluster =
         (String)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileCluster", null, null);


    // Separate out os meta-clusters and sort
    Vector osList = new Vector();
    for (int i=0; i < prodList.size(); i++) {
      SolarisProduct prod = (SolarisProduct)prodList.elementAt(i);
      if (prod.file.startsWith("os.")) {
        osList.addElement(prod);
      }
    }
    //Sort.quickSort(osList, SORT_ORDER.DESCENDING);

    // (Bubble) Sort the OS list by suffix in descending order
    String istr, jstr;
    int isuffidx, jsuffidx;
    for (int i = 0; i < osList.size() - 1; i++) {
        for (int j = i + 1; j < osList.size(); j++) {
            istr = ((SolarisProduct)osList.elementAt(i)).file;
            isuffidx = istr.lastIndexOf('.');
            if (isuffidx == -1) isuffidx = 0;
 
            jstr = ((SolarisProduct)osList.elementAt(j)).file;
            jsuffidx = jstr.lastIndexOf('.');
            if (jsuffidx == -1) jsuffidx = 0;

            if(istr.substring(isuffidx).compareTo(jstr.substring(jsuffidx))<0) {
                Object tmp = osList.elementAt(i);
                osList.setElementAt(osList.elementAt(j), i);
                osList.setElementAt(tmp, j);
            }
        }
      }


    osCheckBoxList = new Vector();
    Enumeration e = osList.elements();
    String checkBoxLabel;
    boolean checkBoxState = false;
    DataCheckbox checkbox;
    while (e.hasMoreElements()) {
      SolarisProduct prod = (SolarisProduct)e.nextElement();
      if (prod.file.startsWith("os.")) {
        //Panel choicePanel = new Panel(new ColumnLayout());
        InsetsPanel choicePanel = new InsetsPanel();
        Insets insets = new Insets(0, 20, 0, 20);
        choicePanel.setInsets(insets);
        choicePanel.setLayout(new RowLayout(LAYOUT_ALIGNMENT.EXPAND));
        // Layout checkbox with cluster name as label, in cbgroup,
        // selected if cluster is set in profile and attach the cluster
        // name to this checkbox for future use
        checkBoxLabel = new String("  ");
        checkBoxLabel += prod.getName();
        checkBoxState = prod.cluster.equals(cluster);
        checkbox = new DataCheckbox(checkBoxLabel, cbgroup,
          checkBoxState,
          prod);
        osCheckBoxList.addElement(checkbox);
        choicePanel.add(checkbox);
        listPanel.add(choicePanel);
        if (checkBoxState == true) {
          curOSCheckbox = checkbox;
        }
      }
    }
    scrollPane.add(listPanel);
    selected = osCheckBoxList.indexOf(cbgroup.getSelectedCheckbox());
    
  }


public void consoleInteraction()
     {
       String labels[] = new String[ osCheckBoxList.size() ];
       selected = osCheckBoxList.indexOf(cbgroup.getSelectedCheckbox());
        
       for(int i = 0; i < labels.length; i++ ) {
         labels[i] = ((Checkbox)osCheckBoxList.elementAt(i)).getLabel();
       }
     
       clusterString = "";
 
       String descString = MsgCat.getString("com.sun.solarisinstall.SolarisInstall",
                               SolarisInstallResources.MSG_CLI_CLUSTER_DESC);
       String promptString = MsgCat.getString("com.sun.solarisinstall.SolarisInstall",
                               SolarisInstallResources.MSG_CLI_CLUSTER_PROMPT);
       
       selected = TTYDisplay.queryValue( promptString, descString, labels, selected,
                                         clusterString );
       cbgroup.setSelectedCheckbox(((Checkbox)osCheckBoxList.elementAt(selected)));
     }

  /**
   * Returns true if this SolarisClusterPanel is finished displaying.
   * This method can be used to verify user input.
   *
   * @return	true if the display of this SolarisClusterPanel is
   *		complete; false otherwise.
   */
  public boolean isDisplayComplete()
  {
    WizardTreeManager wizardManager = getTreeManager();

    Route objectRoute = getRoute().getChildServerRoute("profileObject");

    DependError errorInfo = null;
    okToLeavePanel = true;

    Vector allprodList =
         (Vector)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileUtilProductList", null, null);

    Vector selprodList =
         (Vector)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileUtilSelectedProdList", null, null);

    String oldCluster =
         (String)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileCluster", null, null);

    
    Boolean sixty4Bit = 
      (Boolean)wizardManager.callServerObjectMethod(getRoute(),
        "getData",
        new String[]{"com.sun.wizards.core.Route.class",
        "java.lang.String.class"},
        new Object[] {null, ProfileConstants.SixtyFourBit});
    if (sixty4Bit != null)
      wizardManager.callServerObjectMethod(objectRoute.copy(),
				"setProfile64Bit",
			new String[] {"java.lang.Boolean.class"},
			new Object[] {sixty4Bit});
      

    /*
     * do dependency checking
     */
    Depend depend = new Depend(selprodList, allprodList, oldCluster);
    DataCheckbox newOScb = (DataCheckbox)cbgroup.getSelectedCheckbox();
    SolarisProduct newOSProd = (SolarisProduct)newOScb.getData();   

    errorInfo = depend.updateOS(newOSProd.cluster);

    if (errorInfo.hasError()) {
      String dialogMessage = errorInfo.setDisplayMsg();

      String okString =
                MsgCat.getString("com.sun.solarisinstall.SolarisInstall",
                                  SolarisInstallResources.MSG_DEPEND_OK);
      wizardManager.displayQuery( this, dialogMessage,
                            new String[] { okString },
                            new String[] {"tryAgain"});
      
      /*
       * The okToLeavePanel flag will always be set to false right
       * now. The flag is here so that if there is ever a popup
       * where the user has the option to leave the panel, it can
       * be set to true in the query callback
       */
      if (!okToLeavePanel ) {
        cbgroup.setSelectedCheckbox(curOSCheckbox);
        return(false);
      }
    }


    /*
     * Get cluster of selected checkbox
     */
    DataCheckbox oscb = (DataCheckbox)cbgroup.getSelectedCheckbox();
    String newCluster = ((SolarisProduct)oscb.getData()).cluster;

    /*
     * Remove old cluster and add new one 
     */
    wizardManager.callServerObjectMethod(objectRoute.copy(),
          "setNewCluster",
          new String[] {"java.lang.String.class",
                        "java.lang.String.class" },
          new Object[] {oldCluster, newCluster});
    // Run the TestProfilePanel
    wizardManager.callServerObjectMethod(getRoute(),
			"setData",
                        new String[] {"com.sun.wizards.core.Route.class",
                                       "java.lang.String.class",
                                       "java.lang.Object.class"},
                        new Object[] {null,
                                       "noTest",
					Boolean.FALSE});

    return(true);
  }


  public void tryAgain()
  {
    okToLeavePanel = false;
    return;
  }


  /**
   * Reset this component, given the specified information.
   * This method may be called when a user backtracks in
   * the client wizard tree and changes a fundamental setting.
   * The panel that enabled the modification might traverse
   * subsequent panels and call this method resynchronize
   * all panels with the user's choice.
   *
   * When this method is called, the user selected "Default" installation.
   * This panel must reset its install directory information.
   *
   * @param Object	The information required to perform a reset.
   */
  public void reset(Object info)
  {
    WizardTreeManager wizardManager = getTreeManager();

    Route objectRoute = getRoute().getChildServerRoute("profileObject");

    String origcluster =
        (String)wizardManager.callServerObjectMethod(getRoute(),
        "getData",
        new String[]{"com.sun.wizards.core.Route.class",
        "java.lang.String.class"},
        new Object[] {null, "DefaultCluster"});

    String currentcluster =
         (String)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileCluster", null, null);

    Vector allprodList =
         (Vector)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileUtilProductList", null, null);

    Vector selprodList =
         (Vector)wizardManager.callServerObjectMethod(objectRoute.copy(),
         "getProfileUtilSelectedProdList", null, null);


    /*
     * do dependency checking
     * 
     * Theoretically, the ProductSelectionPanel should have
     * already done whatever needed to be done, and this
     * check/resulting action is redundant. However, I'm 
     * leaving it in because this panel shouldn't depend on 
     * the work of another panel (in case previous panel
     * goes away, panel order changes, etc.)
     */
    DependError errorInfo = null;

    Depend depend = new Depend(selprodList, allprodList, origcluster);
    errorInfo = depend.getDependError();

    if (errorInfo != null) {
     int depError = errorInfo.getErrorCode();
      if (depError == DependError.OS_NOT_VALID) {
        /*
         * The original cluster is insufficient for the default
         * product list. Bump up the cluster per Depend.
         */
        String newCluster = (String)errorInfo.getInfoVector().elementAt(0);
        if (Def.DEBUG) System.out.println("\nSolarisClusterPanel reset: "
                           + " Bump cluster to " + newCluster);
        /*
         * Set the origcluster to the one determined by Depend
         */
        origcluster = newCluster;
      }
    }

    wizardManager.callServerObjectMethod(objectRoute.copy(),
          "setNewCluster",
          new String[] {"java.lang.String.class",
                        "java.lang.String.class" },
          new Object[] {currentcluster, origcluster});

  }


  /**
   * Returns information suggesting which buttons should be
   * displayed for this panel.
   *
   * The SolarisClusterPanel displays all the navigation
   * buttons.
   *
   * @return	A button mask identifying valid navigation buttons.
   */
  public int getButtonMask()
    {
      return(BACK_BUTTON | NEXT_BUTTON | 
	EXIT_BUTTON );
    }

  /**
   * Get the runtime classes required by this panel.
   */
  public void addRuntimeResources(Vector resourceVector)
  {
    super.addRuntimeResources(resourceVector);
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.core.Depend"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.core.DependError"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SolarisWebStartError"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SolarisFSObj"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SolarisFileSystem"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.PFInstall"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.MyLocale"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.ProfileUtil"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.Profile"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.ProfileFile"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SolarisProduct"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SolarisClusterPanel"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.DataCheckbox"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.HeaderPanel"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.InsetsPanel"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.VerticalLayout"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.FlowLabel"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.Separator"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.ColumnLayout"});
    resourceVector.addElement(new String[] {null, "com.sun.wizards.awt.Header"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.SORT_ORDER"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.Sort"});
    resourceVector.addElement(new String[] {null, "com.sun.solarisinstall.panels.Sortable"});
  }
}

