;=====
; CS 111 - Week 5 Lecture 1 - 2026-09-22
;=====

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

;===== ADAPTED from Week 4 Lecture 2 =====
;    (adapted and/or shortened some comments)

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

;----
; these images were originally from
;     http://wallofgame.com/free-online-games/arcade/231/Parachute_Penguin_Shootout.html):

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

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

FLOATING-PENGUIN
LANDED-PENGUIN

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

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

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

;=====
; 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 penguin's y coordinate,
;    and if it is less than the LANDING-HEIGHT,
;    it returns a scene of a floating penguin centered
;    at that y coordinate;
;    otheriwse, it returns a scene of a 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-BACKGD))

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

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

(define (draw-penguin-scene y-coord)
    (cond
        [(< y-coord LANDING-HEIGHT)
            (place-image FLOATING-PENGUIN
                         PENG-CTR-X
                         y-coord
                         PENG-SC-BACKGD)]
        
        [else
            (place-image LANDED-PENGUIN
                         PENG-CTR-X
                         LANDING-HEIGHT
                         PENG-SC-BACKGD)]
    )
)

;===== 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))

;=====
; big-bang's on-key clause expects a function that expects the
;    current-world type and a string representing a keystroke,
;    and returns the new world value
;
; (and big-bang will CALL this function each time the user
;    types a key, calling it with the current world value
;    and a string representing the key typed, resulting in a
;    new world value)

;=====
; I'd like to add an on-key clause so up- and down-arrow
;     keystrokes can change the penguin's elevation!

;-----
; let's call this function change-elevation

;-----
; HOW much should the penguin's height change when an up
;    or down arrow key is pushed?
;
; (and when a number might look odd or not-clear-why,
;    a so-called "magic number", that's often a good
;    candidate to make a named constant!)

(define BOUNCE-AMT 28)

;-----
; 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

;=====
; signature: change-elevation: number string -> number
; purpose: expects the current world value and a keystroke string
;     and returns the world's new value as follows:
;     *    if the keystroke is "up", return a new world reducing
;          the current world by BOUNCE-AMT,
;     *    if it is "down", return a new world increasing the
;          current world by BOUNCE-AMT,
;     *    for any other key, return the world value unchanged

(check-expect (change-elevation 0 "up") -28)

(check-expect (change-elevation 100 "down") 128)

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

(define (change-elevation world-val a-key)
    (cond
        [(string=? a-key "up")   (- world-val BOUNCE-AMT)]
        [(string=? a-key "down") (+ world-val BOUNCE-AMT)]
        [else  world-val]
    )
)

(check-expect (change-elevation 100 "down") 128)

"====="
"type up-arrow or down-arrow and see what happens"
"    (CLOSE big-bang sub-window to "
"        stop this big-bang expression)"
"====="

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

;=====
; itemization data COMBINES/generalizes intervals, enumerations,
;    single special values, etc.!

;=====
; we will use a comment called a DATA DEFINITION to
;     INFORMALLY define a data type
;     (could be an itemization data type, although could
;     also be something else...)

;-----
; CS 111 class style:
;     *   In a Data Definition, use a first-uppercase-letter,
;         then mixed case (camel-case) name for this informal data type
;
;         NumOrF   AddableThing
;
;     *   Once you have put in such a data definition comment,
;         you can use that informal data type in
;         function signatures

;=====
; DATA DEFINITION
; a NumOrF is one of:
;    * #false
;    * a number

;-----
; Now, using class style, I could describe built-in function
;     string->number with this function signature comment:

;-----
; signature: string->number: string -> NumOrF

(string->number "1")
(string->number "bounce")

;=====
; for itemization data,
;    you may find the built-in function equal? useful!

;=====
; DATA DEFINITION:
; an Anything is an expression of any data type

;=====
; signature: equal?: Anything Anything -> boolean

(equal? 3 "3")
(equal? #true "true")
(equal? 3 (+ 1 1 1))

;=====
; once upon a time, a CS 111 student asked if you
;     could write a function that, say, behaved one
;     way if given an image, and another way if given
;     a number, etc. -- that inspired this example:

;=====
; say I decided I wanted a function that would
;    "double" values it is "reasonable" to double

;=====
; DATA DEFINITION
; an AddableThing is one of:
;   *   number
;   *   image
;   *   string

;=====
; signature: double-it: AddableThing -> AddableThing
; purpose: expects an addable thing, and
;    *   if it is a number, it returns two times that number,
;    *   if it is an image, it returns that image side-by-side,
;    *   if it is a string, it returns that string appended to
;        itself
;    (and it should give an error otherwise)

;=====
; FINISH on THURSDAY

;(check-expect (double-it 3) 6)
;(check-expect (double-it (circle 20 "solid" "red"))
;              (beside (circle 20 "solid" "red")
;                      (circle 20 "solid" "red")))
;(check-expect (double-it "moo") "moomoo")

;(define (double-it an-addable-thing)
;    (cond
;      [... ...]
;      [... ...]
;      [... ...]
;    )
;)