#lang scheme/base
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MIME.plt
;; an extensible MIME framework.
;; Bonzai Lab, LLC.  All rights reserved.
;; Licensed under LGPL.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; - the basic common MIME functionalities.
;; yc 2/18/2010 - first version.

(require ""

;; does it make sense to have a mime type without any additional fields?
(define-struct (mime kvs) ()) 

(define mime-header-readertable (make-kvs-registry '()))

(define (mime-header-reader-set! key reader)
  (registry-set! mime-header-readertable key reader)) 

(define (mime-header-reader-del! key)
  (registry-del! mime-header-readertable key)) 

(define (mime-header-reader-ref key (default #f)) 
  (registry-ref mime-header-readertable key default))

(define (mime-header-reader-list) 
  (registry-table mime-header-readertable))

(define mime-readertable (make-kvs-registry '()))

(define (mime-reader-set! key reader)
  (registry-set! mime-readertable key reader))
;;(trace mime-reader-set!)

(define (mime-reader-del! key)
  (registry-del! mime-readertable key)) 

(define (mime-reader-ref key (default #f))
  (registry-ref mime-readertable key default))

;; the default will have to be just a simple *read*...
(define mime-writertable (make-cond-registry '())) 

(define (mime-writer-set! type writer)
  (registry-set! mime-writertable type writer))

(define (mime-writer-del! type)
  (registry-del! mime-writertable type)) 

(define (mime-writer-ref type (default #f))
  (registry-ref mime-writertable type default))

;; we also want to do the same for the mime-body...
(define mime-body-table (make-cond-registry '())) 

(define (mime-body-set! type accessor)
  (registry-set! mime-body-table type accessor))

(define (mime-body-del! type)
  (registry-del! mime-body-table type)) 

(define (mime-body m)
  ((registry-ref mime-body-table m
                (lambda (m)
                  (error 'mime-body "unknown mime type: ~a" m))) m))

(provide mime)
 (struct:mime struct-type?)
 (mime? isa/c)
 (make-mime (-> kvlist? any))
 (mime-header-reader-set! (-> string? Reader/c any))
 (mime-header-reader-del! (-> string? any)) 
 (mime-header-reader-ref (->* (string?)
 (mime-header-reader-list (-> any))
 (mime-reader-set! (-> string? (-> input-port? kvs/list? any) any))
 (mime-reader-del! (-> string? any))
 (mime-reader-ref (->* (string?) (any/c) any))
 (mime-writer-set! (-> isa/c procedure? any))
 (mime-writer-del! (-> isa/c any)) 
 (mime-writer-ref (->* (kvs?) (any/c) any))
 (mime-body (-> kvs? any))
 (mime-body-set! (-> isa/c procedure? any))
 (mime-body-del! (-> isa/c any))