(require 'posix-time)

(define (attestations:check-for-addition)
  (set! *ui:attestations-new* #f)	; Close the door.
  (cond ((ui:from-form?)
	 (add-attestation! (ui:form-datum "newatt"))
	 (format nil "<h1>New Attestation</h1>~2&You now attest ~S"
		 (ui:form-datum "newatt")))
	(t "")))

(define *attestations:table-cellspacing* 10)
(define *attestations:whole-att-untrusted-color* "darkred")
(define *attestations:whole-att-trusted-color* "darkgreen")

(define (attestations:generate-table id)
  (let ((rows (attestations:generate-attestation-rows id)))
    (cond ((not (or (null? rows)
		    (equal? rows "")))
	   (attestations:generate-table-skeleton rows))
	  (t "<b>[No attestations.]</b><p>"))))

(define (attestations:generate-table-skeleton rows)
  (format nil
"<table cellpadding=\"0\" cellspacing=\"~A\" border=\"0\">
  <tr>
    <th align=\"center\">Status</th>
    <th align=\"center\">Message</th>
    <th align=\"center\">Signers</th>
    <th align=\"center\">Oldest sig</th>
    <th align=\"center\">Newest sig</th>
  </tr>
  ~A
</table>~%"
	  *attestations:table-cellspacing*
	  rows))

(define (attestations:generate-attestation-rows id)
  (let ((rows
	 (map (lambda (att)
		(attestations:generate-one-attestation-row att id))
	      (or (identity:get-attestations id) '()))))
    (join-strings rows "")))

;;; Returns a triple of the signers and the earliest and latest signature times for this attestation.
(define (attestations:compute-signatures att id)
  (let ((sigs (cadr att))
	(mintime #x7fffffff)		; %% Should really be most-positive-int or something...
	(maxtime 0))
    (define (check-sig sig)		; Side-effects mintime and maxtime.
      (let* ((ident (car sig))
	     (timestamp (cadr sig))
	     (trusted? (test-signature (car att) id sig))) ; In other words, is -this particular signature- trusted.  Says nothing about whole att.
	(case trusted?
	  ((yes)
	   (when (< timestamp mintime) (set! mintime timestamp))
	   (when (> timestamp maxtime) (set! maxtime timestamp))
	   (identity:description-link-small ident ""))
	  ((maybe)
	   (identity:description-link-small ident "?"))
	  (else ""))))			; Ignore signatures we -know- are bad.
    (let* ((results (map check-sig sigs))
	   (signers (join-strings results ", ")))
      (list signers mintime maxtime))))

(define (attestations:generate-one-attestation-row att id)
  (let* ((triple (attestations:compute-signatures att id))
	 (signers (nth 0 triple))
	 (mintime (nth 1 triple))
	 (maxtime (nth 2 triple))
	 (whole-att-trusted? (test-attestation att id)))
    (format nil
"  <tr>
    <td valign=\"top\" align=\"center\">
	<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">
	  <tr>
	    <td valign=\"top\">&nbsp;<font color=\"~A\"><b>~A</b>&nbsp;</font></td>
	    <td valign=\"top\">&nbsp;~A&nbsp;</td>
	    <td valign=\"top\">&nbsp;~A&nbsp;</td>
	  </tr>
        </table>
    </td>
    <td valign=\"top\" align=\"left\"><font size=\"-1\">~A</font></td>
    <td valign=\"top\" align=\"center\">~A</td>
    <td valign=\"top\" align=\"center\"><font size=\"-1\">~A</font></td>
    <td valign=\"top\" align=\"center\"><font size=\"-1\">~A</font></td>
  </tr>~%"
	    (if (eq? whole-att-trusted? 'yes) *attestations:whole-att-trusted-color* *attestations:whole-att-untrusted-color*)
	    (if (eq? whole-att-trusted? 'yes) "T" "U") ; Trusted or untrusted.  We use letters -and- colors 'cause some people are colorblind...
	    (format nil "<a href=\"att-details.html?id=~A&msg=~A\"><b>?</b></a>"
		    (ui:bytes->hex id)
		    (url-encode (car att)))
	    (if (equal? *local-yenta-id* id)
		(format nil "<a href=\"att-delete.html?id=~A&msg=~A\"><b>X</b></a>"
			(ui:bytes->hex id)
			(url-encode (car att)))
		"&nbsp;")
	    (ui:literal (car att))
	    signers
	    (date-string mintime)
	    (date-string maxtime))))

;;;; Dead code.

; (define (insert-commas l)
;   (if (or (null? l)
; 	  (null? (cdr l))
; 	  (equal? (car l) ""))
;       l
;       (cons (car l) (cons ", " (cdr l)))))
; 
; (define (attestations:attestation-table-body id)
;   (map
;    (lambda (att)
;      (let ((mintime #x7fffffff)
; 	   (maxtime 0))
;        (append
; 	(list
; 	 "<tr><td>"
; 	 (ui:literal (car att))
; 	 "</td><td>"
; 	 (test-attestation att id) 
; 	 "</td><td>"
; 	 (insert-commas
; 	  (map
; 	   (lambda (sig)
; 	     (let* ((t (cadr sig))
; 		    (i (car sig))
; 		    (v (test-signature (car att) id sig))
; 		    (p (identity:description-link i)))
; 	       (case v
; 		 ((yes)
; 		  (format-debug 0 "~%Trusted:  (cat att) = ~S, id = ~S, sig = ~S~&" (car att) id sig)
; 		  (if (< t mintime)
; 		      (set! mintime t))
; 		  (if (> t maxtime)
; 		      (set! maxtime t))
; 		  p)
; 		 ((maybe)
; 		  (list
; 		   p
; 		   "?"))
; 		 (else ;ignore signatures we *know* are bad.
; 		  ""))))
; 	   (cadr att)))
; 	 "</td><td>"
; 	 (ctime mintime)
; 	 "</td><td>"
; 	 (ctime maxtime)
; 	 "</td><td>"
; 	 (format #f "<a href=\"att-details.html?id=~A&msg=~A\">Details</a>"
; 		 (ui:bytes->hex id) (url-encode (car att)))
; 	 )
; 	(if (equal? *local-yenta-id* id)
; 	    (list
; 	     "</td><td>"
; 	     (format #f "<a href=\"att-delete.html?msg=~A\">Delete</a>"
; 		     (url-encode (car att))))
; 	    '())
; 	"</td></tr>")))
;    (or (identity:get-attestations id) '())))
; 
; ;;; End of file.

