/* FileAgent class

   Constructing Intelligent Agents with Java
   (C) Joseph P. Bigus and Jennifer Bigus 1997

   This agent monitors specific files for any changes
   and also answers queries regarding file attributes

*/
 //package sunw.demo.ciagent ;
 import java.io.* ;
 import java.awt.* ;
 import java.util.*;


public class FileAgent extends CIAgent {

   // conditions to check for
   public final int MODIFIED = 0 ;
   public final int DELETED = 1 ;
   public final int THRESHOLD = 2 ;

   // actions to take when conditions are true
   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


   public FileAgent() { name = "Watch" ; };
   public FileAgent (String Name) { super(Name) ;}


   String fileName ;
   File   file ;
   long   lastChanged ;
   int    condition ;
   int    threshold ;
   Dialog actionDialog ;
   String parms ;

 // return a string for display in a list box
 public String getDisplayString() {
    String out = new String() ;
    out = name + " fileName=" + fileName + "cond=" + condition ;
    return out ;
 }


   public void setFileName(String fName) { fileName = fName;
                                           file = new File(fName) ;
                                           lastChanged = file.lastModified() ; }

   public String getFileName() { return fileName; }

   public boolean exists() { return file.exists() ; }
   public boolean changed() { long changeTime = lastChanged ;
                              lastChanged = file.lastModified() ;
                              return !(lastChanged == changeTime) ;
   }
   public long length() { return file.length(); }  // file size
   public boolean isDirectory() { return file.isDirectory(); }
   public long lastModified() { return file.lastModified(); }



   public void setCondition(int cond) { condition = cond; }
   public int getCondition() { return condition ; }

   public void setThreshold(int thresh) { threshold = thresh; }
   public int getThreshold() { return threshold; }

   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 stop() {
    stopped = true;
    trace(name + " stopped \n") ;
    runnit.stop() ;
  }

 public void process() {
    stopped = false ;
    // start a thread running
    trace("Starting " + name + " \n") ;
    runnit = new Thread(this) ;
    runnit.start() ;
 }



   // start an interval timer and watch the specified file/dir
   // for the condition every 15 seconds.  If the condition occurs
   // do the specified action.
   public void run() {

     int interval = 15 * 1000 ;   // 15 seconds
     while(stopped == false){     // interval timer
        try {
           Thread.sleep((long)interval) ;  // in milliseconds
           trace(name + ": checking " + fileName + " \n") ;
        }
        catch (InterruptedException e)
        {
          // interrupted
        }
        boolean cond = checkCondition() ;
        if (cond == true) {
           performAction() ;
        }
     }
     return ;
   }

    boolean checkCondition() {
        boolean truth = false ;
        switch (condition) {
         case MODIFIED:
            truth = changed() ;
            break ;
         case DELETED:           // was file deleted?
            truth = !exists() ;  // see if file exists
            break ;
         case THRESHOLD:
            break ;
        }
        return truth ;
    }

 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() ;
 }


 public  void ciaEventFired(EventObject e) {
      System.out.println("FileAgent:  CIAgentEvent received by " + name +
                         " from " + e) ;
  }

}