 ;; 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)
+(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 -----------------------------------------------------------------

  :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)))))

;; So, `path` operates a little like `update-in`
;;
#_(reg-event-db
    :set-showing

    ;; this now a chain of 2 interceptors. Note use of `path`
    [check-spec-interceptor (path :showing)]

    ;; The event handler
    ;; Because of the `path` interceptor above, the 1st parameter to
    ;; the handler below won't be the entire 'db', and instead will
    ;; be the value at the path `[:showing]` within db.
    ;; Equally the value returned will be the new value for that path
    ;; within app-db.
    (fn [old-showing-value [_ new-showing-value]]
      new-showing-value))                                   ;; return new state for the path


;; usage:  (dispatch [:add-todo  "a description string"])
(reg-event-db                                               ;; given the text, create a new todo
  :add-todo

  ;; Use the standard interceptors, defined above, which we
