(ns play-clj-doclet.html
  (:require [clojure.java.io :as io]
            [clojure.string :as string]
            [hiccup.core :refer :all]))

(defn str->filename
  [ns s]
  (-> (or (let [dot-pos (.lastIndexOf ns ".")]
            (when-not (= dot-pos -1)
              (subs ns (+ 1 dot-pos))))
          "core")
      (str "." s)
      (string/replace "?" "_q")
      (string/replace "->" "_")
      (string/replace ">" "_r")
      (string/replace "<" "_l")
      (str ".html")))

(defn sidebar
  [parsed-files]
  [:div {:class "sidebar"}
   (for [{:keys [ns groups] :as pf} parsed-files]
     (cons (when (> (count ns) 0)
             [:div {:class "ns"} ns])
           (for [{:keys [name]} groups]
             [:div {:class "name"}
              [:a {:href (str->filename ns name)}
               name]])))])

(defn java-param
  [[type-name param-name]]
  (html [:span {:class "j-arg"}
         [:span {:class "j-type"} "^" type-name]
         " "
         param-name]))

(defn java-item
  [{:keys [name text type args]}]
  [:div {:class "j-item"}
   [:span {:class "j-name"}
    (str name)]
   [:span {:class "j-args"}
    (string/join ", " (map java-param args))]
   (when text
     [:div {:class "j-doc"} text])])

(defn content
  [{:keys [name docstring arglists java raw raw*]}]
  [:div {:class "content"}
   [:div {:class "item"}
    [:div {:class "clj"}
     (for [args arglists]
       [:div {:class "c-head"} (pr-str args)])
     [:div {:class "c-doc"} docstring]]
    (when (> (count java) 0)
      (list [:div {:class "c-head"} "Options"]
            (for [[item-name {:keys [text items]}] java]
              (list (when (> (count java) 1)
                      [:div {:class "j-text"} text])
                    [:div {:class "java"}
                     (map java-item items)]))))
    [:div {:class "c-head"} "Source"]
    [:div {:class "c-src"}
     (when raw* [:pre raw*])
     [:pre raw]]]])

(defn create-file
  [parsed-files name content]
  (html [:html
         [:head
          [:title name]
          [:link {:rel "stylesheet" :href "highlight.css"}]
          [:link {:rel "stylesheet" :href "main.css"}]]
         [:body
          (sidebar parsed-files)
          content
          [:script {:src "highlight.js"}]
          [:script {:src "main.js"}]]]))

(defn copy-from-res
  [dir file-name]
  (spit (io/file dir file-name)
        (-> file-name io/resource slurp)))

(defn create
  [dir parsed-files]
  (.mkdir (io/file dir))
  (copy-from-res dir "main.css")
  (copy-from-res dir "main.js")
  (copy-from-res dir "highlight.css")
  (copy-from-res dir "highlight.js")
  (doseq [{:keys [ns groups] :as pf} parsed-files]
    (doseq [{:keys [name] :as group} groups]
      (spit (io/file dir (str->filename ns name))
            (create-file parsed-files name (content group)))))
  (spit (io/file dir "index.html")
        (create-file parsed-files "play-clj docs" nil)))
