; a simple pitch slider demo, adapted from
; http://www.csounds.com/journal/2006summer/SliderDemo.html

(import
 '(csnd Csound CsoundPerformanceThread)
 '(javax.swing JFrame JLabel JSlider JButton JPanel BorderFactory)
 '(javax.swing.border EtchedBorder)
 '(javax.swing.event ChangeListener)
 '(java.awt Font Color GridLayout)
 '(java.awt.event ActionListener WindowAdapter))

(defmacro make-button [label & body]
  `(doto (JButton. ~label)
     (.addActionListener 
      (proxy [ActionListener] []
	(actionPerformed ~'[evt] ~@body)))))

(defn slider-demo []
  (let [pitch-slider (JSlider. JSlider/HORIZONTAL 0 2000 200)
	etched-border 
	  (BorderFactory/createEtchedBorder EtchedBorder/LOWERED)
	serif-font (Font. "Serif" Font/BOLD 16)
	csound (Csound.)
	csd-file (surmulot-file ["clojure" "SliderDemo.csd"])
	perf-thread (ref false)
	perf-stop 
	  (fn [] (when @perf-thread
		   (.Stop @perf-thread)
		   (dosync (ref-set perf-thread false))))
	set-pitch-channel 
          (fn [] (.SetChannel csound "pitch" 
			      (double (.getValue pitch-slider))))]
    ;;
    ;; slider specification
    (doto pitch-slider
      (.setMajorTickSpacing 500)
      (.setMinorTickSpacing 1)
      (.setPaintTicks true)
      (.setPaintLabels true)
      (.addChangeListener (proxy [ChangeListener] []
			    (stateChanged [evt] (set-pitch-channel)))))
    ;;
    ;; GUI
    (doto (JFrame.)
      (.setLayout (GridLayout. 3 1))
      (.setTitle "Slider demo")	       
      ;; start/stop/edit panel
      (.add (doto (JPanel.)
	      (.setLayout (GridLayout. 2 2))
	      (.setBorder etched-border)
	      (.add (make-button "Start"
		      (when (and
			     (not @perf-thread)
			     (= 0 (.Compile csound csd-file "-dodac")))
			(dosync 
			 (ref-set perf-thread 
				  (CsoundPerformanceThread. csound)))
			(.Play @perf-thread)
			(set-pitch-channel))))
	      (.add (make-button "Stop" (perf-stop)))
	      (.add (doto (JLabel. "Press Start, then move Slider.")
		      (.setForeground Color/blue)))
	      (.add (make-button "Edit CSD" (emacs-edit-file csd-file)))
	      (.setFont serif-font)))
      ;; slider panel
      (.add (doto (JPanel.)
	      (.setBorder etched-border)
	      (.add (doto (JLabel. "Pitch") 
		      (.setForeground Color/red)))
	      (.setFont serif-font)
	      (.add pitch-slider)))
      ;; big bottom button
      (.add (make-button "Edit the Clojure source code for this demo" 
	      (emacs-edit-file (surmulot-file ["clojure" "SliderDemo.clj"]))))
      ;; finalization
      (.addWindowListener (proxy [WindowAdapter] []
			    (windowClosing [evt] (perf-stop))))
      (.setResizable false)
      (.pack)
      (.setVisible true))))

;(slider-demo)
