#lang scheme
(require scheme/mpair)
(require scheme/class)
;;;;
(provide tabla%)
;;;; Clase tablas. No son agentes. Son objetos
(define tabla%
  (class* object% ()
    (init-field registro);un vector
    (field
     (la-tabla (mlist registro))     
     )
;;Para ver contenido tabla
    (define get-tabla
      (lambda ()
        la-tabla))
;;Métodos sobre tablas
    (define-syntax tabla-set!
      (syntax-rules ()
        ((tabla-set! lista pos new-reg)
         (mfor-each
          (lambda (reg)
            (when (= (vector-ref reg 0) pos)
              (vector-copy! reg 0 new-reg)))
          lista)) ))
    (define new-id
      (lambda ()
        (mlength la-tabla)))    
    (define tabla-append
      (lambda (reg)
        (set-mcar! la-tabla (mcar la-tabla))
        (set-mcdr! la-tabla (mappend (mcdr la-tabla) (mlist reg))) )) 
    (define tabla-mod
      (lambda (new-reg)
        (let ((pos (vector-ref new-reg 0))
              )
          (tabla-set! (mcdr la-tabla) pos new-reg) ) ))
    (define tabla-match ; devuelve una lista de registros
      (lambda (key valor);nº orden de key
        (let ((lista-registros '()) )
          (mfor-each ;ormap
           (lambda (reg)
             (if (equal? (vector-ref reg key) valor)
                 (set! lista-registros (cons reg lista-registros))
                 #f))
           la-tabla)
          (if (null? lista-registros)
              #f
              lista-registros)
          ) ))
;;Lo público
    (public new-id tabla-append tabla-mod tabla-match get-tabla)
    (super-new) ))
;;;;
;;;;
(define registro-per (vector 'id-per 'nombre 'dni 'id-cc));relación uno a uno
(define registro-cc (vector 'id-cc 'saldo 'id-per))

(define tabla-cc (make-object tabla% registro-cc))
(define tabla-per (make-object tabla% registro-per))
