(ns com.oly.static-sites.do-blog.pages.chess.render
  (:require
   [com.oly.static-sites.do-blog.pages.chess.state :refer [game-state white-square black-square]]
   [com.oly.static-sites.do-blog.pages.chess.movement :refer [fetch-selected-piece-moves]]))

(defn calculate-black-white [pos]
  (if (even? (first pos))
    (if (even? (second pos))
      :black :white)
    (if (even? (second pos))
      :white :black)))

(defn draw-square [pos pieces]
  (let [square (calculate-black-white pos)
        piece (first (filter #(= pos (:start-pos %)) pieces))
        selected-piece-moveable (fetch-selected-piece-moves (first (filter :selected pieces)) @game-state)
        moveable-square (first (filter #(= pos %) selected-piece-moveable))]

    (-> piece (assoc :text (cond
                             (:selected piece) (:character piece) ;"S "
                             piece (:character piece)
                             moveable-square "O "
                             :else (if (= (calculate-black-white pos) :black)
                                     black-square
                                     white-square
                                     )))
        (assoc :colour (if (= square :black)
                         white-square
                         black-square)
               :class (if (= square :black)
                        "black-80"
                        "white-80")))))

(defn draw-board [pieces]
  (loop [x 1
         y 1
         result []]
    (if (>= x 8)
      (if (>= y 8)
        (conj result (draw-square [x y] pieces))
        (recur 1 (+ 1 y) (conj result (draw-square [x y] pieces))))
      (recur (+ 1 x) y (conj result (draw-square [x y] pieces))))))

(defn board-test [size]
  (loop [x-pos 1
         y-pos 1
         result []]
    (if (and (= x-pos size) (= y-pos size))
      result
      (if (= size x-pos)
        (recur 1
               (inc y-pos)
               (conj result [x-pos y-pos]))
        (recur (inc x-pos)
               y-pos
               (conj result [x-pos y-pos]))))))

(defn create-board [size square-defaults]
  (->> (board-test size)
       (mapv #(vector % (square-defaults %)) )
       (into {})))

(defn enhance-board [board on-click-fn]
  (reduce-kv
   (fn [m key square]
     (assoc m key (assoc square :on-click on-click-fn :pos key)))
   {}
   board))

(defn place-pieces-on-board [board pieces on-click-fn]
  (reduce (fn [m piece]
            (let [square-colour (calculate-black-white (:start-pos piece))]
              (assoc m (:start-pos piece)
                     (merge (get m (:start-pos piece))
                            {:text (:character piece)
                             :piece (assoc piece :pos (:start-pos piece))
                             :selected false
                             :colour (:colour piece)
                             :on-click on-click-fn
                             :class (if (= square-colour :white)
                                      (str (if (= :white (:colour piece))
                                             " white "
                                             " black "))

                                      (str (if (= :white (:colour piece)) " white " " black")))}))))
          board
          pieces))
