 
 (def repl-outputstream
   (atom nil))
+
+(def ui-window
+  "The complete UI panel." (atom nil))
 
 ;;
 

    (make-project-window proj)
    #_(println "Switching project:" proj)))

(defn make-editor-window
    "Make an editor window."
    [params]
    (let [
          textArea (RSyntaxTextArea. 42 115)
          ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
          ;textArea.setCodeFoldingEnabled(true);      
          sp (RTextScrollPane. textArea)
          a-new (action :handler a-new :name "New" :tip "Create a new file.")
          a-open (action :handler a-open :name "Open" :tip "Open a file")
          a-save (action :handler a-save :name "Save" :tip "Save the current file.")
          a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
          a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
          a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
          a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
          a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
          a-eval-file (action :handler a-eval-file :name "Evaluate" :tip "Evaluate the current file.")
          a-projects (map #(action :handler (make-a-active-project %)
                                   :name (str (:group %) "/" (:name %))
                                   :tip (str (:group %) "/" (:name %)))
                          (:projects @current-profile))
          menus (menubar
                  :items [(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
                          (menu :text "Edit" :items [a-copy a-cut a-paste])
                          (menu :text "Run" :items [a-eval-file])
                          (menu :text "Projects" :items (into [] a-projects))
                          (menu :text "Git" :items [])
                          #_(menu :text "My Project" :items [(action :handler (fn [e] nil) :name "Open a project")
                                                            (action :handler (fn [e] nil) :name "in")
                                                            (action :handler (fn [e] nil) :name "projects menu")])])
          f (frame :title "Brevis - Editor Window" :menubar menus)]
      (.setSyntaxEditingStyle textArea (cond (= (:language params) :java) 
                                             (SyntaxConstants/SYNTAX_STYLE_JAVA)
                                             :else
                                             (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
      (.setCodeFoldingEnabled textArea true)      
      (display f sp)
      (-> f pack! show!)
      (.setLocation f 0 0)      
      {:frame f
       :text-area textArea
       :scroll-pane sp
       :menus menus}))

(defn get-repl-inputstream
  "Return the input stream for the REPL."

  []
  @repl-outputstream)

#_(defn make-repl-input-window
     "Make a REPL input window."
     [params]
     (let [textArea (RSyntaxTextArea. 25 115)          
           ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
           ;textArea.setCodeFoldingEnabled(true);      
           sp (RTextScrollPane. textArea)
           a-new (action :handler a-new :name "New" :tip "Create a new file.")
           a-open (action :handler a-open :name "Open" :tip "Open a file")
           a-save (action :handler a-save :name "Save" :tip "Save the current file.")
           a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
           a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
           a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
           a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
           a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
           menus (menubar
                   :items [#_(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
                           (menu :text "Edit" :items [a-copy a-cut a-paste])])
           f (frame :title "Brevis - REPL Input" :menubar menus)]
       (.addKeyListener textArea 
         (proxy [java.awt.event.KeyAdapter] []          
           (keyPressed [#^java.awt.event.KeyEvent e]
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_UP)
               (try 
                 (let [startPosition 0]
                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))                  
                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
                   (reset! repl-input-index (min (inc @repl-input-index) (dec (count @repl-input))))
                   #_(.setText textArea (last @repl-input)))
                 (catch Exception e (println (.getMessage e))))
               (.consume e))
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_DOWN)
               (try 
                 (let [startPosition 0]
                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))                  
                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
                   (reset! repl-input-index (max (dec @repl-input-index) 0))
                   #_(.setText textArea (last @repl-input)))
                 (catch Exception e (println (.getMessage e))))
               (.consume e))
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_ENTER)
               (.append textArea "\n")
               ;; This shouldn't be here:
               #_(text! (:text-area @repl-output-window) (.toString (get-repl-outputstream)))
               (try 
                 (let [startPosition 0
                       line (.getText textArea startPosition (- (.getLength (.getDocument textArea)) startPosition 1))
                       ;response-vals (nrepl/message (:client @repl) {:op "eval" :code line})
                       #_session-sender #_(nrepl/client-session @reply.eval-modes.nrepl/current-connection :session @reply.eval-modes.nrepl/current-session)]
                   (reset! repl-input-index 0)
                   (.setText textArea "")
                   (eval-and-print line true)           
                   ;; Add to a console history
                   )
                 (catch Exception e (println (.getMessage e))))
               (.consume e)))))
       (.setSyntaxEditingStyle textArea (cond (= (:language params) :java) 
                                              (SyntaxConstants/SYNTAX_STYLE_JAVA)
                                              :else
                                              (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
       #_(.setCodeFoldingEnabled textArea true)      
       (display f sp)
       (-> f pack! show!)
       #_(println (.getLocation f))
       (.setLocation f 0 680)      
       {:frame f
        :text-area textArea
        :scroll-pane sp
        :menus menus}))

(defn make-repl-input-window
     "Make a REPL input window."
     [params]
     (let [textArea (RSyntaxTextArea. 25 115)          
           ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
           ;textArea.setCodeFoldingEnabled(true);      
           sp (RTextScrollPane. textArea)
           a-new (action :handler a-new :name "New" :tip "Create a new file.")
           a-open (action :handler a-open :name "Open" :tip "Open a file")
           a-save (action :handler a-save :name "Save" :tip "Save the current file.")
           a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
           a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
           a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
           a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
           a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
           menus (menubar
                   :items [#_(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
                           (menu :text "Edit" :items [a-copy a-cut a-paste])])
           ;f (frame :title "Brevis - REPL Input" :menubar menus)
           ]
       (.addKeyListener textArea 
         (proxy [java.awt.event.KeyAdapter] []          
           (keyPressed [#^java.awt.event.KeyEvent e]
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_UP)
               (try 
                 (let [startPosition 0]
                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))                  
                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
                   (reset! repl-input-index (min (inc @repl-input-index) (dec (count @repl-input))))
                   #_(.setText textArea (last @repl-input)))
                 (catch Exception e (println (.getMessage e))))
               (.consume e))
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_DOWN)
               (try 
                 (let [startPosition 0]
                   (.remove (.getDocument textArea) startPosition (- (.getLength (.getDocument textArea)) startPosition 1))                  
                   (.setText textArea (nth @repl-input (- (dec (count @repl-input)) @repl-input-index)))
                   (reset! repl-input-index (max (dec @repl-input-index) 0))
                   #_(.setText textArea (last @repl-input)))
                 (catch Exception e (println (.getMessage e))))
               (.consume e))
             (when (= (.getKeyCode e) java.awt.event.KeyEvent/VK_ENTER)
               (.append textArea "\n")
               ;; This shouldn't be here:
               #_(text! (:text-area @repl-output-window) (.toString (get-repl-outputstream)))
               (try 
                 (let [startPosition 0
                       line (.getText textArea startPosition (- (.getLength (.getDocument textArea)) startPosition 1))
                       ;response-vals (nrepl/message (:client @repl) {:op "eval" :code line})
                       #_session-sender #_(nrepl/client-session @reply.eval-modes.nrepl/current-connection :session @reply.eval-modes.nrepl/current-session)]
                   (reset! repl-input-index 0)
                   (.setText textArea "")
                   (eval-and-print line true)           
                   ;; Add to a console history
                   )
                 (catch Exception e (println (.getMessage e))))
               (.consume e)))))
       (.setSyntaxEditingStyle textArea (cond (= (:language params) :java) 
                                              (SyntaxConstants/SYNTAX_STYLE_JAVA)
                                              :else
                                              (SyntaxConstants/SYNTAX_STYLE_CLOJURE)))
       #_(.setCodeFoldingEnabled textArea true)      
       #_(display f sp)
       #_(-> f pack! show!)
       #_(println (.getLocation f))
       #_(.setLocation f 0 680)      
       {;:frame f
        :text-area textArea
        :scroll-pane sp
        :menus menus}))

