   "Tools for defining and manipulating Android UI elements."
   (:use [neko.activity :only [*activity*]]
         [neko.context :only [*context*]])
+  (:require [clojure.string :as string])
   (:import [android.widget Toast LinearLayout Button]
            [android.view View ViewGroup$LayoutParams]
+           android.widget.LinearLayout$LayoutParams
            android.content.Context))
 
-;; A map that contains the mapping of auxiliary keywords to the most
-;; used constants.
-;;
-(def ^{:private true}
-  attribute-values {;; LinearLayout orientation
-                    :horizontal LinearLayout/HORIZONTAL
-                    :vertical LinearLayout/VERTICAL
-
-                    ;; LayoutParams constants
-                    :fill-parent ViewGroup$LayoutParams/FILL_PARENT
-                    :fill ViewGroup$LayoutParams/FILL_PARENT
-                    :wrap-content ViewGroup$LayoutParams/WRAP_CONTENT
-                    :wrap ViewGroup$LayoutParams/WRAP_CONTENT})
-
 ;; ### Element relations
 
 ;; This section provides utilities to connect the keywords to the
-;; actual UI classes and define the hierarchy relations between the
-;; elements.
+;; actual UI classes, define the hierarchy relations between the
+;; elements and the values for the keywords representing values.
 
 ;; This atom keeps all the relations inside the map.
 (def ^{:private true} keyword-mapping
   (atom {}))
 
-(defn add-keyword-classname-relation
+(defn keyword-add-classname-relation
   "Connects the given keyword to the classname."
   [kw classname]
   (swap! keyword-mapping #(assoc-in % [kw :classname] classname)))

could be either actual values or keywords `:fill` and `:wrap`.

Taken from clj-android by remvee."
  ([both]
    `(let [both# ~(or (attribute-values both)
                                ViewGroup$LayoutParams/WRAP_CONTENT)]
       (new ViewGroup$LayoutParams both# both#)))
  ([width height]
    `(let [width# ~(or (attribute-values width)
                                 ViewGroup$LayoutParams/WRAP_CONTENT)
           height# ~(or (attribute-values height)
                                  ViewGroup$LayoutParams/WRAP_CONTENT)]
       (new ViewGroup$LayoutParams width# height#))))

(defmethod transform-attributes :layout-params [el-type obj attributes
                                                generated-code]
  [(dissoc attributes :layout-width :layout-height)
   (conj generated-code
         `(.setLayoutParams ~obj
                            ~(layout-params (:layout-width attributes)
                                            (:layout-height attributes))))])

;; ### Default attributes


      (mapcat all-parents)
      (concat first-level-parents)
      distinct)))
  
(defn keyword-add-value 
  "Associate the value keyword with the provided value for the given keyword representing the UI element."
  [element-kw value-kw value]
  (swap! keyword-mapping #(assoc-in % [element-kw :values value-kw] value)))

(defn kw-to-static-field
  "Takes a keyword, capitalizes its name and replaces all dashes with underscores."
  [kw]
  (.toUpperCase (string/replace (name kw) \- \_)))

(defn attribute-value
  "If the value is a keyword then returns the value for it from the keyword-mapping. 
If the value-keyword isn't present in the keyword-mapping, form the value as `classname-for-element-kw/CAPITALIZED-VALUE-KW`."
  [element-kw value]
  (if-not (keyword? value)
    value
    (or (-> @keyword-mapping element-kw :values value)
        (symbol (str (.getName (classname element-kw)) \/ (kw-to-static-field value))))))
      
;; These would be moved somewhere at some point.
;;
(do
  (keyword-add-classname-relation :button android.widget.Button)
  (keyword-add-classname-relation :linear-layout android.widget.LinearLayout)
  (keyword-add-classname-relation :layout-params android.view.ViewGroup$LayoutParams)
  (keyword-add-parent :button :layout-params)
  (keyword-add-parent :linear-layout :layout-params)
  (keyword-add-parent :button :id)
  (keyword-add-parent :linear-layout :id)
  (keyword-add-value :layout-params :fill ViewGroup$LayoutParams/FILL_PARENT)
  (keyword-add-value :layout-params :wrap ViewGroup$LayoutParams/WRAP_CONTENT))

;; ## Attributes

