 (def corePop-memo (memoize #(core popNextImage)))
 
 (defn acquire-and-write-to-disk [num-images]
-  (let [filename (str "E:/acquisition/deleteMe" (rand-int 100000) ".dat")]
-    (println filename)
-    ;(run-sequence-acquisition num-images false)
+  (let [filename (str "D:/AcquisitionData/deleteMe" (rand-int 100000) ".dat")]
+    (println "\nto disk:" filename)
     (with-open [file (RandomAccessFile. filename "rw")]
                (time (let [channel (.getChannel file)
                            image-queue (queuify num-images 5 #(core getImage))

           (java.nio.channels FileChannel$MapMode))
  (:require [org.micromanager.mm :as mm])
  (:use [org.micromanager.mm :only (core)]))

;; bucket brigade

(defn bucket-node [input-queue function output-queue]
  (future
    (loop []
      (let [item (.take input-queue)]
        (if (= item input-queue)
          (.put output-queue output-queue)
          (do (.put output-queue (function item))
              (recur)))))))

(defn first-node [n function output-queue]
  (future
    (dotimes [i n]
      (.put output-queue (function)))
    (.put output-queue output-queue)))

(defn last-node [input-queue function]
  (loop []
    (let [item (.take input-queue)]
      (when (not= item input-queue)
        (function item)
        (recur)))))
        

(defn bucket-brigade [n & functions]
  (let [first-queue (LinkedBlockingQueue.)
        first-node (first-node n (first functions) first-queue)]
    (loop [remaining-functions (rest functions) input-queue first-queue]
      (let [f (first remaining-functions)]
        (if-let [n (next remaining-functions)]
          (let [output-queue (LinkedBlockingQueue.)]
            (bucket-node input-queue f output-queue)
            (recur n output-queue))
          (last-node input-queue f))))))

(defn queuify
  "Runs zero-arg function n times on another thread. Returns

                       (dotimes [_ num-images]
                         (write-buf channel (.take filled-buffer-queue))))))))


(defn write-test [num-images]
  (let [filename (str "D:/AcquisitionData/deleteMe" (rand-int 100000) ".dat")
        buf (image-to-byte-buffer (core getImage) (byte-buffer (* 2 n)))]
    (println "\nparallel:" filename)
    (with-open [file (RandomAccessFile. filename "rw")]
               (time (let [channel (.getChannel file)]
                       (dotimes [_ num-images]
                         (write-buf channel buf)))))))

(defn acquire-and-write-parallel [num-images]
  (let [filename (str "D:/AcquisitionData/deleteMe" (rand-int 100000) ".dat")]
    (println "\nparallel:" filename)
    (with-open [file (RandomAccessFile. filename "rw")]
               (time (let [channel (.getChannel file)
                           n (count (core getImage))
                           image-queue (queuify num-images 5 #(core getImage))
                           empty-buffer-queue (queuify 10 10 #(byte-buffer (* 2 n)))
                           filled-buffer-queue (queuify num-images 5 #(image-to-byte-buffer
                                                                        (.take image-queue)
                                                                        (.take empty-buffer-queue)))
                           ]
                       ;(println image-queue empty-buffer-queue filled-buffer-queue)
                       (dotimes [_ num-images]
                         (let [buf (.take filled-buffer-queue)]
                           (write-buf channel buf)
                           (.offer empty-buffer-queue buf))))))))
        
  

;; other tests

(defn monitor-circular-buffer []
  (while (not (core isSequenceRunning))
    (Thread/sleep 100))
  (while (core isSequenceRunning)
    (println (core getRemainingImageCount))
    (Thread/sleep 1000)))

(defn drain-queue [blocking-queue]
  (future (loop [i 0]
