 (ns sormilla.gui
-  (:import [java.awt Color Graphics2D]
+  (:require [clojure.java.io :as io])
+  (:import [java.awt Canvas Color Graphics2D Font]
            [java.awt.geom Ellipse2D$Double]
            [javax.swing JFrame JComponent]))
 
 (set! *warn-on-reflection* true)
+
+(def cutive (with-open [in (io/input-stream (io/resource "CutiveMono-Regular.ttf"))]
+              (Font/createFont Font/TRUETYPE_FONT in)))
 
 (defn ->safe [throttle f]
   (fn [& args]

  (defn r [^Graphics2D g ^long w ^long h data]
    (.setColor g Color/DARK_GRAY)
    (.fillRect g 0 0 w h)
    (let [s (min (/ w 1000.0) (/ h 1000.0))]
      (.translate g (/ w 2.0) (/ h 2.0))
      (.scale g s s))
    (doseq [[cx cy r ^Color c] data]
      (let [d (* 2 r)
          x (- cx r)
          y (- cy r)]
        (.setColor g c)
        (.fill g (Ellipse2D$Double. (double x) (double y) (double d) (double d))))))
  
  (defn s []
    [[0 0 10 Color/GREEN]
     [-400 -400 50 Color/RED]
     [400 400 50 Color/BLUE]])
  
  (def f (make-frame #'s #'r))
  (close-frame! f))

(defn make-frame [source render & {:keys [interval safe safe-throttle max-size top exit-on-close] :or {interval 50 safe-throttle 500 max-size true}}]
  (let [run (atom true)
        frame (JFrame.)
        canvas (Canvas.)
        source (if safe (->safe safe-throttle source) source)
        render (if safe (->safe safe-throttle render) render)]
    (if max-size
      (.setExtendedState frame JFrame/MAXIMIZED_BOTH)
      (.setSize frame 800 500))
    (when top
      (.setAlwaysOnTop frame true))
    (when exit-on-close
      (.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE))
    (.setIgnoreRepaint frame true)
    (.setIgnoreRepaint canvas true)
    (.add frame canvas)
    (.pack frame)
    (.setVisible frame true)
    (.createBufferStrategy canvas 2)
    (let [strategy (.getBufferStrategy canvas)]
      (future
        (try
          (while (deref run)
            (let [start (System/currentTimeMillis)
                  data (source)]
              (when data
                (loop [contents-lost? true]
                  (loop [restored? true]
                    (let [g (.getDrawGraphics strategy)]
                      (render g (.getWidth canvas) (.getHeight canvas) data)
                      (.dispose g))
                    (when (.contentsRestored strategy) (recur true)))
                  (.show strategy)
                  (when (.contentsLost strategy) (recur true))))
              (let [time-left (- (System/currentTimeMillis) start interval)]
                #_(println "time-left:" time-left interval)
                (when (pos? time-left)
                  (Thread/sleep time-left)))))
          (catch Throwable e
            (println "Oh shit!" e)
            (throw e))))
