 (def source-mode  (cell-mode "source-mode"))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; The Brain
+;; Logic
 
 (defn behavior [message state]
-  (println message state)
   (match message
 
     [[:display xy] :click _]
     (case (:mode state)
 
       :formula
-      (let [formula (write-formula xy state)]
+      (let [formula (str (get-in state [(:focus state) :formula]) xy)]
         [[(source-mode xy)
           (display-mode (:source state))
           [[:edit (:focus state)] :value formula]]

            [om.core :as om :include-macros true]
            [clojure.string :as string]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Helpers

(declare read-formula)

(defn- formula? [s]
  (string? (first (re-matches #"^=.*" s))))

(defn- write-formula [s state]
  (let [formula (get-in state [(:focus state) :formula])]
    (str formula " " s)))

(defn- cell-value [xy state]
  (let [cell (state xy)]
    (if (:formula cell)
      (read-formula (:formula cell) state)
      (:value cell))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Formula interpreter

(def ops {"/" / "*" * "+" + "-" -})

(defn resolve-var [xy env]
  (get-in env [xy :value]))

(defn string->token [s env]
  (or (ops s)
      (let [n (js/parseInt s)]
        (if (integer? n) n (cell-value s env)))))

(defn parse-formula [s env]
  (let [[_ a b c] (string/split s #" ")]
    (map #(string->token % env) (list b a c))))

(defn eval-formula [tokens]
  (apply (first tokens) (rest tokens)))

(defn read-formula [s env]
  (eval-formula (parse-formula s env)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Look and feel


      [[(display-mode xy)
        [[:display xy] :value (cell-value (:focus state) state)]]
       (dissoc state :mode)])

    [[:edit xy] :value v]
    (if (formula? v)
      [[(formula-mode xy)] (assoc state :mode :formula xy {:formula v})]
      [[] (assoc state :mode :value xy {:value v})])

    [[:edit xy] :key-down 13]
    [[(display-mode xy) (display-mode (:source state))]
     (dissoc state :mode :edit :source)]
    
    :else [[] state]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Spec

(defn cell [x y]
  (let [xy (str x y)]
