;;; -*- Mode:Common-Lisp; Package:user;fonts: medfnt, hl12b, hl12bi; Base:10 -*-

;;;
;;; Change history:
;;;
;;;  Date      Author	Description
;;; -------------------------------------------------------------------------------------
;;;  6/06/88    TWE	Fixed up so it wouldn't get compiler warning messages.  This also
;;;			made it run to completion without going into the error handler.
;;;			Displays a message telling how to stop the program.  Goes back to
;;;			the original window when the user aborts out.  Added a new
;;;			function CHANGE-VALUE-VIA-MOUSE that allows one to change the
;;;			value of a dial via the mouse.


;;;*********************************************************************************************************** 
;;;
;;;1                         Control  Routines                 *
;;;
;;;***********************************************************************************************************

(defparameter cir-dial nil)
(defparameter horizontal-lineal-dial nil)
(defparameter vertical-lineal-dial nil)
(defparameter sector-dial nil)
(defparameter led-dial nil)
(defparameter dial nil)
(defparameter cycles 0)
(defparameter value 0)

(defun dials-demo ()
  "2Makes window for demo and calls master control program, use this to start demo*"
  (let ((w (make-instance 'w:window :save-bits t :font-map '(fonts:bigfnt)))
        (old-selected-window tv:selected-window))
    (send w :expose)
    (send w :select)
    (send w :set-cursorpos 0 50)
    (send w :string-out-centered "Exit via a CTRL-ABORT")
    (send w :set-cursorpos 0 0)
    (unwind-protect
        (master-control-program)
      ;; Go back to the window we were on.
      (when old-selected-window
        (send old-selected-window :select)))))

(defun master-control-program()
  "2Loops the drawing and sequencing functions until you do a CTRL-ABORT*"
    (draw-dials)
    (simultaneous-movement)
    (one-at-a-time)
    (master-control-program)
    )

(defun draw-dials ()
  "2Calls all the drawing functions of the individual dials*"
  (make-circular-dial)
  (make-horizontal-lineal-dial)
  (make-vertical-lineal-dial)
  (make-sector-dial)
  (make-led-dial))

(defun simultaneous-movement()
  "2Sends updated display value messages to all dial instances simultaneously*"
  (dotimes (count 21 ) 
    (send cir-dial :set-current-value  w:selected-window (* 10 count)) 
    (send horizontal-lineal-dial :set-current-value w:selected-window count)
    (send vertical-lineal-dial :set-current-value w:selected-window count)
    (send sector-dial :set-current-value w:selected-window count)
    (send led-dial :set-current-value w:selected-window count)))
   


(defun one-at-a-time ()
  "2Calls all individual movement routines, controls sequencing of individual dials*" 
  (rotating-circular-dial)                 ; 1Call rotating circular dial routine*
  (setq dial horizontal-lineal-dial)       ; 1set "dial" variable to "horizontal-lineal-dial" *
  (rising-and-falling-dials)               ; 1Call rising and falling dials function*
  (setq dial vertical-lineal-dial)         ; 1change "dial" variable to "vertical-lineal-dial"*
  (rising-and-falling-dials)
  (setq dial sector-dial)                  ; 1change "dial" variable to "sector-dial"*
  (rising-and-falling-dials)
  (counting-led-dial)                      ; 1Call led counting function*
  )



(defun rotating-circular-dial ()
  "Used to control circular dial when rotating individually"
  (dotimes (a 301)
    (send cir-dial :set-current-value w:selected-window a)))


(defun rising-and-falling-dials ()
  "Watches toggling rise and fall functions so that they only toggle 5 times"
  (if (= cycles 5) (setq cycles 0)
      (setq cycles (+ 1 cycles))
      ;;ELSE
      (rise)))

(defun rise()
  "Updates chosen dial from 0 to 20, then calls (fall)"
  (if (= value 20)(fall)
      (setq value (+ value 1))
      (send dial :set-current-value w:selected-window value)
      (rise)))

(defun fall()
  "Updates chosen dial from 20 to 0, then calls rising-and-falling-dials"
  (if (= value 0)(rising-and-falling-dials)
      (setq value (- value 1))
      (send dial :set-current-value w:selected-window value)
      (fall)))

(defun counting-led-dial ()
  "Allows led dial to count from 0 to 100"
  (dotimes ( display 101)
    (send led-dial :set-current-value w:selected-window display)
    ;; This loop kills time so that display does not move too fast .
    (dotimes (kill-time 10000) t)))

;;;***********************************************************************************************************
;;;
;;;                         Make Instance Functions   
;;;
;;;***********************************************************************************************************


