;;; GNU Emacs code converted from Mocklisp
(require 'mlsupport)

;Stuff to save/resume emacs EXACTLY where it was left off, including, in
;particular, the exact position and size of windows.

;The save end.
(ml-defun 
    (save-state s n p f nf cur-top cur-dot cur-mark save-file
	(setq save-file (ml-arg 1 "Save state on file: "))
	(temp-switch-to-buffer save-file) ;See if buf of same name as selected
	(ml-if (> (ml-buffer-size) 0)		;save-file is around.
	    (ml-if (/=			;Ask appro ques if so.
		    (read-string 
			"A buffer of that name exists.  Proceed anyway? ")
		    "y")
		(error "Aborted.")
	    )
	)
	(switch-back-from-temp-buffer)
	(setq s (point-marker))
	(error-occured (kill-buffer "save-state"))
	(error-occured (kill-buffer save-file))
	(setq p (current-window-position))
	(while (not (zerop (/= (current-window-position) 1)))
	       (ml-next-window))
	(setq n (number-of-windows))
	(append-string-to-buffer
	    (concat (int-to-string n) " ") "save-state")
	(append-string-to-buffer 
	    (concat (int-to-string p) "\n") "save-state")
	;(save-excursion 
	     ;(exchange-dot-and-mark)
	     ;(message "mark=" (my-dot)) (sit-for 20))
	(while (not (zerop (>= (setq n (- n 1)) 0)))	;For each window.
	       (ml-if (= (setq f (buffer-file-name)) "")
		   (ml-if (= (read-string 
			      (concat "Save buffer "
				      (buffer-name)
				      " in file of that name? "))
			  "y")
		       (progn 
			      (write-file
				  (buffer-name))
			      (setq f (buffer-file-name))
		       )
		       (setq nf		;Lack of leading path name will
			     (concat "/"; signal buf w/ no file.
				     (buffer-name)))
		   )
	       )
	       (ml-if (/= f "")
		   (progn 
			  (setq cur-dot (my-dot));save up here befor too late.
			  (append-string-to-buffer f "save-state")
			  
			  ;Save exact pos of top of window.
			  (save-excursion
			      (beginning-of-window)
			      (setq cur-top (my-dot))
			      (append-string-to-buffer
				  (concat " " (int-to-string cur-top)) "save-state")
			  )
			  
			  ;Save current dot.
			  (append-string-to-buffer
			      (concat " " (int-to-string cur-dot)) "save-state")
			  
			  ;Save current mark, if any.
			  (save-excursion
			      (ml-if (error-occured 
				      (exchange-point-and-mark))
				  (setq cur-mark 0)
				  (setq cur-mark (my-dot))
			      )
			  )
			  (append-string-to-buffer
			      (concat " " (int-to-string cur-mark)) "save-state")
		   )
		   (progn 		;Buf w/ no file.
		       ;See how nf is set above.
		       (append-string-to-buffer nf "save-state")
		       (append-string-to-buffer " 0" "save-state")
		       (append-string-to-buffer " 0" "save-state")
		       (append-string-to-buffer " 0" "save-state")
		   )
	       )
	       ;Save size of this window.
	       (append-string-to-buffer 
		   (concat " " (int-to-string (window-height)) "\n") "save-state")
	       (ml-next-window)		;Move on to next window on screen.
	)
	
	;Save the whole shabang on the appro file.
	(write-buffer-to-file "save-state" save-file)
	(kill-buffer "save-state")
	(pop-to-buffer s)		;Restore cursor just in case we
	; arent really exitting.
	(novalue)
    )
)

;The restore end.
(ml-defun 
    ;Debugging note:  declare-global the local vars to see what goes on.
    (restore-state ps num-of-windows cur-window-position
	file buf this-window top-dot cur-dot cur-mark wh restore-file
	(setq restore-file (ml-arg 1 "Restore state from file: "))
	(setq ps pop-up-windows)
	(setq pop-up-windows 0)
	(find-file restore-file)
	(beginning-of-buffer)
	(setq num-of-windows (word-to-string))
	(setq cur-window-position (next-word-to-string))
	(null-screen)
	(while (not (zerop (>= (setq num-of-windows (- num-of-windows 1)) 0)))
	       ;(if (!= (get-tty-string "before switch to .emacs_save") "y")
		    ;(error-message "stop"))
	       (switch-to-buffer restore-file)
	       (ml-next-line) (beginning-of-line);Move to next file info line.
	       (set-mark-command)
	       (end-of-line)		;Find end of filename.  Note that
	       (ml-provide-prefix-argument ; (search-forward " ") didn`t work
		   4			; when filename contained blanks
		   (backward-word 1))	; (e.g., "Error log").
	       (backward-character)	;Jitter to exact spot.
	       (setq file (region-to-string));Pick up file name.
	       (set-mark-command)		;Mark end of file name
	       (ml-if (error-occured 	;Dont know if this could happen,
		       (ml-search-backward "/")) ; but I`ll chk just in case.
		   (error 
		       (concat
			      "Bad file name in "
			      restore-file)
		   )
	       )
	       (ml-if (bolp)		;No path prefix means this is buf
		   (setq file "")	; w/ no file.  Recall that save-state
	       )			; puts leading / in for this purpose.
	       (forward-character)	;Jitter.
	       (setq buf (region-to-string));Get buf name.
	       (ml-search-forward " ")	;
	       
	       (end-of-line)		;Line up for next
	       (ml-provide-prefix-argument ; next-word-to-string.
		   4			;Again,
		   (backward-word 1))	; (search-forward " ") doesn`t work.
	       (backward-character)	;Jitter.
	       ;Get rest of the goodies.
	       (setq top-dot (next-word-to-string))
	       (setq cur-dot (next-word-to-string))
	       (setq cur-mark (next-word-to-string))
	       (setq wh (next-word-to-string))
	       
	       (setq this-window	;Note what window we`re now in.
		     (current-window-position))
	       (ml-if (/= file "")		;Hedge for no-file-w/-buf case.
		   (find-file file)	; Visit next file
		   (switch-to-buffer 	; or switch to fileless buf.
		       buf)
	       )
	       ;(if (!= (get-tty-string "Cont? ") "y")
		    ;(error-message "stop"))
	       (ml-if (/= this-window	;If window pos has changed, then
		       (current-window-position)); this file must be
		   (progn 	    ; in > 1 buf -- go back to window,
		       (while (not (zerop (/= this-window
				  (current-window-position))))
			      (ml-next-window)
		       )
		       (switch-to-buffer; and switch to appro buffer.
			   buf)
		   )		    ;Now one sees we need both buf and
	       )		    ; file names when > 1 buf for a file.
	       
	       (ml-if (> num-of-windows 0)	;For all but last window,
		   (progn 		; make a new window below.
		       (switch-to-buffer-in-window "1" "null")
		       (ml-previous-window)  ;Shrink new window
		       ;(if (!= (get-tty-string
				    ;(concat "wh=" (int-to-string wh)))
				;"y")
			    ;(error-message "stop2"))
		       (while (not (zerop (> (window-height) wh))) ; as appro.
			      (shrink-window)
		       )
		   )
	       )
	       
	       ;Restore mark.
	       (save-excursion
		   (ml-if (/= cur-mark 0)
		       (progn 
			      (goto-char cur-mark)
			      (set-mark-command)
		       )
		   )
	       )
	       
	       ;Restore exact top of window position.
	       (goto-char top-dot)
	       (line-to-top-of-window)
	       (goto-char cur-dot)	;Restore exact dot position.
	       (error-occured		;On w/ the show.  Err chk in
		   (ml-next-window))	; case only 1 window total.
	       ;(error-message "stop")
	       ;CANT GET FUCKING MESSAGE OUT HERE.
	       ;(message "stuff = " top-dot " " cur-dot " " cur-mark " " wh)
	       ;(if (!= (get-tty-string "end of main loop") "y")
		    ;(error-message "stop"))
	)
	(while (not (zerop (/= cur-window-position (current-window-position))))
	       (ml-next-window))		;Restore cursor to orig window.
	(setq pop-up-windows ps)
	(novalue)
    )
)


