;=====
; CS 111 - Week 5 Lecture 1 - 2025-09-23
;=====

(require 2htdp/image)
(require 2htdp/universe)

;===== ADAPTED from Week 4 Lecture 2 =====
;    (shortened some comments)

;=====
; some useful penguin-scene-related named constants

(define PENG-SC-WIDTH 300)
(define PENG-SC-HEIGHT 450)

(define PENG-SC-BACKGRD
        (empty-scene PENG-SC-WIDTH PENG-SC-HEIGHT))

(define PENG-CTR-X (/ PENG-SC-WIDTH 2))

(define FLOATING-PENGUIN
    (bitmap/url
       "https://nrs-projects.humboldt.edu/~st10/f25cs111/floating-penguin.png")
)

(define LANDED-PENGUIN
    (bitmap/url
       "https://nrs-projects.humboldt.edu/~st10/f25cs111/landed-penguin.png")
)

FLOATING-PENGUIN
LANDED-PENGUIN

;=====
; so the penguin can "land" when its feet roughly
;    reach the "ground" --
;    subtract half the landed penguin's height
;         from PENG-SC-HEIGHT to get a better landing height;

(define LANDING-HEIGHT
        (- PENG-SC-HEIGHT
           (/ (image-height LANDED-PENGUIN)
              2)))

;=====
; signature: draw-penguin-scene: number -> scene
; purpose: expects a world-number, and if it is less than
;   LANDING-HEIGHT, it returns a scene with a floating penguin
;   with the world-number as its y coordinate;
;   otherwise, it returns a scene with the now-landed penguin
;   on the "ground"

; for this function, I want at least 3 tests:
;    one that results in a floating penguin scene,
;    one that results in a landed penguin scene,
;    and one for the boundary between these two world-num ranges
; (more tests are fine!)

(check-expect (draw-penguin-scene 10)
              (place-image FLOATING-PENGUIN
                           PENG-CTR-X
                           10
                           PENG-SC-BACKGRD))

(check-expect (draw-penguin-scene -70)
              (place-image FLOATING-PENGUIN
                           PENG-CTR-X
                           -70
                           PENG-SC-BACKGRD))

(check-expect (draw-penguin-scene (+ 10 PENG-SC-HEIGHT))
              (place-image LANDED-PENGUIN
                           PENG-CTR-X
                           LANDING-HEIGHT
                           PENG-SC-BACKGRD))

(check-expect (draw-penguin-scene LANDING-HEIGHT)
              (place-image LANDED-PENGUIN
                           PENG-CTR-X
                           LANDING-HEIGHT
                           PENG-SC-BACKGRD))

(define (draw-penguin-scene world-num)
    (cond
       [(< world-num LANDING-HEIGHT)
            (place-image FLOATING-PENGUIN
                         PENG-CTR-X
                         world-num
                         PENG-SC-BACKGRD)]
       [else (place-image LANDED-PENGUIN
                          PENG-CTR-X
                          LANDING-HEIGHT
                          PENG-SC-BACKGRD)]
    )
)

;===== END of part adapted from Week 4 Lecture 2 =====

(draw-penguin-scene 10)
(draw-penguin-scene 10000)

"our penguin-world as of the end of class, "
"    Week 4 - Lecture 2: "
"    (CLOSE big-bang sub-window to "
"        stop this big-bang expression!!)"

(big-bang 0
  (to-draw draw-penguin-scene)
  (on-tick add1))

;=====
; I would like to be able to change my penguin's
;    elevation by typing an up-arrow or down-arrow
;    key

; since my penguin world's type is number,
;    this function for the on-key clause
;    must expect a number and a string and return
;    a number

;=====
; useful named constant: how MUCH will the penguin's
;     elevation change per up- or down-arrow keystroke?

(define ELEV-CHANGE 200)

;=====
; signature: change-elevation: number string -> number
; purpose: expects the current world-number and a keystroke
;    string "up" or "down", and returns the following:
;    *   if the keystroke string is "up", it returns
;        the current world value REDUCED by ELEV-CHANGE
;    *   if the keystroke string is "down", it returns
;        the current world value INCREASED by ELEV-CHANGE
;    *   if the keystroke string is anything else,
;        it returns the world value UNCHANGED

;====
; this is enumeration data -- and as purpose statement is
;    written, need at LEAST 3 tests, one for "up", one for
;    "down", and because purpose specifies what to do for any
;    other keystroke, at least one for some OTHER keystroke

(check-expect (change-elevation 100 "up")
              (- 100 ELEV-CHANGE))

(check-expect (change-elevation 200 "down")
              (+ 200 ELEV-CHANGE))

(check-expect (change-elevation 150 "left")
              150)

(define (change-elevation world-num key-string)
    (cond
        [(string=? key-string "up")   (- world-num ELEV-CHANGE)]
        [(string=? key-string "down") (+ world-num ELEV-CHANGE)]
        [else world-num]
    )
)

(change-elevation 200 "down")

"====="
"type up-arrow or down-arrow and see what happens"
"====="

(big-bang 0
  (to-draw draw-penguin-scene)
  (on-tick add1)
  (on-key change-elevation))