;;;; Preloading pages.

(yreq "UI/page-directory")		; Defines *page-directory*, *ui-pages*, and *ui-file-list*.

(define (seaq a alist)
  (let ((val (assq a alist)))
    (if val
	(cdr val)
	#f)))

(define ui:file-procs
  (begin
    (define (as-is file)
      (let ((sr (sr:make-string 1000)))
	(do ((char (read-char file) (read-char file)))
	    ((eof-object? char) (sr:to-string sr))
	  (sr:add-char! char sr))))
    (define text as-is)
    (define (scheme file)
      (eval (read file)))
    (define (scheme-source file)
      (define ret '())
      (define done #f)
      (define mode 'text)
      (do ()
	  (done ret)
	(case mode
	  ((text)
	   (let ((sr (sr:make-string 1000)))
	     (do ((char (read-char file) (read-char file)))
		 ((or (eof-object? char) (char=? #\{ char))
		  (if (eof-object? char)
		      (set! done #t)
		      (set! mode 'scheme))
		  (set! ret (append ret (list (sr:to-string sr)))))
	       (sr:add-char! char sr))))
	  ((scheme)
	   (cond ((char=? (peek-char file) #\})
		  (read-char file)
		  (set! mode 'text))
		 (t
		  (let ((exp (read file)))
		    (cond ((eof-object? exp)
			   (set! done #t))
			  ((eq? '} exp)
			   (set! mode 'text))
			  (else (set! ret (append ret (list exp))))))))))))
    `((as-is . ,as-is)
      (text . ,text)
      (scheme-source . ,scheme-source)
      (scheme . ,scheme))))

(define (ui:read-ui-file filespec after-time) ; If after-time is NIL or 0, it's unconditional.
  (unless (number? after-time)
    (set! after-time 0))
  (let* ((name (car filespec))
	 (procs (string-edit ".html" ".scm" name))
	 (was-html? (not (equal? procs name)))
	 (scm? #f)
	 (scm-tried? #f))
    (when was-html?
      (let ((full-scm (string-append *page-directory* procs)))
	(set! scm? (file-exists? full-scm))
	(when (and scm?
		   (or (zero? after-time)
		       (> (vector-ref (stat full-scm) 10) after-time)))
	  (format t "~&Reading ~A" procs)
	  (set! scm-tried? #t)
	  (try-load full-scm))))
    (let ((full-html (string-append *page-directory* name)))
      (when (or (zero? after-time)
		(> (vector-ref (stat full-html) 10) after-time))
	(if scm-tried?
	    (format t ", html~&")
	    (format t "~&Reading ~A~&" name))
	((seaq (caadr filespec) ui:file-procs)
	 (open-input-file full-html))))))

(define (ui:maybe-update-entry entry ruf-value) ; read-ui-file could return garbage if it falls off its various conditionals; this means "no change".
  (unless (or (eq? ruf-value *unspecified*)
	      (eq? ruf-value #f)
	      (eq? ruf-value '()))
    (set-cdr! (cddr entry) (list ruf-value))))

(define (ui:preload-ui-pages after-time)
  (ui:maybe-generate-page-tables)
  (for-each (lambda (entry)
	      (ui:maybe-update-entry entry (ui:read-ui-file entry after-time)))
	    *ui-file-list*))

(define (ui:reload-page filename)
  (let ((entry (assoc filename *ui-file-list*)))
    (ui:maybe-update-entry entry (ui:read-ui-file entry 0))))

;;; End of file.
