//     $Id: DemonEngine.java,v 3.8 1998/12/09 14:38:37 rgb2u Exp $    
 /////////////////////////////////////////////////////////////////////
 //
 // File: DemonEngine.java
 //
 // Purpose: This describes the Demon Engine class.  The Demon Engine is
 //          responsible for interfacing between the Demon RMI module
 //          and the Demon GUI module.  It contains the logic that 
 //          "runs" the demon side of the simulation.
 //
 // Authors: rgb  Rob Bartholet  rgb2u@virginia.edu
 // 
 // Modifications:
 //
 //   12-NOV-1998  rgb Initial Creation
 //   16-NOV-1998  smg Added automatic version header
 //   16-NOV-1998  rgb Added code to throw exceptions
 //   17-NOV-1998  rgb Fixed some compilation errors in signatures
 //   18-NOV-1998  rgb Minor changes to catch exception thrown by DemonGUI
 //   18-NOV-1998  rgb Cleaned up code
 //   20-NOV-1998  rgb Uncommented call to DemonRMI.Shutdown()
 //   01-DEC-1998  rgb Added AbortClicked()
 //                rgb Added mode parameter to SetParameters
 //   02-DEC-1998  rgb fixed minor error
 //                rgb Added SubmitMode()
 //                rgb Removed mode param to SetParameters
 //   03-DEC-1998  rgb Changed demon_rmi.SetParameters to demon_rmi.StartRun
 //                rgb Got rid of freeze and unfreeze, and now use gui.SetState
 //                rgb Added Quit()
 //                rgb Added constants to define state of gui
 //   08-DEC-1998  rgb Added constructor to take string and port
 //                rgb Added ReceiveMap wrapper around rmi.Connect
 //                rgb Removed SetState from new constructor
 //   09-DEC-1998  rgb Added ReceiveState ()
 //                rgb Removed all references to setting state from here
 //                rgb Removed old unused constructor
 //
 // Todo:
 //        encode SetState arguments as constants somewhere
 //
 /////////////////////////////////////////////////////////////////////
 import java.rmi.*;
 public class DemonEngine {
   private DemonGUI demon_gui;      // used to call back ClientGUI
   private DemonRMI demon_rmi;      // used to communicate with server
   // constructor
   // DemonEngine instantiated by DemonGui
   // DemonEngine instantiates DemonRMI     
   public DemonEngine (DemonGUI gui, String address, String port) throws Exception {
     if (gui == null) {
       throw new NullException ("gui argument is null");
     }
     else {
       demon_gui = gui;
       demon_rmi = new DemonRMI (this);
       ReceiveMap (demon_rmi.Connect (address, port) );
       demon_rmi.RegisterWithServer ();
     }
   }
   // demon sets propagation mechanism and cycle delay time
   // returns true if set successfully; else returns false
   public boolean SetParameters (int propagation, long delay) throws Exception {
     if (demon_rmi.StartRun (propagation, delay) ) {
       return true;
     }
     else {
       PrintMessage ("Failure submitting parameters\nEnsure your values are valid\nTry again");
       return false;
     }
   }
   // demon submits the mode, auto mode is 0, manual mode is 1
   // returns true if mode set successfully; else returns false
   public boolean SubmitMode (int mode, int runs) throws Exception {
     if (mode < 0 || mode > 1) {
       throw new BoundsException ("Invalid mode selected");
     }
     else if (mode == 1 && runs <= 0) {
       throw new BoundsException ("Invalid number of runs selected");
     }
     else {
       if (demon_rmi.SubmitMode (mode, runs) ) {
     return true;
       }
       else {
     PrintMessage ("Failure submitting mode\nTry again");
     return false;
       }
     }
   }
   // receive stats from server and send to gui
   public void ReceiveStats (Stats my_stats) throws Exception {
     if (my_stats == null) {
       throw new NullException ("Stats argument is null");
     }
     else {
       demon_gui.DisplayStats (my_stats);
     }
   }
   // receive map from server and send to gui
   public void ReceiveMap (Map my_map) throws Exception {
     if (my_map == null) {
       throw new NullException ("map argument is null");
     }
     else {
       demon_gui.DisplayMap (my_map);
     }
   }
   // receive state from rmi and pass to GUI
   public void ReceiveState (int state) throws Exception {
     demon_gui.ReceiveState (state);
   }
   // rmi sends client connection status to demon
   // calls gui to display current status
   public void ReceiveClientConnectStatus (ClientConnectStatus status) throws Exception {
     if (status == null) {
       throw new NullException ("ClientConnectStatus argument is null");
     }
     else {
       demon_gui.DisplayClientConnectStatus (status);
     }
   }
   // demon wants to shut down system
   public void QuitClicked () throws Exception {
     PrintMessage ("Shutting down the system...");
     demon_rmi.ShutDown ();
   }
   // demon wants to abort the current simulation
   public void AbortClicked () throws Exception {
     PrintMessage ("Aborting the current simulation...");
     demon_rmi.Abort ();
   }
   // RMI wants to print a message to the GUI output
   // receive string from RMI, pass on to GUI
   public void PrintMessage (String s) {
     demon_gui.Notify (s);
   }
   // Method for RMI to pass exceptions to GUI for display
   public void Error (Exception e) {
     demon_gui.Error (e);
   }
   // method for gui to call when applet is destroyed
   public void Quit () throws Exception {
     demon_rmi.Quit ();
   }
 }