#lang scheme
;(require scheme/class)

(define base-cuentas%
  (class object% ;()
    (init-field
     (sucursal 0))
    (field
     (bd-cuentas '())
     (n-siguiente 1))
    ;;;;;;;;;;;;;;;;;;;;
    (define/private extrae-cuenta
      (lambda (bd id)
        (if (null? bd)
            "no existe"
            (if (= (send (car bd) get-id) id)
                (car bd)
                (extrae-cuenta (cdr bd) id)) )))
    ;;;;;;
    (define crear
      (lambda ()
        (let*
            ((numero (+ sucursal n-siguiente))
             (cuenta (make-object cuenta% numero)) )
          (set! bd-cuentas (cons cuenta bd-cuentas))
          (display "Titular? ")
          (send cuenta set-titular (read))
          (display "Saldo inicial? ")
          (send cuenta set-saldo (read))
          (set! n-siguiente (add1 n-siguiente))
          (display "Cuenta creada con número: ")
          (display (send cuenta get-id))
          (display " Titular: ")
          (display (send cuenta get-titular))
          (display " Saldo: ")
          (display (send cuenta get-saldo)) )))
    (define ingresar
      (lambda ()
        (display "Número de cuenta? ")
        (let*
            ((numero (read))
             (cuenta (extrae-cuenta bd-cuentas numero)))
          (display "Confirme titular = ")
          (display (send cuenta get-titular))
          (if (equal? (read) 's)
              (begin
                (display "Cantidad? ")
                (send cuenta ingresar (read)) 
                )
              "Titular no confirmado")
          ) ))    
    (define sacar
      (lambda ()
        (display "Número de cuenta? ")
        (let*
            ((numero (read))
             (cuenta (extrae-cuenta bd-cuentas numero)))
          (display "Confirme titular = ")
          (display (send cuenta get-titular))
          (if (equal? (read) 's)
              (begin
                (display "Cantidad? ")
                (send cuenta sacar (read)) )
              "Titular no confirmado")
          ) ))
    (define saldo
      (lambda ()
        (display "Número de cuenta? ")
        (let*
            ((numero (read))
             (cuenta (extrae-cuenta bd-cuentas numero)))
          (display "Confirme titular = ")
          (display (send cuenta get-titular))
          (if (equal? (read) 's)
              (begin
                (display "Saldo disponible ")
                (display (send cuenta get-saldo)))
              #f
              ) )))
    (define cerrar
      (lambda ()
        (display "Número de cuenta? ")
        (let*
            ((numero (read))
             (cuenta (extrae-cuenta bd-cuentas numero)))
          (display "Confirme titular = ")
          (display (send cuenta get-titular))
          (if (equal? (read) 's)
              (begin
                (display "Cuenta ")
                (display (send cuenta get-id))
                (display " Titular ")
                (display (send cuenta get-titular))
                (send cuenta set-acceso #f)
                (display " cerrada")
                )
              #f
              ) )))
    ;;;;;;
    (public crear ingresar sacar saldo cerrar)
    ;;;;;;
    (super-new) ))

;(define bd (make-object base-cuentas% 1000))

;;;;;;;;;;;
(define cuenta%
  (class object% ;()
    (init-field
     identificador)
    (field
     (poseedor 'ssss)
     (acceso #t)
     (saldo 0) )
    ;;;;;;;;;;;;;;;;;;;;
    (define get-id
      (lambda ()
        identificador))
    ;;;;;;
    (define get-titular
      (lambda ()
        poseedor))
    (define set-titular
      (lambda (x)
        (set! poseedor x)))
    ;;;;;;
    (define get-saldo
      (lambda ()
        saldo))
    (define set-saldo
      (lambda (x)
        (set! saldo x)))
    ;;;;::
    (define get-acceso
      (lambda ()
        acceso))
    (define set-acceso
      (lambda (x)
        (set! acceso x)))
    ;;;;;;
    (define ingresar
      (lambda (x)
        (set! saldo (+ saldo x))
        (display "Saldo resultante ")
        (display saldo)
        ))    
    (define sacar
      (lambda (x)
        (cond
          ((> x saldo)
           "Crédito insuficiente" )
          (else
           (set! saldo (- saldo x))
           (display "Saldo resultante ")
           (display saldo)) )
        ))    
    ;;;;;;
    (public get-id get-acceso get-titular get-saldo
            set-saldo set-acceso set-titular
            ingresar sacar)
    ;;;;;;
    (super-new) ))



;(define q (make-object cuenta% 1001))
;(define q (instantiate cuenta% () (identificador 1001)))
;(define q (new cuenta% (identificador 1001)))


;(define sucursal (make-object base-cuentas% 1800))
;(define sucursal (instantiate base-cuentas% () (sucursal 1800)))
;(define sucursal (new base-cuentas% (sucursal 1800)))