package com.sun.launcher.panels;

import java.awt.*;
import java.util.*;
import com.sun.wizards.core.*;
import com.sun.wizards.awt.*;
import com.sun.wizards.nodes.*;
import com.sun.launcher.*;
import com.sun.launcher.panels.*;
import com.sun.launcher.core.*;


/*
 *  This panel actually launches the installer. Panel text
 *  merely tells user launching in in progress. Panel disappears
 *  after a timeout, hopefully leaving just-launched wizard on 
 *  the screen. A thread monitors the status of the process 
 *  corresponding to the wizard and when the process exits,
 *  the panel reappears (and quickly proceeds to the next panel).
 */
public class LaunchPanel extends ParentPanel implements Runnable
{
  private transient Panel mainPanel = null;
  private transient Panel textPanel = null;
  private transient FlowLabel CDprompt = null;
  private transient Thread waitThread = null;
  private boolean noExitSkipButtons = false;
  private String CDtext = null;

  public LaunchPanel()
  {
  }

  public LaunchPanel(WizardState wizardState, String name)
  {
    super(wizardState, name);
  }
    
  public LaunchPanel(String name, Route route, WizardTreeManager wizardManager) 
  {
    super(name, route, wizardManager);
  }


  /**
   * This method creates the user interface.
   */
  public void createUI()
  {
    super.createUI();
    setLayout(new BorderLayout());

    /*
     * Add the header.
     */
    String heading = MsgCat.getString("com.sun.launcher.Launcher", 
                                       LauncherResources.MSG_HDR_LAUNCHING);
    add(new HeaderPanel(heading, null, 38), "North");

    add(mainPanel = new Panel(new BorderLayout()));

    textPanel = new Panel(new BorderLayout(0,0));
    mainPanel.add(textPanel, "Center");
  }

      public void consoleInteraction()
      {
	 super.consoleInteraction();
	 TTYDisplay.showNewline();
	 TTYDisplay.showText(CDtext);
	 TTYDisplay.showNewline();
      }

  public void beginDisplay()
  {
    super.beginDisplay();

    if (CDprompt != null) textPanel.remove(CDprompt);

    WizardTreeManager wizardManager = getTreeManager();

    String noExSkButtons =
           (String)wizardManager.callServerObjectMethod(getRoute(),
            "getData",
            new String[] {"java.lang.String.class"},
            new Object[] {LaunchConstants.NoExitSkipButtons});

    if ((noExSkButtons != null) && ( noExSkButtons.equals("YES"))){
      noExitSkipButtons = true;
    } else {
      noExitSkipButtons = false;
    }

    String CDName=
           (String)wizardManager.callServerObjectMethod(
            getRoute(),
            "getData",
            new String[] {"java.lang.String.class"},
            new Object[] {LaunchConstants.CDName});
    /*
     * If there is no CD name, just say "launching"
     */
    String logtext = null;

    if (CDName == null){
      CDtext = MsgCat.getString("com.sun.launcher.Launcher",
                LauncherResources.MSG_LAUNCHING); 
      logtext = MsgCat.getString("com.sun.launcher.Launcher",
                LauncherResources.MSG_LOG_LAUNCHING); 
    } else {
      Object[] CDnameArg = { CDName };
      CDtext =  MsgCat.getString("com.sun.launcher.Launcher",
                LauncherResources.MSG_LAUNCHING_FOR, CDnameArg); 
      logtext = MsgCat.getString("com.sun.launcher.Launcher",
                LauncherResources.MSG_LOG_LAUNCHING_FOR, CDnameArg); 
    }

    CDprompt = new FlowLabel(CDtext);
    textPanel.add(CDprompt, "Center");

    callWriteToLog(logtext);


    //System.out.println("myroute = " + getRoute(null));

    /* 
     * Call a sequence that:
     *  1) launches the installer and 
     *  2) sets a timer 
     *
     *  When the timer expires:
     *  1) make this panel disappear
     *  2) start a thread to monitor the progress of the 
     *     installer process and continue to next panel
     *     when the installer exits
     */
    wizardManager.callServerObjectMethod(
        getRoute(),
        "performSequence",
        new String[] {"com.sun.wizards.core.Route.class",
                      "java.lang.String.class",
                      "java.lang.Boolean.TYPE",
                      "java.lang.String.class"},
        new Object[] {getRoute(null),
                      "launchInstallSequence",
                      new Boolean(false),
                      "hidePanel"});
   }


   public int getButtonMask()
   {
     if (noExitSkipButtons) {
       return(0);
     } else {
       //return(EXIT_BUTTON);
       return(0);
     }
   }
    

  /**
   * We need to include setProgress so performSequence finds the 
   * callback method properly.  
   */
  public void setProgress(int [] myarray) 
  {
  }