#_(defn make-repl-output-window
    "Make an editor window."
    [params]
    (let [f (frame :title "Brevis - REPL Output" :width 800 :height 200 :minimum-size [800 :by 360])
          text-area (text :multi-line? true :font "MONOSPACED-PLAIN-14"
                                           :text "> ")
          area (scrollable text-area)
          listener-thread (Thread. (fn []  
                                     (loop []
                                       (let [resp (nrepl.transport/recv (:client @repl) 20)]
                                         (when resp
                                           (when (:out resp) (write-stdout-repl (:out resp)))
                                           (when (:value resp) (write-value-repl (:value resp)))))
                                       (recur))))]
     (display f area)
     (-> f pack! show!)
     (.setLocation f 850 650)      
     {:frame f
      :scrollable area
      :listener-thread listener-thread
      :text-area text-area}))

(defn make-repl-output-window
    "Make an editor window."
    [params]
    (let [;f (frame :title "Brevis - REPL Output" :width 800 :height 200 :minimum-size [800 :by 360])
          text-area (text :multi-line? true :font "MONOSPACED-PLAIN-14"
                                           :text "> ")
          area (scrollable text-area)
          listener-thread (Thread. (fn []  
                                     (loop []
                                       (let [resp (nrepl.transport/recv (:client @repl) 20)]
                                         (when resp
                                           (when (:out resp) (write-stdout-repl (:out resp)))
                                           (when (:value resp) (write-value-repl (:value resp)))))
                                       (recur))))]
     #_(display f area)
     #_(-> f pack! show!)
     #_(.setLocation f 850 650)      
     {;:frame f
      :scrollable area
      :listener-thread listener-thread
      :text-area text-area}))

