 
 ;;; Board functions
 
-(defn init-board! [board width height]
-  (let [state (->> (repeat width :empty)
-                   vec
-                   (repeat height)
-                   vec)]
-    (reset! board state)))
-
-(defn change-cell-in-board! [board x y new-state]
-  (swap! board assoc-in [y x] new-state))
-
-(defn update-region-of-board! [board [from-x from-y] [to-x to-y] new-state]
+(defn init-board [width height]
+  (->> (repeat width :empty)
+       vec
+       (repeat height)
+       vec))
+
+(defn change-cell-in-board [board x y new-state]
+  (assoc-in board [y x] new-state))
+
+(defn update-region-of-board [board [from-x from-y] [to-x to-y] new-state]
   (let [cells-to-change (for [x (range-inc from-x to-x)
                               y (range-inc from-y to-y)]
                           [y x])
-        new-board (reduce #(assoc-in %1 %2 new-state) @board cells-to-change)]
-    (reset! board new-board)))
+        new-board (reduce #(assoc-in %1 %2 new-state) board cells-to-change)]
+    new-board))
 
 (defn pad [nums beg end value]
   (vec (concat (repeat beg value)

;  [:tr [:td]        [:td#.num 2] [:td#.cell.c0.r2] [:td#.cell.c1.r2] [:td#.cell.c2.r2] [:td#.cell.c3.r2]]
;  [:tr [:td]        [:td#.num 4] [:td#.cell.c0.r3] [:td#.cell.c1.r3] [:td#.cell.c2.r3] [:td#.cell.c3.r3]]])

(def current-fill-style (atom nil)) ;one of [:empty :crossed :filled nil]

(def board (atom nil))

(def drag-type (atom :rect)) ; possible values :rect, :by-one

(defn range-inc [a b]
  (range (min a b) (inc (max a b))))


             :mouseup (add-event :mouseup)
             :mouseleave (add-event :mouseleave))
    (listen! [(sel1 :#puzzle-table) :.num]
             :mousedown (add-event :number-click)
             :contextmenu disable-context-menu)
    (listen! (sel1 :#button-done) :click (add-event :done))
    (listen! (sel1 :#button-clear) :click (add-event :clear))))

(defn handle-cell-events [event-chan initial-state]
  (go-loop
   [[evt event-type] (<! event-chan)
    state initial-state]
   (let [new-state (case event-type
                     :mousedown (handle-mouse-down-on-cell evt state)
                     :contextmenu (disable-context-menu evt)
                     :mouseenter (handle-mouse-enter-on-cell evt state)
                     :mouseup (stop-dragging initial-state state)
                     :mouseleave (stop-dragging initial-state state)
                     :number-click (handle-number-click evt)
                     :done (if (done-handler evt) initial-state state)
                     :clear (do (clear-puzzle) initial-state)
                     (do (log (str "Unknown event: " event-type)) state))]
     (recur (<! event-chan) new-state))))

(defn show [nono]
  (dommy/replace! (sel1 :#puzzle-table) (create-template nono))
  (let [event-chan (chan 5)]
    (add-handlers event-chan)
    (handle-cell-events event-chan
                        {:fill-style nil
                         :base-cell nil
                         :last-cell nil
                         :drag-type :rect
                         :board (init-board (count (:top nono)) (count (:left nono)))}))
  (show-view :puzzle))

(defn ^:export init []
