;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Copyright (c) 1993 by William M. Perry (wmperry@indiana.edu)	    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Support for HTTP/1.0 MIME Type                                          ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'w3)

(defvar w3-mime-accept-string nil
  "String to send to the server in the Accept: field")

(defvar w3-mime-viewers
  '(
    ("application" . (
		      ("postscript" . "ghostview %s")
		      ("dvi"        . "xdvi %s")
		      ("latex"      . "latex %s ; xdvi %s")
		      ("tex"        . "tex %s ; xdvi %s")
		      ("texinfo"    . "??? %s")
		      ("x-rtf"      . "??? %s")
		      ))
    ("audio"       . (
		      ("x-aiff"     . "??? %s")
		      ("basic"      . "play %s")
		      ))
    ("image"       . (
		      ("x-cave"     . "??? %s")
		      ("x11-dump"   . "xwud -in %s")
		      ("windowdump" . "xwud -in %s")
		      ("x-elvm"     . "??? %s")
		      ("gif\\|jpeg\\|portable-bitmap\\|portable-graymap\\|portable-pixmap\\|x-tiff\\|xbitmap"
		       "xv -perfect %s")
		      ("x-rgb"      . "??? %s")
		      ("cmu-raster" . "??? %s")
		      ))
    ("text"        . (
;		      ("html"       . w3-prepare-buffer)
		      ("setext"     . "??? %s")
		      ("plain"      . text-mode)
		      ))
    ("video"       . (
		      ("x-movie"    . "??? %s")
		      ("mpeg"       . "mpeg_play %s")
		      ))
    ("archive"     . (
		      ("tar"        . tar-mode)
;		      ("shar"       . w3-undo-shar)
		      ))
    )
  "*An assoc list containing mime content headers and how to view them.
Format is: '( (\"toplevelencoding\" . ( (\"minor encoding\" . \"how\") ...)))
The \"how\" can be either a string suitable for a (format ...) command, or
a lisp symbol specifying a function to call.

The \"minor\" encoding may be a regular expression - it is passed through
string-match.")

(defvar w3-mime-encodings
  '(
    ("x-uuencode"    . "uudecode")
    ("x-hqx"         . "mcvert")
    ("x-zip"         . "gunzip")
    ("x-compress"    . "uncompress")
    )
  "*An assoc list of mime content-encoding fields and the commands to
uncompress them.")

(defun w3-mime-viewer (encoding)
  "Get the mime viewer command for ENCODING, return nil if none found.
Expects an argument like text/html, or application/dvi"
  (string-match "/" encoding)
  (let* ((major (substring encoding 0 (match-beginning 0)))
	 (minor (substring encoding (1+ (match-beginning 0)) nil))
	 (alist (cdr-safe (assoc major w3-mime-viewers)))
	 (viewr nil))
    (if alist
	(progn
	  (setq viewr (car (cdr-safe (w3-in-assoc minor alist))))))
    viewr))

(defun w3-parse-viewer-types ()
  "Create a string usable for an Accept: header from w3-mime-viewers"
  (let ((tmp w3-mime-viewers)
	(tp1 nil)
	(tp2 nil)
	(str "")
	(mjr nil)
	(mnr nil))
    (while tmp
      (setq mnr (cdr (car tmp))
	    mjr (car (car tmp))
	    tmp (cdr tmp))
      (while mnr
	(setq tp1 (car (car mnr))
	      mnr (cdr mnr))
	(while (string-match (regexp-quote "\\|") tp1)
	  (setq tp2 (substring tp1 0 (match-beginning 0))
		tp1 (substring tp1 (match-end 0) nil)
		str (format "%s\r\nAccept: %s/%s" str mjr tp2)))
	(setq str (format "%s\r\nAccept: %s/%s"  str mjr tp1))))
    (substring str 1 nil)))
              
(defun w3-create-mime-request (url ref-url)
  "Create a MIME request for URL, referred to by REF-URL"
  (if (and w3-use-http2
	   (not (w3-member w3-current-server w3-bad-server-list)))
      (let ((request
	     (format
	      (concat
	       "GET %s HTTP/1.0\r\nFrom: %s@%s\r\n"
	       "Accept-encoding: x-compress; x-zip\r"
	       "%s\r\nUser-Agent: Emacs-W3/%s\r\n\r\n\n")
	      url
	      (user-real-login-name)
	      (system-name)
	      w3-mime-accept-string
	      w3-version-number
	      ref-url)))
	request)
    (format "GET %s\r\n" url)))

(defun w3-parse-mime-headers ()
  "Parse mime headers and remove them from the html"
  (set-buffer " *W3*")
  (let* ((st (point-min))
	 (nd (progn
	       (goto-char (point-min))
	       (re-search-forward "^\r*$" nil t)
	       (1+ (point))))
	 (hdrs (buffer-substring st nd)))
    (delete-region st nd)
    (let (type
	  encoding
	  viewr
	  status
	  statusmsg
	  server)
      (if (string-match "^Content-encoding: +\\([^\\\r]*\\)\\\r*$" hdrs)
	  (setq encoding (substring hdrs (match-beginning 1) (match-end 1))))
      (if (string-match "^Content-type: +\\([^\\\r]*\\)\\\r*$" hdrs)
	  (setq type (substring hdrs (match-beginning 1) (match-end 1))))
      (if (string-match "^Server: +\\([^\\\r]*\\)\\\r*$" hdrs)
	  (setq server (substring hdrs (match-beginning 1) (match-end 1))))
      (if (string-match "^HTTP.+ \\([0-9]+\\) *\\([^\\\r]*\\)\\\r*$" hdrs)
	  (setq status (string-to-int
			(substring hdrs (match-beginning 1) (match-end 1)))
		statusmsg (substring hdrs (match-beginning 2) (match-end 2))))
      (setq viewr (w3-mime-viewer type))
      (setq w3-current-mime-type type
	    w3-current-mime-encoding encoding
	    w3-current-mime-viewer viewr
	    w3-current-mime-server-type server))))

(defun w3-is-mime-response ()
  "Determine if the current buffer is a MIME response"
  (set-buffer " *W3*")
  (let* ((st (point-min))
	 (nd (progn
	       (goto-char (point-min))
	       (re-search-forward "^\r*$" nil t)
	       (if (not (eobp)) (1+ (point)) (point))))
	 (hdrs (buffer-substring st nd)))
    (and (string-match "^HTTP/.+" hdrs)
	 (equal w3-current-type "http")
	 (string-match "^MIME-version:.*" hdrs))))    

(or w3-mime-accept-string (setq w3-mime-accept-string (w3-parse-viewer-types)))

(provide 'w3-mime)