(defn make-ui
  "Make a multi-widget UI."
  []
  (let [a-new (action :handler a-new :name "New" :tip "Create a new file.")
        a-open (action :handler a-open :name "Open" :tip "Open a file")
        a-save (action :handler a-save :name "Save" :tip "Save the current file.")
        a-exit (action :handler a-exit :name "Exit" :tip "Exit the editor.")
        a-copy (action :handler a-copy :name "Copy" :tip "Copy selected text to the clipboard.")
        a-paste (action :handler a-paste :name "Paste" :tip "Paste text from the clipboard.")
        a-cut (action :handler a-cut :name "Cut" :tip "Cut text to the clipboard.")
        a-save-as (action :handler a-save-as :name "Save As" :tip "Save the current file.")
        a-eval-file (action :handler a-eval-file :name "Evaluate" :tip "Evaluate the current file.")
        a-projects (map #(action :handler (make-a-active-project %)
                                 :name (str (:group %) "/" (:name %))
                                 :tip (str (:group %) "/" (:name %)))
                        (:projects @current-profile))
        menus (menubar
                :items [(menu :text "File" :items [a-new a-open a-save a-save-as a-exit])
                        (menu :text "Edit" :items [a-copy a-cut a-paste])
                        (menu :text "Run" :items [a-eval-file])
                        (menu :text "Projects" :items (into [] a-projects))
                        (menu :text "Git" :items [])
                        #_(menu :text "My Project" :items [(action :handler (fn [e] nil) :name "Open a project")
                                                          (action :handler (fn [e] nil) :name "in")
                                                          (action :handler (fn [e] nil) :name "projects menu")])])
        panel (mig-panel :constraints [#_"wrap 2"]
                         :items [[(:scroll-pane (get-editor)) "wrap, span 2, w 100%, h 75%"]
                                 [(:scroll-pane @repl-input-window) "w 50%, h 25%"]
                                 [(:scrollable @repl-output-window) "w 50%, h 25%"]])
        f (frame :title "Brevis - UI" :width 1024 :height 768 #_:minimum-size #_[800 :by 600] :menubar menus)]
    (display f panel)
    (-> f #_pack! show!)
    (.setLocation f 0 0)      
    {:frame f
     :panel panel}))

(defn -main 
  "Start from command line."
