   [f ^ints array idx]
   (let [v (aget array idx)]
     (aset array idx ^int (f v))))
-
-(def ainc! (partial array-mutate! inc))
-(def adec! (partial array-mutate! dec))
 
 (defmacro amap!
   "Mutating version of amap"

(ns clojure2d.utils
  (:require [clojure.string :as s]
            [clojure2d.math :as m]))

(set! *warn-on-reflection* true)
(set! *unchecked-math* true)

(defn repeat-val
  "Repeats given value num times and return String"
  [v cnt]
  (s/join (repeat cnt v)))

(defn pad-left
  "Pad string with given char(s)"
  ([string cnt]
   (pad-left string cnt \space))
  ([string cnt padchr]
   (let [c (count string)]
     (if (< c cnt)
       (str (repeat-val padchr (- cnt c)) string)
       string))))

(defn to-hex
  "return hex value of given number, padded with leading zeroes if given length"
  ([n]
   (s/upper-case 
    (cond 
      (instance? Byte n) (Integer/toHexString (unchecked-byte n))
      (instance? Integer n) (Integer/toHexString (unchecked-int n))
      :else (Long/toHexString (unchecked-long n)))))
  ([n pad]
   (pad-left (to-hex n) pad \0)))

(defmacro time-with-name
  "Evaluates expr and prints the time it took.  Returns the value of

  (let [tick (atom (dec v))]
    #(swap! tick inc)))

(defn make-session-name
  ""
  ([]
   (let [^java.text.SimpleDateFormat sdf (java.text.SimpleDateFormat. "yyyyMMddHHmmss")
         date (java.util.Date.)]
     [(.format sdf date) (to-hex (hash date))])))

(def ^:dynamic *log-to-file* false)

(let [session-name (atom nil) ; store session name as a current date
      session-file (agent nil) ; logger Writer, created and used when *log-to-file* is true
      session-cnt (atom nil) ; counter for next filename fn
      ^java.text.SimpleDateFormat sdf (java.text.SimpleDateFormat. "yyyy-MM-dd HH:mm:ss")
      nilfn (fn [_] nil)]

  (defn close-session
    ""
    []
    (when-not (nil? @session-file)
      (send session-file (fn [^java.io.Writer o]
                           (.flush o)
                           (.close o)
                           nil)))
    (swap! session-name nilfn)
    (swap! session-cnt nilfn))

  (defn make-session
    ""
    []
    (let [nname (make-session-name)]
      (swap! session-name (fn [_] nname))

      (when *log-to-file*
        (let [fname (str "log/" (first nname) ".log")]
          (io/make-parents fname)
          (send session-file (fn [^java.io.Writer o]
                               (do
                                 (when-not (nil? o)
                                   (.flush o)
                                   (.close o))
                                 (let [^java.io.Writer no (io/writer fname :append true)]
                                   (.write no (str "Session id: " (second nname) "\n"))
                                   no))))))

      (swap! session-cnt (fn [_] (make-counter 0)))))

  (defn log
    ""
    [s]
    (when *log-to-file*
      (if (nil? @session-file)
        (do
          (make-session)
          (log s))
        (let [to-log (str (.format sdf (java.util.Date.)) ": " s "\n")]
          (send session-file (fn [^java.io.Writer o]
                               (.write o to-log)
                               (.flush o)
                               o)))))
    true)

  (defn next-filename
    ""
    [prefix]
    (if (nil? @session-name)
      (do
        (make-session)
        (next-filename prefix))
      (str prefix (second @session-name) "_" (format "%06d" (@session-cnt)))))

  (defn get-session-name
    ""
    []
    @session-name)


)
