;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL -*-


(defvar stdo)

(defun wizard (&optional (interval 240))
  (setf stdo (fdefinition standard-output))
  
  (let* ((buffer (tv:kbd-get-io-buffer))
	 (plist (if (null buffer)
		    (ferror nil "No buffer for kbd.")
		  (locf (tv:io-buffer-plist buffer))))
	 (sync tv:kbd-intercepted-characters)
	 (global tv:kbd-global-asynchronous-characters)
	 (async (contents plist)))
    
    (setf tv:kbd-intercepted-characters nil)
    (setf tv:kbd-global-asynchronous-characters nil)
    (setf (get plist :asynchronous-characters) `((,(char-int #\c-m-abort) tv:kbd-asynchronous-intercept-character
						  (:name "Luse" :priority 50.)
						  user:luse)))
    
    (fdefine 'tv:mouse-overseer
	     #'(lambda ()
		 (process-wait "Wedged" #'(lambda () nil)))
	     t t)
    (send tv:mouse-process :kill)
    
    (43display "In use by an arcane wizard ...")
    
    (unwind-protect (prog nil
		       loop
			  (process-wait "Wizard Lock"
					#'(lambda () (and (tv:key-state (char-int #\space))
							  (tv:key-state (char-int #\rubout)))))
			  (send stdo :clear-input)
			  (process-sleep interval "Wizard Lock")
			  (when (send stdo :any-tyi-no-hang) (go loop)))
      
      (setf tv:kbd-intercepted-characters sync)
      (setf tv:kbd-global-asynchronous-characters global)
      (setf (contents plist) async)
      (undefun 'tv:mouse-overseer)
      (tv:mouse-initialize)
      (send terminal-io :clear-input)
      (send standard-output :clear-screen))))



(defun luse (&rest ignore)
  (43display "You luse." stdo)
  (process-sleep 60 "Luse!")
  (43display "In use by an arcane wizard ..." stdo))



(defun 43display (string &optional (stream standard-output))
  (let (left top right bottom)
    (multiple-value-setq (left top right bottom) (send stream :inside-edges))
    (send stream :clear-screen)
    (send stream :string-out-x-y-centered-explicit
	  string
	  left top right bottom
	  fonts:43vxms)))