(ml-defun 
    (append-string-to-buffer cb cd td
	(temp-switch-to-buffer (ml-arg 2 "Append string to buffer: "))
	(end-of-buffer)
	(insert-string (ml-arg 1 "string: "))
	(switch-back-from-temp-buffer)
    )
)


(ml-defun 
    (write-buffer-to-file bn fn
	(temp-switch-to-buffer
	    (setq bn (ml-arg 1 "Write to file from buffer: ")))
	(write-file 
	    (ml-if (/= (setq fn (ml-arg 2 "file name: ")) "")
		fn
		bn
	    )
	)
	(switch-back-from-temp-buffer)
    )
)


(ml-defun (ml-foo 
 (declare-global &cur-buffer-name &cur-top-of-window &cur-dot &cur-mark)))

(ml-foo)



(ml-defun 
    (temp-switch-to-buffer
	(setq &cur-buffer-name (buffer-name))
	(setq &cur-dot (my-dot))
	(beginning-of-window)
	(setq &cur-top-of-window (my-dot))
	(save-excursion 
	    (ml-if (error-occured 		;in case no mark set.
		    (exchange-point-and-mark))
		(setq &cur-mark 0)
		(setq &cur-mark (my-dot))
	    )
	)
	(switch-to-buffer (ml-arg 1 "Temp switch to buffer: "))
    )
)

(ml-defun 
    (switch-back-from-temp-buffer
	(switch-to-buffer &cur-buffer-name)
	(ml-if (/= &cur-mark 0)
	    (progn 
		   (goto-char &cur-mark)
		   (set-mark-command)
	    )
	)
	(goto-char &cur-top-of-window)
	(line-to-top-of-window)
	(goto-char &cur-dot)
    )
)

(ml-defun 
    (word-to-string s
	(save-excursion 
	    (error-occured (ml-re-search-backward "\\W"));in case a beg of buf.
	    (forward-word 1)
	    (set-mark-command)
	    (backward-word 1)
	    (setq s (region-to-string))
	)
	s
    )
)

(ml-defun 
    (next-word
	(ml-re-search-forward "\\W")
	(forward-word 1)
	(backward-word 1)
    )
)

(ml-defun 
    (next-word-to-string
	(next-word)
	(word-to-string)
    )
)