import edu.mit.ai.psg.jevaESUI.JevaESUI;
import edu.mit.ai.psg.jevaES.JevaES;
import java.util.*;
import java.text.*;

/** DemoAppointmentCalendarStub

    An example showing the read-eval-print-loop JevaESUI.replWindowValue()
    being used for unimplemented stub code: When the stub is called to make an
    appointment, a window pops up to ask the user what to do, and user types
    in Java statements to implement stub body for this call.

    User may simply type "return true;" to accept and return 
    (e.g., if state of appointments is kept off line on a sheet of paper).

    Alternatively user may also type code to update the vector of appointments:
    <pre>
    { 
      Object appt = new DemoAppointmentCalendarStub.Appointment
                         (dateTime, durationMinutes, purpose, contact);
      appointments.addElement(appt);
      return true;
    }
    </pre>
    Recursive invocation is allowed; User may type in code that 
    recursively invokes another stub, e.g., to cancel a conflicting 
    appointment.  

    Note that user may throw any exception from JevaESUI.replWindowValue(), so
    each stub method must catch all exceptions and rethrow only those which
    its specification allows it to throw.
**/
public class DemoAppointmentCalendarStub {
  public static void main(String[] ignore) {
    try {
      DemoAppointmentCalendarStub apptBook = new DemoAppointmentCalendarStub();
      // initialize with 2 example appointments
      DateFormat dateParser = new SimpleDateFormat("d MMM yyyy, HH:mm");
      apptBook.appointments.addElement
	(new DemoAppointmentCalendarStub.Appointment
	 (dateParser.parse("1 Dec 1998, 16:15"), "30 min Team Meeting"));
      apptBook.appointments.addElement
	(new DemoAppointmentCalendarStub.Appointment
	 (dateParser.parse("30 Nov 1998, 14:30"), "90 min Class Meeting"));
      // make an appointment
      apptBook.makeAppointment(dateParser.parse("1 Dec 1998, 16:30"), 
			       "90 min Learning Seminar");
    } catch(ParseException e) { throw new Error(""+e); }
    finally { System.exit(0); }
  }
  // -- simple Vector to hold Appointment refs ---
  public Vector appointments = new Vector();
  // -- inner Appointment class ---
  public static class Appointment {
    public Date dateTime;
    public String purpose;
    public Appointment(Date dateTime, String purpose) {
      this.dateTime = dateTime; 
      this.purpose = purpose; 
    }
    public String toString() { return "Appt["+dateTime+": "+purpose+"]"; }
  }
  // --- methods ---
  public boolean makeAppointment(Date dateTime, String purpose) {
    // stub
    try {
      Boolean result = (Boolean) 
      JevaESUI.repl
      (0,
       ("/** makeAppointment stub: Consider adding new Appointment to "+
	"appointments;\n"+
	"    return true if accepted, false if not accepted. **/\n"+
	"boolean makeAppointment("+
	"\n  (Date) dateTime: "+dateTime+
	"\n  (String) purpose: "+purpose+")\n"+
	"(Vector) appointments: "+appointments+ "\n"+
	"self: "+this+"\n"),
       Boolean.class, JevaESUI.NoThrowDeclarations,
       JevaES.extendEnv
       (Date.class, "dateTime", dateTime,
	JevaES.extendEnv
	(String.class, "purpose", purpose,
	 JevaES.extendEnv
	 (Vector.class, "appointments", appointments,
	  JevaES.extendEnv
	  (DemoAppointmentCalendarStub.class, "self", this,
	   JevaES.makeDefaultEnv())))));
      return result.booleanValue();
    } catch (Throwable t) { throw new Error("thrown: "+t); }
  }

  public void cancelAppointment(Date dateTime)
  throws IllegalArgumentException {
    // stub
    try {
      JevaESUI.repl
	(0,
	 ("/** cancelAppointment stub: cancel old appointment from "+
	  "appointments;\n"+
	  "    throw an IllegalArgumentException if no such appointment.**/\n"+
	  "void cancelAppointment("+
	  "\n  (Date) dateTime: "+dateTime+")\n"+
	  "throws IllegalArgumentException\n"+
	  "(Vector) appointments: "+appointments+ "\n"+
	  "self: "+this+"\n"),
	 void.class, new Class[] {IllegalArgumentException.class},
	 JevaES.extendEnv
	 (Date.class, "dateTime", dateTime,
	  JevaES.extendEnv
	  (Vector.class, "appointments", appointments,
	   JevaES.extendEnv
	   (DemoAppointmentCalendarStub.class, "self", this,
	    JevaES.makeDefaultEnv()))));
    } catch (Throwable t) { throw new Error("thrown: "+t); }
  }
}


