examples/closed-loop-graphical.ss
(require (planet "simulation-with-graphics.ss"
                 ("williams" "simulation.plt")))
(require (planet "random-distributions.ss"
                 ("williams" "science.plt")))

(define attendant #f)

(define (generator n)
  (do ((i 0 (+ 1 i)))
      ((= i n) (void))
    (wait (random-exponential 4.0))
    (schedule now (customer i))))

(define-process (customer i)
  (with-resource (attendant)
    (wait/work (random-flat 2.0 10.0))))

(define (run-simulation n1 n2)
  (parameterize
      ((current-output-port (open-output-text-editor text)))
    (with-new-simulation-environment
     ;; Initialize graphics
     (begin-busy-cursor)
     (send run-button enable #f)
     (send gauge set-range n1)
     ;; Start open loop simulation
     (let ((k (make-variable 0))
           (avg-queue-length (make-variable)))
       (tally (variable-statistics avg-queue-length))
       (tally (variable-history avg-queue-length))
       (monitor after (set-variable-value! k v)
                (send gauge set-value v))
       (send gauge set-value 0)
       (do ((i 0 (+ i 1)))
           ((= i n1) (void))
         (with-new-simulation-environment
          (set! attendant (make-resource (send n-attendants-slider get-value)))
          (schedule (at 0.0) (generator n2))
          (start-simulation)
          (set-variable-value!
           avg-queue-length
           (variable-mean (resource-queue-variable-n attendant)))
          (send text erase)
          (printf "Number of experiments = ~a~n"
                  (variable-n avg-queue-length))
          (printf "Minimum average queue length = ~a~n"
                  (variable-minimum avg-queue-length))
          (printf "Maximum average queue length = ~a~n"
                  (variable-maximum avg-queue-length))
          (set-variable-value! k i)))
       (printf "Mean average queue length = ~a~n"
               (variable-mean avg-queue-length))
       (printf "Variance average queue length = ~a~n"
               (variable-variance avg-queue-length))
       (write-special (history-plot (variable-history avg-queue-length)
                                    "Average Queue Length")))
   ;; Finalize graphics
   (send run-button enable #t)
   (end-busy-cursor))))

;;; Simulation graphics

(define frame (instantiate frame% ("Graphical Closed Loop Example")
                (x 0) (y 0)))
(define n1-slider (instantiate slider% ("Number of runs" 1 1000 frame)
                    (init-value 100)
                    (style '(horizontal vertical-label))))
(define n2-slider (instantiate slider% ("Number of customers per run" 1 1000 frame)
                    (init-value 100)
                    (style '(horizontal vertical-label))))
(define n-attendants-slider (instantiate slider% ("Number of attendents" 1 100 frame)
                    (init-value 2)
                    (style '(horizontal vertical-label))))
                                
(define canvas (instantiate editor-canvas% (frame)
                 (min-width 500)
                 (min-height 400)
                 (style '(no-hscroll no-vscroll))))
(define text (instantiate text% ()))
(send canvas set-editor text)

(define gauge (instantiate gauge% ("Progress" 100 frame)))

(define run-button (instantiate button%
                     ("&Run" frame (lambda (b e)
                                     (run-simulation
                                      (send n1-slider get-value)
                                      (send n2-slider get-value))))))

(send frame show #t)