   (:gen-class))
 
 
-; [TODO] too many atoms
-(def timer (atom nil))
-(def interval (atom nil))
-(def started (atom nil))
-(def in-state (atom nil))
 (def counted (atom 1))
-(def message-id (atom nil))
-
+(def state (atom {:timer      nil
+                  :interval   nil
+                  :started    nil
+                  :mode       nil
+                  :message-id nil}))
 
 
 
 (defn secs [s] (* s 1000))
 (defn mins [m] (* m (secs 60)))
-(def states {:pomodoro {:text #(str "업무로 돌아올 시간입니다! " @counted), :next :relax, :during (mins 5)}
-             :relax    {:text #(str "쉴 시간입니다!"), :next :pomodoro, :during (secs 30)}})
+(def modes {:pomodoro {:text #(str "업무로 돌아올 시간입니다! " @counted), :next :relax, :during (mins 5)}
+            :relax    {:text #(str "쉴 시간입니다!"), :next :pomodoro, :during (secs 30)}})
 
 
 



(defn elapsed-time []
  (- (System/currentTimeMillis) @started))

(defn base-time []
  (:during (@in-state states)))

(defn ms->sec [ms]
  (quot ms 1000))

  (edit-m message id)
  )

(defn session-alive? []
  (nil? (:timer @state)))



(defn send-remaining [byline]
  (if (nil? (:message-id @state))
    (->> (send-m (str "남은 시간은 " (remaining-time) "초"))
         :result
         :message_id
         (swap! state assoc :message-id))
    (edit-message (:message-id @state) (str "남은 시간은 " (remaining-time) "/" (ms->sec (base-time)) "초 by " byline))))



(defn goto-x [key]
  (let [mode (key modes)]
    (send-m ((:text mode)))
    (swap! state assoc :mode key)
    (swap! state assoc :started (System/currentTimeMillis))
    (swap! state assoc :message-id nil)
    (when-not (nil? (:interval @state)) (future-cancel (:interval @state)))
    (swap! state assoc :interval (set-interval #(send-remaining "interval") (secs 10)))
    (when (= key :relax)
      (swap! counted inc))
    (set-timeout #(goto-x (:next mode)) (:during mode))))


;;;; Handlers
(defn timer-start []
  (if (session-alive?)
    (goto-x :pomodoro)
    (send-m "이미 세션이 진행중입니다")))

(defn check-remaining []
  (if-not (session-alive?)
    (send-remaining "manual")
    (send-m "타이머가 돌고 있지 않음")))

(defn cancel-timer []
  (if-not (session-alive?)
    (do
      (future-cancel (:timer @state))
      (future-cancel (:interval @state))
      (swap! state assoc :timer nil)
      (send-m (str (:mode @state) " 취소되었습니다")))
    (send-m "진행중인 태스크가 없습니다")))

(defn count-counted []
