#lang scheme

;;;; La clase de los guiones. Conocimiento. Carente de dinamismo
(define guion%
  (class object%
    (field
     (secuencia-actos 'una-lista-ordenada)
     )
    (define/public set-actos
      (lambda procs-por-orden
        (set! secuencia-actos procs-por-orden)
        ))
    (define/public plan-accion
      (lambda ()
        secuencia-actos
        ))
    (super-new)
    ))
;;;; Modelo de instancia
(define saludo-presentacion (make-object guion%))
;;
(define extender-mano
  (lambda ()
    (printf "extendiendo la mano diestra~n")
    ))
(define estrechar-mano
  (lambda ()
    (printf "estrechando la mano del otro~n")
    ))
(define hablar
  (lambda (frase)
    (printf "profiriendo: ~a~n" frase)
    ))
;;
(send saludo-presentacion set-actos
      extender-mano estrechar-mano hablar)
;;;;; Otra instancia de guion
(define en-ascensor (make-object guion%))
;;
(define al-entrar
  (lambda ()
    (let ((frases-posibles 
           (list "Hola" "Buenos días" "Buenas tardes"))
          )
      (hablar 
       (list-ref frases-posibles 
                 (random (length frases-posibles))))
      )
    ))
(define otro-abandona-ascensor
  (lambda ()
    (let ((frases-posibles 
           (list "Adiós" "Hasta luego" "Buen día"))
          )
      (hablar 
       (list-ref frases-posibles 
                 (random (length frases-posibles))))
      )
    ))
(define al-salir
  (lambda ()
    (let ((frases-posibles 
           (list "Adiós" "Hasta luego" "Buen día"))
          )
      (hablar 
       (list-ref frases-posibles 
                 (random (length frases-posibles))))
      )
    ))
;;
(send en-ascensor set-actos
      al-entrar otro-abandona-ascensor al-salir)
;;;;; En el banco
(define en-banco (make-object guion%))
;;
(define saludo-inicial
  (lambda ()
    (let ((frases-posibles 
           (list "Hola" "Buenos días"))
          )
      (hablar 
       (list-ref frases-posibles 
                 (random (length frases-posibles))))
      )
    ))
(define deseo-hacer
  (lambda (operacion)
    (hablar
     (string-append "Deseo " operacion))
    ))
(define intercambio-actos
  (lambda ()
    (let itera ((funcionario 
                 (list 
                  "Acción funcionario: "
                  "Acción funcionario: "
                  "Acción funcionario: "
                  "Acción funcionario: "))
                (cliente
                 (list
                  "Acción cliente: ";"Mi DNI es..."
                  "Acción cliente: ";"... euros"
                  "Acción cliente: ";"Lo cuenta"
                  ))
                )
      (if (null? cliente)
          (hablar "Gracias")
          (begin
            (hablar (first funcionario))
            (sleep 1)
            (hablar (first cliente))
            (itera (rest funcionario) (rest cliente)))
          )
      )
    ))
(define al-acabar
  (lambda ()
    (let ((frases-posibles 
           (list "Adiós" "Hasta otro día" "Buen día"))
          )
      (hablar 
       (list-ref frases-posibles 
                 (random (length frases-posibles))))
      )
    ))
;;
(send en-banco set-actos
      saludo-inicial deseo-hacer intercambio-actos al-acabar)
;;;;;
(let itera ((lst (send en-banco plan-accion)))
    (if (null? (cdr lst))
        ((first lst))
        (begin
          (if (equal? (first lst) deseo-hacer)
            ((first lst) "hacer un ingreso")
            ((first lst)))
          (itera (rest lst)))))

(let itera ((lst (send en-banco plan-accion)))
    (if (null? (cdr lst))
        ((first lst))
        (begin
          (if (equal? (first lst) deseo-hacer)
            ((first lst) "retirar dinero")
            ((first lst)))
          (itera (rest lst)))))