(defun make-circular-dial ()
  "makes instance of circular dial and sets values"
  (setf cir-dial (make-instance 'dash:editable-circular-dial-entity))
  (send cir-dial :set-x-center 200)
  (send cir-dial :set-y-center 200)
  (send cir-dial :set-default-hand-width 1)
  (send cir-dial :scale 1.2)
  (send cir-dial :set-up-editable-circular-dial-entity);;makes new values stick
  (send cir-dial :draw w:selected-window))




(defun make-vertical-lineal-dial ()
  (setf vertical-lineal-dial(make-instance 'dash:editable-lineal-dial-entity))
  (send vertical-lineal-dial :set-x-center 800)
  (send vertical-lineal-dial :set-y-center 200)
  (send vertical-lineal-dial :set-max-towards :up)
  (send vertical-lineal-dial :set-max-bar-value 20)
  (send vertical-lineal-dial :set-bar-height 200)
  (send vertical-lineal-dial :set-inverse-video-p :yes)
  (send vertical-lineal-dial :set-up-editable-lineal-dial-entity)
  ;1;(send vertical-lineal-dial :edit-parameters)*;;bypasses given values and prompts with menu
  (send vertical-lineal-dial :draw w:selected-window))
 


(defun make-horizontal-lineal-dial ()
  (setf horizontal-lineal-dial(make-instance 'dash:editable-lineal-dial-entity))
  (send horizontal-lineal-dial :set-x-center 500)
  (send horizontal-lineal-dial :set-y-center 200)
  (send horizontal-lineal-dial :set-max-towards :right)
  (send horizontal-lineal-dial :set-max-bar-value 20)
  (send horizontal-lineal-dial :set-bar-height 200)
  (send horizontal-lineal-dial :set-inverse-video-p :yes)
  (send horizontal-lineal-dial :set-up-editable-lineal-dial-entity)
  ;1;(send horizontal-lineal-dial :edit-parameters)*
  (send horizontal-lineal-dial :draw w:selected-window))


(defun make-sector-dial ()
  (setf sector-dial (make-instance 'dash:editable-sector-dial-entity))
  (send sector-dial :set-x-center 200)
  (send sector-dial :set-y-center 600)
  (send sector-dial :scale 1.2)
  ;1;(send sector-dial :edit-parameters)*
  (send sector-dial :draw w:selected-window))


(defun make-led-dial ()
  (setf led-dial (make-instance 'dash:editable-led-dial-entity))
  (send led-dial :set-x-center 500)
  (send led-dial :set-y-center 550)
  (send led-dial :set-inverse-video-p :yes) 
  ;1;(send led-dial :edit-parameters)*
  (send led-dial :draw w:selected-window))



;;; The following function allows one to change the value of a dial by using
;;; the mouse.  The dial being used is a circular dial, but you should be able
;;; to use something similar with any other type of dial.
(defun change-value-via-mouse ()
  (let* ((w (make-instance 'w:window :save-bits t :font-map '(fonts:bigfnt)
                           :blinker-p nil
                           ;; Use funny window edges to make sure the window coordinates
                           ;; being used are correct.
                           :edges '(100 200 900 700)))
         (circle (make-instance (make-instance 'dash:Editable-Circular-Dial-Entity)))
         (old-selected-window tv:selected-window)
         ;; Make the mouse very responsive when it is inside the dial.
         (inside-sleep-delay 1)
         (outside-sleep-delay 30)
         window-x window-y
         (window-width (send w :width))
         (window-height (send w :height)))
    (multiple-value-setq (window-x window-y)
      (send w :edges))
    (send w :select)
    (send w :set-cursorpos 0 50)
    (send w :string-out-centered "Exit via a CTRL-ABORT")
    (send w :set-cursorpos 0 70)
    (send w :string-out-centered "Move the mouse inside the dial to change the value")
    (send w :set-cursorpos 0 0)
    ;; Center the dial.  The `100' is the size of the dial.  The origin is not really the center
    ;; of the dial, but is the upper left-hand corner.
    (send circle :set-origin (- (truncate window-width 2) 100) (- (truncate window-height 2) 100))
    (send circle :draw w)
    (unwind-protect
        (loop for x = (- w:mouse-x window-x)
              for y = (- w:mouse-y window-y)
              ;; Inside-dial? uses coordinates inside the window.
              when (send circle :inside-dial? x y)
              do (progn
                   ;; The mouse is inside the dial.  Change the value.
                   (send circle :set-current-value w (send circle :convert-window-coordinates-to-dial-value
                                                           ;; Specify `t' to use inside window coordinates.
                                                           w x y t))
                   ;; Let other processes run too, and tell the user where the mouse is.
                   (process-sleep inside-sleep-delay "Inside dial"))
              when (not (send circle :inside-dial? x y))
              do (process-sleep outside-sleep-delay "Outside dial"))
      
      ;; Go back to the window we were on.
      (when old-selected-window
        (send old-selected-window :select)))))


;;;1(defun move-dial (dial-or-gauge x y stop-x stop-y)*
;;;"moves instance of dial on to screen to given location smoothly" 
;;;1 (if (and(= x stop-x)(= y stop-y)) (rotating-circular-dial))*
;;;  1(setq x (+ x 25))*
;;;  1(setq y (+ y 25))*	
;;;  1(send dial-or-gauge :move 25 25)*
;;;  1(send dial-or-gauge :draw w:selected-window)*
;;;  1(send dial-or-gauge :undraw w:selected-window)*
;;;  1(move-dial dial-or-gauge x y stop-x stop-y)*
;;;1 )


