(define (maak-auto capaciteit) 
  (let ((batterij 100)
        (laadstation #f))

    (define (charge!)
      (if laadstation
          (begin (set! batterij 100)
                 ((laadstation 'withdraw!) (* capaciteit (/ (- 100 batterij) 100))))))
    


    (define (koppel! station)
      (if (and (not laadstation) (station 'vrij?)) 
          (begin (set! laadstation station) (station 'koppel!)))) 

    (define (ontkoppel!)
      (if laadstation      
          (begin (laadstation 'ontkoppel!)
                 (set! laadstation #f))))

    (define (dispatch msg)
      (cond ((eq? msg 'charge) batterij)
            ((eq? msg 'charge!) charge!)
            ((eq? msg 'koppel!) koppel!)
            ((eq? msg 'ontkoppel!) ontkoppel!) 
            (else (display "error: wrong message!"))))
    dispatch))



;;----------------------------------

(define (maak-laadstation)
  (let ((koppeling #f)
        (afgenomen 0))
    
    (define (withdraw! hoeveelheid)
      (set! afgenomen (+ afgenomen hoeveelheid)))

    (define (koppel!)
      (set! koppeling #t))

    (define (ontkoppel!)
      (set! koppeling #f))

    (define (dispatch msg)
      (cond ((eq? msg 'withdraw!) withdraw!)
            ((eq? msg 'vrij?) (not koppeling))
            ((eq? msg 'koppel!) (koppel!))
            ((eq? msg 'ontkoppel!) ontkoppel!) 
            (else (display "error: wrong message!")))) 
    dispatch))



;;----------------------------------

(define (maak-laadpark n)

  (define (maak-stations n)
    (if (= n 0)
        '()
        (cons (maak-laadstation) (maak-stations (- n 1)))))
  (let ((stations (maak-stations n))) 
    
    (define (full? stations) 
      (cond ((null? stations) #t)
            (((car stations) 'vrij?) #f)
            (else (full? (cdr stations)))))
     
    (define (enter! auto)
      (define (iter stations auto) 
        (cond ((null? stations) #f)
              (((car stations) 'vrij?) ((auto 'koppel!) (car stations)))
              (else (iter (cdr stations) auto))))
      (iter stations auto))

    (define (dispatch msg)
      (cond ((eq? msg 'full?) (full? stations)) ;(full? stations) 
            ((eq? msg 'enter!) enter!)
            (else (display "error: wrong message!"))))
    dispatch))