                                        (str "Failed to remove hyphenation pattern: " details)))
                :format :json))
 
+(defn lookup-hyphenation-pattern!
+  [spelling word]
+  (ajax/GET "/api/hyphenate"
+            :params {:word word :spelling spelling}
+            :handler (fn [hyphenated] (do
+                                        (swap! app-state assoc :official-hyphenation hyphenated)
+                                        (swap! app-state assoc :hyphenation hyphenated)))
+            :error-handler (fn [details]
+                             (.warn js/console
+                                    (str "Failed to lookup hyphenation patterns for word: " details)))))
+
 (defn hyphenation-pattern [pattern]
   [:tr
    [:td (:word pattern)]

     {:on-click #(remove-hyphenation-pattern! pattern)}
     [:span.glyphicon.glyphicon-remove {:aria-hidden true}] " Delete"]]])

(defn word-field [val]
  [:div.form-group
   [:label.sr-only {:for "wordInput"} "Word"]
   [:input.form-control
    {:id "wordInput"
     :type "text"
     :placeholder "Word"
     :value @val
     :on-change #(reset! val (-> % .-target .-value))}]])

(defn- hyphenation-valid? [s]
  (and (not (string/blank? s))
       (re-find #"\S-\S" s)))

(defn hyphenation-field [val]
  [:div
   {:class (if (or (string/blank? @val)
                   (hyphenation-valid? @val))
             "form-group" "form-group has-error")}
   [:label.sr-only {:for "hyphenationInput"} "Hyphenation"]
   [:input.form-control
    {:type "text"
     :placeholder "Hyphenation"
     :value @val
     :on-change #(reset! val (-> % .-target .-value))}]])

(defn- hyphenation-add-button
  [word hyphenation]
  [:button.btn.btn-default
   {:on-click #(when (and @word (hyphenation-valid? @hyphenation))
                 (add-hyphenation-pattern! {:word @word :hyphenation @hyphenation :spelling @spelling})
                 (reset! word "")
                 (reset! hyphenation ""))
    :disabled (when (or (string/blank? @word)
                        (not (hyphenation-valid? @hyphenation)))
                "disabled")}
   "Add"])

(defn new-hyphenation []
  (let [word (reagent/atom "")
        hyphenation (reagent/atom "")]
    (fn []
      [:div.form-inline
       [word-field word]
       [hyphenation-field hyphenation]
       [hyphenation-add-button word hyphenation]])))

(defn hyphenation-filter [search]
  [:input.form-control
   {:type "text"
    :placeholder "Search"
    :value @search
    :on-change (fn [e]
                 (reset! search (-> e .-target .-value))
                 (load-hyphenation-patterns! @spelling @search))}])

(defn spelling-filter []
  [:select {:value @spelling
            :on-change (fn [e]
                         (reset! spelling (-> e .-target .-value))
                         (load-hyphenation-patterns! @spelling @search))}
   [:option {:value 0} "Old Spelling"]
   [:option {:value 1} "New Spelling"]])

(defn hyphenation-list []
  [:div.container
   [:h1 "Hyphenation list"]
   [:div.row
    [:div.col-md-6
     [hyphenation-filter search]]
    [:div.col-md-6
     [spelling-filter]]]
    [:div.row
    [:table#hyphenations.table.table-striped
     [:thead [:tr [:th "Word"] [:th "Hyphenation"]]]
     [:tbody
      (for [h (sort-by :word (:hyphenations @app-state))]
        ^{:key (:word h)} [hyphenation-pattern h])]]]
   [:div.row
    [new-hyphenation]]])

;; -------------------------
;; Views

  (reagent/render [current-page] (.getElementById js/document "app")))

(defn init! []
  (load-hyphenation-patterns! @spelling @word)
  (accountant/configure-navigation!
    {:nav-handler
     (fn [path]
