; recursive-firebird-basics.dither
;
; THE RECURSIVE FIREBIRD — "Five Threads, One Flame"
;
; This beginner-sized recipe collects the values and calculations from the
; Getting Started with Dither tutorial. Run and change the small expressions
; near the bottom one at a time.

; Give the recipe a name and record the Dither modules it uses.
(module dither://package/user/recursive-firebird
  :title "The Recursive Firebird"
  :version "0.1.0"
  :summary "A five-thread phoenix recipe for a 5x7 garment hoop."
  :requires [dither://package/core
             dither://package/math]
  :capabilities [:write-document :spawn-jobs])

; Describe the machine and hoop in labeled values. Nested maps keep the units
; beside each measurement, which is easier to read than a bare number.
(defcustom user/firebird-machine
  {:profile :brother-se2000
   :single-needle true
   :hoop {:width {:inches 5.0}
          :height {:inches 7.0}}
   :safe-area {:width {:inches 4.45}
               :height {:inches 6.45}}
   :export-format :pes
   :thread-block-budget 5}
  :title "Firebird Machine Profile"
  :type :map)

; Set a comfortable target and a hard ceiling. The target guides normal work;
; the hard maximum is the point the recipe must not cross.
(defcustom user/firebird-budgets
  {:target-stitches 34000
   :hard-max-stitches 42000
   :target-trims 28
   :hard-max-trims 45
   :min-stitch {:millimeters 1.15}
   :preferred-running-stitch {:millimeters 2.15}
   :min-open-gap {:millimeters 0.85}}
  :title "Firebird Stitch and Routing Budgets"
  :type :map)

; Keep the five real thread passes in sewing order. Each entry is a map with a
; short ID, a friendly name, and an RGB preview color.
(defcustom user/firebird-palette
  [{:id :deep-teal
    :name "Deep Teal"
    :rgb "#087A7A"}
   {:id :dark-plum
    :name "Dark Plum"
    :rgb "#542044"}
   {:id :ember-coral
    :name "Ember Coral"
    :rgb "#CB5B48"}
   {:id :bone-ivory
    :name "Bone Ivory"
    :rgb "#E8DFC8"}
   {:id :antique-gold
    :name "Antique Gold"
    :rgb "#C99538"}]
  :title "Firebird Five-Thread Palette"
  :type :vector)

; These are the artistic controls worth changing between related versions.
; The seed chooses a repeatable variation; the feather counts set complexity.
(defcustom user/firebird-art
  {:seed 208319
   :primary-wing-feathers 9
   :secondary-wing-feathers 7
   :tail-streamers 11}
  :title "Firebird Artistic Controls"
  :type :map)

; Keep a number between two limits. Helpers like this make longer calculations
; easier to read because their names explain their purpose.
(define user/clamp
  (fn [number lower upper]
    (min upper (max lower number))))

; Find a value between a starting and ending value. A mix of 0.0 returns the
; start; a mix of 1.0 returns the end; 0.5 lands halfway between them.
(define user/lerp
  (fn [start end mix]
    (+ start (* (- end start) mix))))

; Calculate one normalized position for each primary feather. The small 0.65
; offset keeps the first position away from the exact wing root.
(define user/wing-positions
  (fn []
    (let {:count (get (custom/get user/firebird-art)
                      :primary-wing-feathers)}
      (for [index (range count)]
        (/ (+ index 0.65) count)))))

; Inspect the machine's safe width. The result is {:inches 4.45}.
(get-in (custom/get user/firebird-machine)
        [:safe-area :width])

; Inspect the nine calculated wing positions.
(user/wing-positions)

; Try a neighboring seed without replacing the original setting. The value
; returns to 208319 as soon as this expression finishes.
(custom/with-temporary
  {user/firebird-art
    (assoc (custom/get user/firebird-art) :seed 208320)}
  {:temporary-seed
    (get-in (custom/get user/firebird-art) [:seed])
   :wing-positions
    (user/wing-positions)})

; Mark the module as complete after its settings and helpers are defined.
(provide dither://package/user/recursive-firebird)
