 (ns chessground.data
   "Representation and manipulation of the application data"
   (:require [chessground.common :as common :refer [pp]]
-            [chessground.chess :as chess]))
+            [chessground.chess :as chess]
+            [chessground.schemas :refer [ChessState]]
+            [schema.core :as s :refer [Str Bool]])
+  (:require-macros [schema.macros :as sm :refer [defschema]]))
 
-(def defaults
+(sm/def defaults :- ChessState
   "Default state, overridable by user configuration"
   {:fen nil ; replaced by :chess by data/make
    :chess {} ; representation of a chess game

        (with-fen (:fen config))
        (dissoc :fen))))

(defn clear [state]
  (-> state
      (assoc :chess chess/clear)
      (assoc-in [:movable :dests] nil)))

(defn is-movable? [state key]
  "Piece on this square may be moved somewhere, if the validation allows it"
  (let [owner (chess/owner-color (:chess state) key)
        movable (:movable state)
        color (:color movable)]
    (and owner (or (= color "both") (= color owner)))))

(defn can-move? [state orig dest]
  "The piece on orig can definitely be moved to dest"
  (and (is-movable? state orig)
       (or (-> state :movable :free)
           (common/set-contains? (get-in state [:movable :dests orig]) dest))))

(defn dests-of [state orig]
  "List of destinations square keys for this origin"
  (when (is-movable? state orig)
    (if (-> state :movable :free)
      (for [rank (range 1 9)

   :spare-pieces false ; provide extra pieces to put on the board)
   })


(sm/defn with-fen :- ChessState
  [state :- ChessState
   fen :- Str]
  (assoc state :chess (chess/make fen)))

(sm/defn make :- ChessState
  [js-config :- js/Object]
  (let [config (-> js-config
                   common/keywordize-keys
                   (common/keywordize-keys-in [:movable])
