(module common racket
  (require scribble/core scribble/base scribble/html-properties scriblib/render-cond)
  (require setup/dirs)
  (require mzlib/etc)

  The function amkhlv/css-file-path() will not be used, because I decided 
  that the .css files should be local to each slideshow
  (provide amkhlv/css-file-path)
  (define (amkhlv/css-file-path cssname) (build-path 
                                          (string->path (string-append "css/" cssname))))

  Provides relative path for e.g.:
  @(hyperlink (amkhlv/path-to-link "../document.pdf") "here")
   [amkhlv/path-to-link (-> path-string? string?)])
  (define amkhlv/path-to-link
    (lambda (relpath)
      (string-append "file://" (path->string (path->complete-path (expand-user-path relpath))))

  javascript injection
   [amkhlv/js (->* () () #:rest (listof string?) element?)])
  (define (amkhlv/js . body)
     (make-style #f (list (make-script-property "text/javascript" body)))

  javascript from URL
   [amkhlv/js-url (-> string? element?)])
  (define (amkhlv/js-url url)
    (amkhlv/js "document.write(\"<script src='"  url  "'/><\\/script>\");"))

  This is a very universal style selector for element
   [amkhlv/elemstyle (-> string? style?)])
  (define (amkhlv/elemstyle s)
    (make-style #f  (cons (make-attributes (list (cons 'style s)))
                          (style-properties plain))))

  A table
  (provide amkhlv/rectangular-table?)
  (define (amkhlv/rectangular-table? a)
    (and (list? a) 
         (for/and ([y a]) (list? y))
         (let ([ly (length a)])
           (and ((length a) . > . 0)
                (let ([lx (length (car a))])
                  (and (lx . > . 0)
                       (for/and ([z (cdr a)]) 
                                (= (length z) lx))))))))
            [amkhlv/table (->* (amkhlv/rectangular-table?) (#:orient (or/c 'hor 'vert)) table?)])
  (define (amkhlv/table listofrows #:orient [dirn #f])
    (let* (
           [cell-style-suffix (if dirn
                                  (if (equal? dirn 'hor) 
            (make-style (string-append "amktablecell" cell-style-suffix) '())]
            (make-style (string-append "amktabletopleftcell" cell-style-suffix) '())]
            (make-style (string-append "amktableleftcell" cell-style-suffix) '())]
            (make-style (string-append "amktabletopcell" cell-style-suffix) '())]
            (cons topleft-cell-style
                  (map (lambda (x) top-cell-style) (cdr (car listofrows)))
            (cons left-cell-style
                  (map (lambda (x) generic-cell-style) (cdr (car listofrows)))
            (cons style-def-first-row
                  (map (lambda (x) style-def-generic-row) (cdr listofrows))
      (make-table (make-style #f (list (make-table-cells style-def)))
                  (map (lambda (x) 
                         (map (lambda (y) 
                                (if (block? y)
                                    (make-paragraph plain y)))

  (provide/contract [amkhlv/verb 
                     (->* ((or/c string? #f)) (#:indent exact-nonnegative-integer?) #:rest (listof string?) block?)])
  (define (nolinebreaks p)
     (make-style #f '())
     (map (lambda (x)
             (make-paragraph (make-style #f (list 'div)) 
                             (paragraph-content (car x))))
          (table-blockss p)))
  (define amkhlv/verb (compose nolinebreaks verbatim))

                                        ; colored text
   [amkhlv/clr (->* ((or/c string? (list/c byte? byte? byte?))) () #:rest (listof content?) element?)]) 
  (define (amkhlv/clr clr-name . txt)
    (element (style #f (list (color-property clr-name)))