;;; mew-syntax.el --- Internal syntax for Mew

;; Author:  Kazu Yamamoto <Kazu@Mew.org>
;; Created: Oct  2, 1996
;; Revised: Oct 25, 1997

;;; Code:

(defconst mew-syntax-version "mew-syntax.el version 0.16")

(require 'mew)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mew-encode-syntax
;;
;; <esgl> = [ 'single file (dcr) (<epri>) (CT:)   CTE: CD: nil (CDP:) ]
;; <emul> = [ 'multi  dir/ (dcr) (<epri>) ("mul") CTE: CD: nil (CDP:) 1*<eprt> ]
;; <eprt> = <esgl> | <emul>
;; <epri> = list of (mew-ct-mls mew-ct-pgs)
;;
;; mew-decode-syntax
;;
;; <dmsg> = [ 'message hbeg hend (<dpri>) ("msg") CTE: CD: CID: (CDP:) <dbdy> ]
;; <dsgl> = [ 'single   beg  end (<dpri>) (CT:)   CTE: CD: CID: (CDP:) ]
;; <dmul> = [ 'multi    beg  end (<dpri>) ("mul") CTE: CD: CID: (CDP:) 1*<dprt> ]
;; <dbdy> = <dmul> | Text/Plain <dsgl>
;; <dprt> = <dmsg> | <dsgl> | <dmul>
;; <dpri> = list of (mew-ct-mls mew-ct-pgs RESULT) in reverse order ;; for cons

;;
;;
;;

(defmacro mew-syntax-singlepart-p (syntax)
  (` (eq (aref (, syntax) 0) 'single)))

(defmacro mew-syntax-multipart-p (syntax)
  (` (eq (aref (, syntax) 0) 'multi)))

(defmacro mew-syntax-message-p (syntax)
  (` (eq (aref (, syntax) 0) 'message)))

;;
;;
;;

(defmacro mew-syntax-get-key (syntax)
  (` (aref (, syntax) 0)))

(defmacro mew-syntax-set-key (syntax key)
  (` (aset (, syntax) 0 (, key))))

(defmacro mew-syntax-get-begin (syntax)
  (` (aref (, syntax) 1)))

(defmacro mew-syntax-set-begin (syntax begin)
  (` (aset (, syntax) 1 (, begin))))

(defmacro mew-syntax-get-end (syntax)
  (` (aref (, syntax) 2)))

(defmacro mew-syntax-set-end (syntax end)
  (` (aset (, syntax) 2 (, end))))

(defmacro mew-syntax-get-privacy (syntax)
  (` (aref (, syntax) 3)))

(defmacro mew-syntax-set-privacy (syntax privacy)
  (` (aset (, syntax) 3 (, privacy))))

(defmacro mew-syntax-get-ct (syntax)
  (` (aref (, syntax) 4)))

(defmacro mew-syntax-set-ct (syntax ct)
  (` (aset (, syntax) 4 (, ct))))

(defmacro mew-syntax-get-cte (syntax)
  (` (aref (, syntax) 5)))

(defmacro mew-syntax-set-cte (syntax cte)
  (` (aset (, syntax) 5 (, cte))))

(defmacro mew-syntax-get-cd (syntax)
  (` (aref (, syntax) 6)))

(defmacro mew-syntax-set-cd (syntax cd)
  (` (aset (, syntax) 6 (, cd))))

(defmacro mew-syntax-get-cid (syntax)
  (` (aref (, syntax) 7)))

(defmacro mew-syntax-set-cid (syntax cid)
  (` (aset (, syntax) 7 (, cid))))

(defmacro mew-syntax-get-cdp (syntax)
  (` (aref (, syntax) 8)))

(defmacro mew-syntax-set-cdp (syntax cdp)
  (` (aset (, syntax) 8 (, cdp))))

(defmacro mew-syntax-get-part (syntax)
  (` (aref (, syntax) 9)))

(defmacro mew-syntax-set-part (syntax part)
  (` (aset (, syntax) 9 (, part))))

;; alias for draft syntax

(defmacro mew-syntax-get-file (syntax)
  (` (aref (, syntax) 1)))

(defmacro mew-syntax-set-file (syntax file)
  (` (aset (, syntax) 1 (, file))))

(defmacro mew-syntax-get-decrypters (syntax)
  (` (aref (, syntax) 2)))

(defmacro mew-syntax-set-decrypters (syntax decrypters)
  (` (aset (, syntax) 2 (, decrypters))))

;; for ct: parameters

(defun mew-syntax-get-member (ctl member)
  (let ((case-fold-search t)
	(regex (concat "^" member "=\"?\\([^\"]*\\)\"?$"))) ;; xxx
    (catch 'loop
      (while ctl
	(if (string-match regex (car ctl))
	    (throw 'loop (mew-match 1 (car ctl))))
	(setq ctl (cdr ctl))
	)
      )
    ))

;; need to setq
(defmacro mew-syntax-cat (syntax part)
  (` (vconcat (, syntax) (vector (, part)))))

(defun mew-syntax-cdp-format (file)
  (if file (list "attachment" (concat "filename=" file))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Entry functions
;;

(defun mew-split-number (num-str)
  (let ((start 0)
	(end 0)
	(nums nil))
    (while (setq end (string-match "\\." num-str start))
      (setq nums (cons (string-to-int (substring num-str start end)) nums))
      (setq start (1+ end))
      )
    (nreverse (cons (string-to-int (substring num-str start nil)) nums))
    ))

(defun mew-syntax-get-entry-strnum (syntax strnum)
  (if (null strnum) 
      (mew-syntax-get-part syntax) ;; for old spec
    (mew-syntax-get-entry syntax (mew-split-number strnum)))
  )

(defun mew-syntax-get-entry (syntax nums)
  (cond
   ((null nums) syntax) ;; single & message match
   ((mew-syntax-message-p syntax)
    (mew-syntax-get-entry (mew-syntax-get-part syntax) nums))
   ((mew-syntax-multipart-p syntax)
    (if (null nums) syntax
      (mew-syntax-get-entry
	 (aref syntax (+ mew-syntax-magic (1- (car nums)))) (cdr nums))))
   ))

(defun mew-syntax-insert-entry (syntax nums entry)
  (let* ((root syntax)
	 (child entry)
	 grand parent
	 (nl (length nums))
	 (rev (reverse nums))
	 (n0 (nth 0 rev))
	 (n1 (nth 1 rev))
	 (ns (reverse (nthcdr 2 rev))))
    (cond
     ((= nl 1)
      (setq parent root)
      (mew-syntax-add-entry parent n0 child))
     (t
      (if (= nl 2)
	  (setq grand root)
	(setq grand (mew-syntax-get-entry root ns)))
      (setq parent (mew-syntax-get-entry grand (list n1)))
      (setq parent (mew-syntax-add-entry parent n0 child))
      (aset grand (+ mew-syntax-magic (1- n1)) parent)
      root
      )
     )
    ))

(defun mew-syntax-add-entry (syntax n entry)
  "Must not use in functions other than mew-syntax-insert-entry"
  (let* ((len (1+ (length syntax)))
	 (vec (make-vector len nil))
	 (cnt 0) (thr (+ mew-syntax-magic (1- n))))
    (while (< cnt thr)
      (aset vec cnt (aref syntax cnt))
      (setq cnt (1+ cnt)))
    (aset vec cnt entry)
    (setq cnt (1+ cnt))
    (while (< cnt len)
      (aset vec cnt (aref syntax (1- cnt)))
      (setq cnt (1+ cnt)))
    vec ;; return value
    ))

(defun mew-syntax-remove-entry (syntax nums)
  (let* ((root syntax)
	 grand parent
	 (nl (length nums))
	 (rev (reverse nums))
	 (n0 (nth 0 rev))
	 (n1 (nth 1 rev))
	 (ns (reverse (nthcdr 2 rev))))
    (cond
     ((= nl 1)
      (setq parent root)
      (mew-syntax-cut-entry parent n0))
     (t
      (if (= nl 2)
	  (setq grand root)
	(setq grand (mew-syntax-get-entry root ns)))
      (setq parent (mew-syntax-get-entry grand (list n1)))
      (setq parent (mew-syntax-cut-entry parent n0))
      (aset grand (+ mew-syntax-magic (1- n1)) parent)
      root
      )
     )
    ))

(defun mew-syntax-cut-entry (syntax n)
  "Must not use in functions other than mew-syntax-remove-entry"
  (let* ((len (1- (length syntax)))
	 (vec (make-vector len nil))
	 (cnt 0) (thr (+ mew-syntax-magic (1- n))))
    (while (< cnt thr)
      (aset vec cnt (aref syntax cnt))
      (setq cnt (1+ cnt)))
    (while (< cnt len)
      (aset vec cnt (aref syntax (1+ cnt)))
      (setq cnt (1+ cnt)))
    vec ;; return value
    ))

(defun mew-syntax-clear-marks (syntax nums)
  (cond
   ((null nums)
    ;; clear privacy
    (mew-syntax-set-privacy syntax nil)
    ;; get encoding back
    (mew-syntax-set-cte syntax
			(mew-syntax-get-cte
			 (mew-encode-syntax-single 
			  (mew-syntax-get-file syntax))))
    )
   (t
    (mew-syntax-clear-marks
     (aref syntax (+ mew-syntax-magic (1- (car nums)))) (cdr nums))
    )
   ))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mew-encode-syntax
;;

(defvar mew-syntax-number-text-regex "^.....\\([.0-9]+\\) +")
(defvar mew-syntax-number-icon-regex "<\\([0-9.]+\\)>")

(defun mew-summary-goto-part (msg part)
  (goto-char (point-min))
  (cond
   ((equal major-mode 'mew-virtual-mode)
    (if (re-search-forward (format "\r.*%s" msg) nil t)
	(re-search-forward (format "^.....%s" part) nil t)))
   ((equal major-mode 'mew-summary-mode)
    (if (re-search-forward (format "^ *%s" msg) nil t)
	(re-search-forward (format "^.....%s" part) nil t)))
   )
  (beginning-of-line)
  )

(defun mew-summary-goto-message ()
  (if (mew-summary-in-multi-p)
      (progn
	(goto-char (marker-position mew-summary-buffer-beg))
	(forward-line -1))))

(defun mew-syntax-number ()
  (let ((event last-command-event)
	ret str)
    (if (and mew-icon-p
	     (mouse-event-p event)
	     (event-over-toolbar-p event)
	     (or (button-press-event-p event)
		 (button-release-event-p event)))
	(progn
	  (setq str (toolbar-button-help-string (event-toolbar-button event)))
	  ;; last-pressed-toolbar-button can't be used.
	  (if (string-match mew-syntax-number-icon-regex str)
	      (setq ret (mew-match 1 str)))
	  ;; if "top", returns nil.
	  ret)
      (if (or (mew-draft-in-attach-p)
	      (mew-summary-in-multi-p))
	  (save-excursion
	    (beginning-of-line)
	    (if (looking-at mew-syntax-number-text-regex)
		(mew-match 1)))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; get number
;;;
    
(defun mew-summary-message-number ()
  (let ((event last-command-event)
	ret str)
    (if (and mew-icon-p	
	     ;; exclude press button 2 in summary buffer.
	     ;; exclude pulldown menu in Summary mode.
	     ;; exclude popup menu of multipart icon because
	     ;; the cursor has already moved.
	     (mouse-event-p event)
	     (event-over-toolbar-p event)
	     (or (button-press-event-p event)     ;; right button
		 (button-release-event-p event))) ;; left button
	(if last-pressed-toolbar-button
	    (progn
	      (setq str (toolbar-button-help-string 
			 last-pressed-toolbar-button))
	      (if (string-match "^\\([0-9]+\\) " str)
		  (setq ret (mew-match 1 str)))
	      )))
    (if ret
	ret
      (if (not (mew-summary-in-multi-p))
	  (save-excursion
	    (beginning-of-line)
	    (cond 
	     ((equal major-mode 'mew-summary-mode)
	      (if (looking-at mew-summary-message-regex)
		  (mew-match 1)
		nil)
	      )
	     ((equal major-mode 'mew-virtual-mode)
	      (if (looking-at ".*\r \\(\\+.*\\) \\(.*\\)$")
		  (mew-match 2)
		nil))
	     (t nil))))
      )))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mew-encode-syntax
;;

(defun mew-encode-syntax-single (file &optional ctl cte cd cid cdp 
				      privacy decrypters)
  ;; cid is just for beauty
  ;; if cdp is non-nil, set cdp from file.
  (let* ((attr (mew-attr-by-file file))
	 (ct (mew-attr-get-ct attr)))
    (or cte (setq cte (mew-attr-get-cte attr)))
    (if (null ctl) (setq ctl (list ct)))
    (if (and cdp 
	     (not (mew-member-match ct mew-mime-content-type-ignore-cdp t)))
	(setq cdp file)
      (setq cdp nil))
    (setq cdp (mew-syntax-cdp-format cdp))
    (vconcat [single] (list file decrypters privacy ctl cte cd cid cdp))
    ))

(defun mew-encode-syntax-multi (dir ct)
  (if (not (string-match (concat mew-path-separator "$") dir))
      (setq dir (file-name-as-directory dir)))
  (vconcat [multi] (list dir) [nil nil] (list ct) [nil nil nil nil])
  )

(defun mew-encode-syntax-initial (dir)
  (vconcat
   (mew-encode-syntax-multi dir mew-type-mlm)
   (list (mew-encode-syntax-single mew-draft-coverpage (list mew-ct-txt))))
  ;; ensure to guess charset ....
  )

(defun mew-encode-syntax-initial-multi (dir n)
  (let ((i 1) (ret))
    (while (<= i n)
      (setq ret (vconcat ret (list (mew-encode-syntax-single
				    (int-to-string i)))))
      (setq i (1+ i)))
    (vconcat (mew-encode-syntax-multi dir mew-type-mlm)
	     (list (mew-encode-syntax-single mew-draft-coverpage 
					     (list mew-ct-txt)))
	     ret)
    ))

(defconst mew-encode-syntax-dot
  [nil "." nil nil ("") nil nil nil nil])

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mew-decode-syntax
;;

(defun mew-decode-syntax-rfc822 (&optional msg-head)
  ;; msg-head may include CD:
  (if (null msg-head) (setq msg-head (mew-decode-syntax-rfc822-head t)))
  (vconcat msg-head (vector (mew-decode-syntax-text))))

(defun mew-decode-syntax-rfc822-head (&optional reg-hend)
  (vector 'message (point-min)
	  (and reg-hend
	       (save-excursion (forward-line -1) (beginning-of-line) (point)))
	  nil mew-type-msg nil nil nil nil))

(defun mew-decode-syntax-text ()
  (vector 'single (point) (point-max) nil mew-type-txt nil nil nil nil))

(defconst mew-encode-syntax-multi-head 
  (vector 'multi nil nil nil mew-type-mlm nil nil nil nil))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; syntax printer
;;

(defvar mew-summary-buffer-beg (make-marker))
(defvar mew-summary-buffer-end (make-marker))
(defvar mew-summary-buffer-tmp (make-marker))

(defun mew-summary-in-multi-p ()
  (and (marker-position mew-summary-buffer-beg)
       (marker-position mew-summary-buffer-end)
       (>= (point) (marker-position mew-summary-buffer-beg))
       (<  (point) (marker-position mew-summary-buffer-end))))

(defun mew-encode-syntax-print (syntax)
  (interactive)
  (let ((end nil)
	(nums (mew-attach-nums)))
    (cond
     ((mew-attach-p)
      (goto-char (point-max))
      (re-search-backward (concat "^" mew-draft-attach-boundary-end "$"))
      (setq end (point))
      (re-search-backward (concat "^" mew-draft-attach-boundary-begin "$"))   
      (forward-line)
      (delete-region (point) end)
      (save-excursion
	(mew-syntax-print syntax
			  ;; message number, xxx hard coding
			  (substring (mew-syntax-get-file syntax) 0 -1)
			  nil 'mew-draft-button
			  (if mew-icon-p mew-draft-toolbar))
	)
      (mew-attach-goto-number 'here nums)
      ))))

(defun mew-decode-syntax-print (msg syntax buf)
  (let ((cbuf (current-buffer)))
    (set-buffer buf)
    (forward-line)
    (set-marker mew-summary-buffer-beg (point) (current-buffer))
    (let* ((buffer-read-only nil)
	   (multi (mew-syntax-get-part syntax)))
      (mew-syntax-print multi msg 'decoding 'mew-summary-button
			(if mew-icon-p mew-summary-toolbar))
      (put-text-property (marker-position mew-summary-buffer-beg) (point)
			 'face 'default))
    (set-marker mew-summary-buffer-end (point) (current-buffer))
    (goto-char (marker-position mew-summary-buffer-beg))
    (forward-line -1)
    (set-buffer-modified-p nil)
    (set-buffer cbuf)))

;; The entire body is multipart/* or text/plain in Mew decode syntax.
;; This part number is 'nil' which is refered as "body". So, either 
;; multipart/* or text/plain can be labeled as "body". Other CT: 
;; under message are encapsulated in multipart/mixed. They are refered by
;; part number.

(defun mew-syntax-print (syntax msg dec func bar)
  (mew-syntax-clear-icon-spec)
  (if dec (mew-decode-syntax-clear-privacy))
  (mew-syntax-multipart msg syntax dec nil func 'body) ;; body is nil
  (if mew-icon-p
      (let ((toolbar))
	(cond
	 ((eq mew-multipart-icon-position 'left)
	  (setq toolbar (append (mew-syntax-get-icon-spec)
				mew-icon-separate-spec
				bar)))
	 ((eq mew-multipart-icon-position 'right)
	  (setq toolbar (append bar
				mew-icon-separate-spec
				(mew-syntax-get-icon-spec))))
	 (t (setq toolbar bar))
	 )
	(set-specifier default-toolbar (cons (current-buffer) toolbar))
	)))

(defun mew-syntax-multipart (msg syntax dec part func body)
  (let* ((ct (car (mew-syntax-get-ct syntax)))
	 (cd (or (mew-syntax-get-cd syntax) ""))
	 (cnt mew-syntax-magic)
	 (num 1)
	 (len (length syntax))
	 strpart subsyntax)
    ;; multipart itself is displayed only when encoding.
    (if dec
	(mew-decode-syntax-set-privacy
	 syntax
	 (concat (if part (concat part " "))
		 (if body "body ")
		 "multi"))
      (mew-syntax-format syntax part dec)
      (mew-syntax-set-icon-spec msg part
				ct cd
				(mew-attr-get-icon (mew-attr-by-ct ct)) func))
    (while (< cnt len)
      (if part
	  (setq strpart (concat part "." (int-to-string num)))
	(setq strpart (int-to-string num)))
      (setq subsyntax (aref syntax cnt))
      (cond
       ((mew-syntax-multipart-p subsyntax)
	(mew-syntax-multipart msg subsyntax dec strpart func nil))
       ((mew-syntax-message-p subsyntax)
	(mew-syntax-message msg subsyntax dec strpart func))
       ((mew-syntax-singlepart-p subsyntax)
	(mew-syntax-singlepart msg subsyntax dec strpart func
			       (and body (equal cnt mew-syntax-magic))))
       )
      (setq cnt (1+ cnt))
      (setq num (1+ num)))
    (if dec 
	()
      (if part
	  (setq part (concat part "." (int-to-string num)))
	(setq part (int-to-string num)))
      (mew-syntax-format mew-encode-syntax-dot part dec)
      (mew-syntax-set-icon-spec msg part "Attach Here" cd mew-icon-blank func))
    ))

(defun mew-syntax-singlepart (msg syntax dec part func first)
  ;; part is valid only when called by mew-syntax-multipart.
  (let ((ct (capitalize (car (mew-syntax-get-ct syntax))))
	(cd (or (mew-syntax-get-cd syntax) ""))
	(cdpl (mew-syntax-get-cdp syntax)))
    ;; see also mew-mime-message/rfc822.
    (if (and dec
	     ;; the first singlepart in multipart under message if t
	     ;; the first singlepart under message if 'body
	     first
	     ;; CT: is text/plain but not attached file.
	     (equal ct mew-ct-txt)
	     (or (null cdpl) (null (mew-syntax-get-member cdpl "filename"))))
	() ;; skip displaying.
      ;; reach here only when called by mew-syntax-multipart.
      (mew-syntax-format syntax part dec)
      (mew-syntax-set-icon-spec msg part ct cd 
				(mew-attr-get-icon (mew-attr-by-ct ct)) func))
    (if dec (mew-decode-syntax-set-privacy
	     syntax
	     (if (equal first 'body)
		 (if part (concat part " body") "body")
	       part)))
    ))

(defun mew-syntax-message (msg syntax dec part func)
  (let ((ct (capitalize (car (mew-syntax-get-ct syntax))))
	(cd (or (mew-syntax-get-cd syntax) ""))
	(subsyntax (mew-syntax-get-part syntax)))
    (mew-syntax-format syntax part dec)
    (if dec (mew-decode-syntax-set-privacy
	     syntax
	     (format "%s message" part)))
    (mew-syntax-set-icon-spec msg part ct cd 
			      (mew-attr-get-icon (mew-attr-by-ct ct)) func)
    (cond
     ((mew-syntax-multipart-p subsyntax)
      (mew-syntax-multipart msg subsyntax dec part func 'body))
     ((mew-syntax-message-p subsyntax)
      ) ;; never happens
     ((mew-syntax-singlepart-p subsyntax)
      ;; text/plain only
      (mew-syntax-singlepart msg subsyntax dec part func 'body))
     )
    ))

;012345678901234567890123456789012345678901234567890123456789012345678901234567
;<4>snss<27-2                   >ss<24+2                    >ss<16            >

(defun mew-syntax-format (syntax number dec)
  (let* ((file (if (not dec) (mew-syntax-get-file syntax)))
	 (ctl (mew-syntax-get-ct syntax))
	 (ct (capitalize (car ctl)))
	 (char (mew-syntax-get-member ctl "charset"))
	 (cte (mew-syntax-get-cte syntax)) ;; cte may be nil
	 (cd (mew-syntax-get-cd syntax))
	 (cdpl (mew-syntax-get-cdp syntax))
	 (filename (mew-syntax-get-member cdpl "filename"))
	 (decrypters (mew-syntax-get-decrypters syntax))
	 (cd-or-dec cd)
	 (privacy (mew-syntax-get-privacy syntax))
	 (space " ") (SP 32)
	 (cnt "..") (lcnt (length cnt))
	 (LT (- (window-width) 2))
	 (ln (length number))
	 (lm 4)
	 (lt 27) (ltc (- lt lcnt))
	 (ld (* (/ (- LT lm lt) 5) 3)) (ldc (- ld lcnt))
	 (lf (- LT lm ln lt ld 8)) (lfc (- lf lcnt))
	 (AR "*") (lfc* (1- lfc)) (asterisk nil)
	 (case-fold-search t)
	 (marks (make-string lm SP))
	 (i 0) (N (length privacy))
	 ctm ctp)

    (if (string= (capitalize mew-ct-txt) ct)
	(if char
	    (setq ct (concat ct "(" char ")"))
	  (if dec
	      (setq ct (concat ct "(us-ascii)")))
	  (setq ct (concat ct "(guess)"))))
    (if (null privacy)
	(if (null cte)
	    ()
	  (setq cte (downcase cte))
	  (cond
	   ((or (equal cte mew-7bit)
		(equal cte mew-8bit)
		(equal cte mew-bin))
	    ;; no mark
	    )
	   ((equal cte mew-b64) (aset marks 0 ?B))
	   ((equal cte mew-qp)  (aset marks 0 ?Q))
	   ((equal cte mew-xg)  (aset marks 0 ?G))
	   (t                   (aset marks 0 ?X))
	   ))
      (if dec (setq privacy (reverse privacy)))
      (while (< i N)
	(setq ctm (nth 0 (nth i privacy)))
	(setq ctp (nth 1 (nth i privacy)))
	(cond
	 ((string-match "pgp"  ctp) (aset marks (* i 2) ?P))
	 ((string-match "moss" ctp) (aset marks (* i 2) ?M))
	 )
	(cond
	 ((string-match mew-ct-mle ctm) (aset marks (1+ (* i 2)) ?E))
	 ((string-match mew-ct-mls ctm) (aset marks (1+ (* i 2)) ?S))
	 )
	(setq i (1+ i))
	))
    (if (< lm (length marks))
	(setq marks (substring marks 0 lm))
      (setq marks (concat marks (make-string (- lm (length marks)) SP))))
        
    (if (< lt (length ct))
	(setq ct (concat (substring ct 0 ltc) cnt))
      (setq ct (concat ct (make-string (- lt (length ct)) SP))))

    (if (and (not dec) decrypters) (setq cd-or-dec decrypters))
    (if (null cd-or-dec)
	(setq cd-or-dec (make-string ld SP))
      (if (< ld (mew-string-width cd-or-dec))
	  (setq cd-or-dec (concat (mew-substring cd-or-dec ldc) cnt))
	(setq cd-or-dec
	      (concat cd-or-dec 
		      (make-string (- ld (mew-string-width cd-or-dec)) SP)))))
    (cond
     (filename
      (setq file filename))
     ((and file (not (equal file ".")) (not (string-match "/$" file)))
      (setq asterisk t)
      (setq file (concat file AR)))
     )
    (if file
	(if (< lf (mew-string-width file))
	    (if asterisk
		(setq file (concat (mew-substring file lfc*) AR cnt))
	      (setq file (concat (mew-substring file lfc) cnt)))))
    (insert
     (concat
      marks
      (if number (concat space number))
      space space
      ct
      space space
      cd-or-dec
      space space
      file
      "\n"))
    ))

(defun mew-decode-syntax-delete ()
  (if (and (marker-position mew-summary-buffer-beg)
	   (marker-position mew-summary-buffer-end))
      (let ((cbuf (current-buffer)))
	(set-buffer (marker-buffer mew-summary-buffer-beg))
	(if mew-icon-p
	    (progn
	      (mew-syntax-clear-icon-spec)
	      (set-specifier default-toolbar
			     (cons (current-buffer) mew-summary-toolbar))))
	(set-marker mew-summary-buffer-tmp (point))
	(let ((buffer-read-only nil))
	  (delete-region 
	   (marker-position mew-summary-buffer-beg)
	   (marker-position mew-summary-buffer-end)))
	(set-marker mew-summary-buffer-beg nil)
	(set-marker mew-summary-buffer-end nil)
	(goto-char (marker-position mew-summary-buffer-tmp))
	(set-buffer-modified-p nil)
	(set-buffer cbuf))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; icon spec
;;

(defvar mew-syntax-icon-spec nil)

(defun mew-syntax-set-icon-spec (msg part ct cd icon func)
  (if mew-icon-p
      (setq mew-syntax-icon-spec 
	    (cons
	     (vector icon func t
		     (format "%s <%s> (%s) %s" msg (or part "top") ct cd))
	     mew-syntax-icon-spec))))

(defun mew-syntax-clear-icon-spec ()
  (setq mew-syntax-icon-spec nil))

(defun mew-syntax-get-icon-spec ()
  (nreverse mew-syntax-icon-spec))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; decode privacy
;;

(defvar mew-decode-syntax-privacy-result nil)

(defun mew-decode-syntax-set-privacy (syntax label)
  (let ((privacy (mew-syntax-get-privacy syntax))
	results)
    (while privacy
      (setq results (concat results (nth 2 (car privacy))))
      (setq privacy (cdr privacy)))
    (if results
	(setq mew-decode-syntax-privacy-result
	      (concat mew-decode-syntax-privacy-result
		      mew-x-mew:
		      (format " <%s> " label)
		      results
		      "\n")))))

(defun mew-decode-syntax-clear-privacy ()
  (setq mew-decode-syntax-privacy-result nil))

(defun mew-decode-syntax-insert-privacy ()
  (if mew-decode-syntax-privacy-result
      (insert mew-decode-syntax-privacy-result)))

(provide 'mew-syntax)

;;; Copyright Notice:

;; Copyright (C) 1996, 1997, 1998 Mew developing team.
;; All rights reserved.

;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions
;; are met:
;; 
;; 1. Redistributions of source code must retain the above copyright
;;    notice, this list of conditions and the following disclaimer.
;; 2. Redistributions in binary form must reproduce the above copyright
;;    notice, this list of conditions and the following disclaimer in the
;;    documentation and/or other materials provided with the distribution.
;; 3. All advertising materials mentioning features or use of this software
;;    must display the following acknowledgement:
;;       This product includes software developed by 
;;       Mew developing team and its contributors.
;; 4. Neither the name of the team nor the names of its contributors
;;    may be used to endorse or promote products derived from this software
;;    without specific prior written permission.
;; 
;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
;; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

;;; mew-syntax.el ends here
