 ;; To fully understand this advanced topic, you'll have to read the tutorials
 ;; and look at the bottom of `db.cljs` for the `:local-store-todos` cofx
 ;; registration.
-(reg-event-fx                 ;; part of the re-frame API
-  :initialise-db              ;; event id being handled
+(reg-event-fx                                               ;; part of the re-frame API
+  :initialise-db                                            ;; event id being handled
 
   ;; the interceptor chain (a vector of 2 interceptors in this case)
-  [(inject-cofx :local-store-todos) ;; gets todos from localstore, and puts value into coeffects arg
-   check-spec-interceptor]          ;; after event handler runs, check app-db for correctness. Does it still match Spec?
+  [(inject-cofx :local-store-todos)                         ;; gets todos from localstore, and puts value into coeffects arg
+   check-spec-interceptor]                                  ;; after event handler runs, check app-db for correctness. Does it still match Spec?
 
   ;; the event handler (function) being registered
-  (fn [{:keys [db local-store-todos]} _]                  ;; take 2 values from coeffects. Ignore event vector itself.
-    {:db (assoc default-db :todos local-store-todos)}))   ;; all hail the new state to be put in app-db
+  (fn [{:keys [db local-store-todos]} _]                    ;; take 2 values from coeffects. Ignore event vector itself.
+    {:db (assoc default-db :todos local-store-todos)}))     ;; all hail the new state to be put in app-db
 
 
 ;; usage:  (dispatch [:set-showing  :active])
 ;; This event is dispatched when the user clicks on one of the 3
 ;; filter buttons at the bottom of the display.
-(reg-event-db      ;; part of the re-frame API
-  :set-showing     ;; event-id
+(reg-event-db                                               ;; part of the re-frame API
+  :set-showing                                              ;; event-id
 
   ;; only one interceptor
-  [check-spec-interceptor]       ;; after event handler runs, check app-db for correctness. Does it still match Spec?
+  [check-spec-interceptor]                                  ;; after event handler runs, check app-db for correctness. Does it still match Spec?
 
   ;; handler
-  (fn [db [_ new-filter-kw]]     ;; new-filter-kw is one of :all, :active or :done
+  (fn [db [_ new-filter-kw]]                                ;; new-filter-kw is one of :all, :active or :done
     (assoc db :showing new-filter-kw)))
 
 ;; NOTE: below is a rewrite of the event handler (above) using a `path` Interceptor

  :toggle-done
  todo-interceptors
  (fn-traced [todos [_ id]]
    (update-in todos [id :done] not)))


(reg-event-db
  :save
  todo-interceptors
  (fn-traced [todos [_ id title]]
    (assoc-in todos [id :title] title)))


(reg-event-db
  :delete-todo
  todo-interceptors
  (fn-traced [todos [_ id]]
    (dissoc todos id)))


(reg-event-db
  :clear-completed
  todo-interceptors
  (fn-traced [todos _]
    (let [done-ids (->> (vals todos)         ;; which todos have a :done of true
                        (filter :done)
                        (map :id))]
      (reduce dissoc todos done-ids))))      ;; delete todos which are done


(reg-event-db
  :complete-all-toggle
  todo-interceptors
  (fn-traced [todos _]
    (let [new-done (not-every? :done (vals todos))]   ;; work out: toggle true or false?
      (reduce #(assoc-in %1 [%2 :done] new-done)
              todos
              (keys todos)))))

;; which manipulate todos.
;; A chain of interceptors is a vector of interceptors.
;; Explanation of the `path` Interceptor is given further below.
(def todo-interceptors [check-spec-interceptor              ;; ensure the spec is still valid  (after)
                        (path :todos)                       ;; the 1st param given to handler will be the value from this path within db
                        ->local-store])                     ;; write todos to localstore  (after)


;; -- Helpers -----------------------------------------------------------------
