/* TimerAgent class

   Constructing Intelligent Agents with Java
   (C) Joseph P. Bigus and Jennifer Bigus 1997

   This agent can fire events on specified intervals
   or at a single specified date and time.

*/
// package sunw.demo.ciagent ;
 import java.awt.* ;
 import java.io.* ;
 import java.util.*;

 public class TimerAgent extends CIAgent {

  public final int ALERT = 0;    // display a dialog
  public final int EXECUTE = 1;  // start a process
  public final int EVENT = 2;    // send an event to another agent

  int action = EVENT ;   // default action is to send an event
  String parms ;
  int interval ;  // for interval timers
  Date time ;     // for one shot timers
  Dialog actionDialog ;


  public TimerAgent() { name = "Timer"; }
  public TimerAgent(String Name) { super(Name); } ;

 // return a string for display in a list box
 public String getDisplayString() {
    String out = new String() ;
    out = name + " int=" + (interval/1000) +
          " date=" + time + " action=" + action + "parms=" + parms ;
    return out ;
 }

 public void setInterval(int secs) {
        interval = secs * 1000 ;
 }
 public int getInterval() { return interval ; }

 public void setTime(Date t) { time = t ; }
 public Date getTime() { return time ; }

 public void setAction(int act) { action = act; }
 public int getAction() { return action ; }

 public void setParms(String params) { parms = params; }
 public String getParms() { return parms ; }

 public void setDialog(Dialog dlg) { actionDialog= dlg ; }



 public void process() {
    stopped = false ;
    // start a thread running and send an update message every interval secs
    trace("Starting " + name + "\n") ;
    runnit = new Thread(this) ;
    runnit.start() ;
 }

 public void stop() {
    stopped = true;
    trace(name + " stopped \n") ;
    runnit.stop() ;
}

 // method of Runnable (Thread) interface
 public void run() {
    if (interval > 0) {
      while(stopped == false){     // interval timer
        try {
           Thread.sleep((long)interval) ;  // in milliseconds
           trace(name + ": Interval sleep over ") ;
        }
        catch (InterruptedException e)
        {
          // interrupted
        }
            performAction() ;
      }
    } else {                      // one-shot alarm
       try {
           Date date = new Date() ; // get current date/time
           int curDay = date.getDay() ;
           int curHour = date.getHours() ;
           int alarmHour = time.getHours() ;
           int deltaHour = ((alarmHour - curHour) % 24) * 60 ; // in minutes
           int curMin = date.getMinutes() ;
           int alarmMin = time.getMinutes() ;
           long deltaMin = (alarmMin - curMin) % 60 ;
           long delta = (deltaHour + deltaMin) * 60 * 1000 ;
           System.out.println("going to sleep for " + delta + " msecs") ;
           Thread.sleep(delta) ;  // in milliseconds
           date = new Date() ; // get current date/time
           trace(name + ":Alarm sleep over at " + date) ;
           notifyCIAgentEventListeners(new CIAgentEvent(this, "alarm"));   // signal interested observer
        }
        catch (InterruptedException e)
        {
          // interrupted
        }
             performAction() ;
    }

 }

  public  void ciaEventFired(CIAgentEvent e) {
      trace(name + ":  CIAgentEvent received by " + name +
           " from " + e.getSource() + " with arg " + e.getArgObject()) ;
  }

  // perform the action specified by the user
  void performAction() {
   switch (action) {
            case 0:
                 trace(name + ": Alert fired \n") ;
                 ((AlertDialog)actionDialog).label1.setText(parms) ;
                 actionDialog.show() ;
                 if (((AlertDialog)actionDialog).cancel == true) stop() ;
                 break ;
            case 1:
                 trace(name + ": Executing command \n") ;
                 executeCmd(parms) ;
                 break ;
            case 2:
                 notifyCIAgentEventListeners(new CIAgentEvent(this,"interval"));   // signal interested observer
                 break ;
          }
  }

public  int executeCmd(String cmd) {
     Process process ;
     String line ;
     textArea = ((ExecuteDialog)actionDialog).textArea1 ;
     actionDialog.show() ;
     try {
         // this prefix works for Win 95/NT only ???
         trace(cmd) ; // echo command and parameters
         process = Runtime.getRuntime().exec("command.com /c " + cmd + "\n");
         DataInputStream data = new DataInputStream(process.getInputStream());
         while ((line = data.readLine()) != null)
         {
             trace(line);
         }
         data.close();

     } catch (IOException err) {
         trace("Error: EXEC failed, " + err.toString()) ;
         err.printStackTrace();
        return -1 ;
     }
      if (((ExecuteDialog)actionDialog).cancel == true) stop() ;
      return process.exitValue() ;
 }




};

