#lang scheme
(require xml
         "define.ss"
         "function.ss"
         "text.ss")
(define css/c (listof (cons/c text/c (listof (list/c text/c text/c)))))
(provide/contract
 [css/c flat-contract?]
 [css? (-> any/c boolean?)]
 [write-css (->* [css/c] [output-port?] void?)])
(define css? (flat-contract-predicate css/c))
(define write-css
  (lambda/parameter (css [output #:param current-output-port])
    (for-each write-style-defn css)))
(define write-style-defn
  (lambda/parameter (style-defn [output #:param current-output-port])
    (write-selector (car style-defn))
    (display " {")
    (for-each write-prop-defn (cdr style-defn))
    (display " }\n")))
(define write-text
  (lambda/parameter (text [output #:param current-output-port])
    (display (text->string text))))
(define write-selector write-text)
(define write-prop-defn
  (lambda/parameter (prop-defn [output #:param current-output-port])
    (display " ")
    (write-prop-name (car prop-defn))
    (display " : ")
    (write-prop-val (cadr prop-defn))
    (display ";")))
(define write-prop-name write-text)
(define write-prop-val write-text)
(define-if-unbound xexpr/c
  (flat-named-contract "Xexpr" xexpr?))
(provide xexpr/c)
(provide write-xexpr)
(define-if-unbound write-xexpr
  (lambda/parameter (xexpr [output #:param current-output-port])
    (write-xml/content (xexpr->xml xexpr))))
(provide/contract
 [create-webpage (string? xexpr/c . -> . void?)]
 [create-stylesheet (string? css/c . -> . void?)])
(define (create-stylesheet filename css)
  (let* ([out-port (open-output-file filename #:exists 'replace)])
    (write-css css out-port)
    (close-output-port out-port)))
(define (create-webpage filename xexpr)
  (let* ([out-port (open-output-file filename #:exists 'replace)])
    (write-xexpr xexpr out-port)
    (close-output-port out-port)))