(ns advent.screens.dialogue
  (:require [play-clj.core :refer :all]
            [play-clj.ui :refer :all]
            [play-clj.utils :refer :all]
            [play-clj.g2d :refer :all]
            [clojure.pprint]
            [advent.pathfind]
            [clojure.core.async :refer [put! <! <!! >! >!! chan go thread take! alts!!]]
            #_[advent.screens.scene :as scene])
  (:import [com.badlogic.gdx.graphics Pixmap Pixmap$Filter Texture Texture$TextureFilter]
           [com.badlogic.gdx.graphics.g2d TextureRegion]
           [com.badlogic.gdx.scenes.scene2d.utils Align]
           [com.badlogic.gdx Screen]))

(defn ensure-on-screen [talk]
  (let [margin-width (* 0.05 (game :width))
        minimum-x margin-width
        maximum-x (- (game :width) margin-width)
        label-width (label! talk :get-width)
        label-right (+ (:x talk) label-width)]
    (cond (> label-right maximum-x) (assoc talk :x (- maximum-x label-width))
          (< (:x talk) minimum-x) (assoc talk :x minimum-x)
          :else talk)))

(defscreen talking-screen
  :on-show
  (fn [screen entities]
    (update! screen :renderer (stage) :camera (orthographic))
    {})
  :on-render
  (fn [screen [entities]]
    (render! screen (vals entities))
    entities)

  :on-talk
  (fn [{:keys [create-talk target-id text x y scale]} [entities]]
    (let [font (bitmap-font "ego/font.fnt" ) 
          tr (bitmap-font! font :get-region)
          scale (or (min (max scale 0.75) 1) 1)
          width (/  (game :width) 1.5)
          tx (.getTexture tr)
          _ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)
          talk (assoc (label text (style :label font (color :white))) :x (- (* 4 x) (/ width 2)) :y (* 4 y))
          talk (ensure-on-screen talk)]
      (label! talk :set-wrap true)
      (label! talk :set-width width)
      (label! talk :set-font-scale scale)
      (label! talk :set-alignment Align/center)
      (assoc entities target-id talk)))

  :stop-talk
  (fn [{:keys [target-id] } [entities]]
    (dissoc entities target-id))

  
  :on-resize (fn [screen entities]
               (size! screen 1280 960)))

(defscreen choice-screen
  :on-show
  (fn [screen entities]
    (update! screen :renderer (stage) :camera (orthographic))
    {})

  :on-render
  (fn [screen [entities]]
    (render! screen (vals entities))
    entities)

  :on-present-choices
  (fn [{:keys [choices callback]} [entities]]
    (let [font (bitmap-font "ego/font.fnt" ) 
          tr (bitmap-font! font :get-region)
          scale 1 
          tx (.getTexture tr)
          _ (texture! tx :set-filter Texture$TextureFilter/Linear Texture$TextureFilter/Linear)]
      (-> entities
          (into (for [[[text] i] (map vector choices (range))]
                  [i (assoc (label text (style :label font (color :white))) :x 30 :y (* 30 i))]))
          (assoc :state {:object nil :callback callback :choices choices}))))

  :on-touch-down (fn [screen [entities]]
                   (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})]
                     (when (seq entities)
                       (when (< y (* 30 (dec (count entities))))
                         ((get-in entities [:state :callback]) (int (/ y 30))) 
                         {}))))

  :on-mouse-moved (fn [screen [entities]]
                    (let [{:keys [x y]} (input->screen screen {:x (:input-x screen) :y (:input-y screen)})
                          font (bitmap-font "ego/font.fnt" )]
                     (when (seq entities)
                       (doseq [index (range (dec (count  entities)))]
                         (if (< (* index 30) y (* (inc index) 30))
                           (label! (entities index) :set-style (style :label font (color :yellow)))
                           (label! (entities index) :set-style (style :label font (color :white))))))))
  
  :on-resize (fn [screen entities]
               (size! screen 1280 960)))