  /**
   * Hide the panel and start a thread to wait for the 
   * installer to exit
   */
  public void hidePanel()
  {
    WizardTreeManager wizardManager = getTreeManager();

    Boolean nullProcess =
           (Boolean)wizardManager.callServerObjectMethod(getRoute(),
            "getData",
            new String[] {"java.lang.String.class"},
            new Object[] {LaunchConstants.nullProcess});

    /* 
     * If we have a null process, call handleLaunchErr to give 
     * user option to try again or continue to next cd.
     */
    if (nullProcess.booleanValue()) {
      if (Def.DEBUG)System.out.println("\nLaunchPanel: hidePanel NULL PROCESS");
      handleLaunchErr();
      return;
    }

    if (Def.DEBUG) System.out.println("LaunchPanel: Hiding panel");

    Frame myFrame = getFrame();
    if (myFrame == null) {
       if (Def.DEBUG) System.out.println("Error: LaunchPanel can't get frame.");
    } else {
      myFrame.setVisible(false); // makes it invisible
    }

    /* 
     * Start a thread that waits for exit 
     * of installer, makes panel visible again, and then 
     * goes on to next iteration
     */
     if (waitThread != null) {
       waitThread.stop();
       waitThread = null;
     }
     waitThread = new Thread(this);
     waitThread.start();

  }

  /**
   * The run method is used to wait for the installer to complete
   * before making the panel visible again.
   */
  public void run()
  {
    WizardTreeManager wizardManager = getTreeManager();

    wizardManager.callServerObjectMethod(
        getRoute(),
        "performSequence",
        new String[] {"com.sun.wizards.core.Route.class",
                      "java.lang.String.class",
                      "java.lang.Boolean.TYPE",
                      "java.lang.String.class"},
        new Object[] {getRoute(null),
                      "waitForSequence",
                      new Boolean(true),
                      null});

    Frame myFrame = getFrame();
    if (myFrame == null) {
       if (Def.DEBUG) System.out.println("Error: LaunchPanel can't get frame.");
    } else {
      myFrame.setVisible(true); // makes it visible
    }

    String logMessage = MsgCat.getString("com.sun.launcher.Launcher",
                   LauncherResources.MSG_LOG_INSTALLER_COMPLETE);
    callWriteToLog(logMessage);

    /*
     *  on to the next panel
     */
    if (wizardManager.hasGUI())
    {
       wizardManager.nextButtonPressed();
    }
    waitThread = null;

  }


  /*
   * Couldn't launch. Eject the cd if necessary, popup a dialog 
   * box, do logging.
   */
  private void handleLaunchErr()
  {
    /*
     * For some reason (likely a bad path to the installer or a
     * cd that has a VOLID that isn't included in the cd.info 
     * file), we got a null process and can't launch. 
     */

    String dialogMessage = null;
    String logMessage = null;

    dialogMessage = MsgCat.getString("com.sun.launcher.Launcher",
                   LauncherResources.MSG_UNABLE_TO_LAUNCH);
    logMessage = MsgCat.getString("com.sun.launcher.Launcher",
                   LauncherResources.MSG_LOG_LAUNCH_FAILED);

    callWriteToLog(logMessage);

    WizardTreeManager wizardManager = getTreeManager();

    Boolean CDmountOK =
           (Boolean)wizardManager.callServerObjectMethod(
            getRoute(),
            "getData",
            new String[] {"java.lang.String.class"},
            new Object[] {LaunchConstants.CDmountOK});

    /*
     * If we have a CD mounted, eject it.
     */
    if ((CDmountOK != null) && (CDmountOK.booleanValue())) {
      Route launchRoute = getRoute().getChildServerRoute("launchObject");
      wizardManager.callServerObjectMethod(
                         launchRoute.copy(),
                         "EjectCD",
                         null, null);

      wizardManager.callServerObjectMethod(
                     getRoute(),
                     "setData",
                     new String[] {"java.lang.String.class",
                                   "java.lang.Object.class"},
                     new Object[] {LaunchConstants.CDmountOK,
                                    Boolean.FALSE});
    }

    /*
     * Pop up a dialog box
     */
    wizardManager.displayQuery( this, dialogMessage,
          new String[] {MsgCat.getString("com.sun.launcher.Launcher",
                                          LauncherResources.MSG_TRY_AGAIN),
                       MsgCat.getString("com.sun.launcher.Launcher",
                                          LauncherResources.MSG_PROCEED_NEXT)},
          new String[] {"tryAgain",
                       "localNextIteration"});

  }


  /*
   * User wants to try again. Restart the iteration at the beginning.
   */
  public void tryAgain()
  {
    redoIteration();
  }


  /*
   * User wants to proceed to next cd. 
   */
  public void localNextIteration()
  {
    nextIteration();
  }

   public void addRuntimeResources(Vector resourceVector)
   {
     super.addRuntimeResources(resourceVector);
     resourceVector.addElement(new String[] {null, "com.sun.launcher.panels.LaunchPanel"});
   }
}
