;=====
; CS 111 - Week 3 Lecture 2 - 2024-09-12
;=====

(require 2htdp/image)

;=====
; reminder: the two basic operations that 2htdp/image
;     provides for the scene type it also defines:
; *   empty-scene
; *   place-image

;-----
; signature: empty-scene: number number -> scene
; purpose: expects a desired scene's width and height
;    in pixels, and returns a blank scene of that
;    width and height

(define WIDTH 400)
(define HEIGHT 200)

(empty-scene WIDTH HEIGHT)

;-----
; signature: place-image: image number number scene -> scene
; purpose: expects a desired image, a desired x and y location,
;    and a desired scene, and returns a new scene with
;    that image at that location in that scene

;-----
; NOTE: in 2htdp/image and 2htdp/universe,
; the coordinate system is such that (0, 0) is the top left,
; and as x gets bigger, you go right;
; and as y gets bigger, you go ***DOWN***

"this red circle ring should be centered at"
"    100 pixels from the left,"
"    and 50 pixels down:"

(place-image (circle 40 "outline" "red")
             100
             50
             (empty-scene WIDTH HEIGHT))

"this blue square should be centered at"
"    WIDTH pixels from the left,"
"    and HEIGHT pixels down"
"    (so, in the lower-right corner)"

(place-image (square 60 "solid" "blue")
             WIDTH
             HEIGHT
             (empty-scene WIDTH HEIGHT))

"this purple rectangle should be centered at"
"    WIDTH pixels from the left,"
"    and 0 pixels down"
"    (so, in the upper-right corner)"

(place-image (rectangle 100 60 "solid" "purple")
             WIDTH
             0
             (empty-scene WIDTH HEIGHT))

"this green pentagon should be centered at"
"    0 pixels from the left,"
"    and 0 pixels down"
"    (so, in the upper-left corner)"

(place-image (regular-polygon 40 5 "solid" "green")
             0
             0
             (empty-scene WIDTH HEIGHT))

;=====
; I want a function that expects a (positive) number
;    and returns a scene of a teal star of that number's
;    size centered in that scene

;-----
; hey -- function teal-star from Week 2 - Lecture 2 could
;    be used to help me write this scene function!

;=====
; COPYING OVER signature, purpose, tests and
;     definition of function teal-star from
;     Week 2 Lecture 2, because I'd like to use it
;     in my scene function here!
; CS 111 CLASS STYLE: when you copy a previously-created
;     function into another Racket file, copy over
;     its signature, purpose, and tests as well as its
;     definition (and also any other definitions it needs!)

;=====
;FROM WEEK 2 LECTURE 2
;=====
;=====
; signature: teal-star: number -> image
; purpose: expects the desired distance between
;   a star's points in pixels, and returns a solid
;   teal star of that size

(check-expect (teal-star 10)
              (star 10 "solid" "teal"))
(check-expect (teal-star 50)
              (star 50 "solid" "teal"))

(define (teal-star edge-size)
    (star edge-size "solid" "teal")
)
;===== (END of part copied over from Week 2 Lecture 2)

;-----
; continuing, now, with the design recipe steps for
;     this scene function:

;=====
; signature: teal-star-scene: number -> scene
; purpose: expects a star size, and returns a scene
;    of a centered teal star of that size

(check-expect (teal-star-scene 50)
              (place-image
                  (teal-star 50)
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  (empty-scene WIDTH HEIGHT)))

(check-expect (teal-star-scene 8)
              (place-image
                   (teal-star 8)
                   (/ WIDTH 2)
                   (/ HEIGHT 2)
                   (empty-scene WIDTH HEIGHT)))

(define (teal-star-scene star-size)
   (place-image (teal-star star-size)
                (/ WIDTH 2)
                (/ HEIGHT 2)
                (empty-scene WIDTH HEIGHT))
)

(teal-star-scene 50)
(teal-star-scene 8)

;=====
; function big-bang is defined in the module
; 2htdp/universe

(require 2htdp/universe)

;-----
; big-bang expects at least 2 arguments;
;    the first is the initial value of a new "world"
;        (and the type of that value becomes the type
;        of the new world)
;    the remainder are clauses, special compound expressions
;        that start with the name of an event
;        and are followed with the name of a function
;        to be called when that event happens (an event-handler
;        function) (and a few have additional optional arguments)
;    big-bang returns the value of the world when it ended

;-----
; the event you MUST handle is when big-bang wants to
;    depict its world, to draw its world:
; to-draw
; when the to-draw event occurs, big-bang calls the
;    the function you give it with the current world value
;    as its argument, and it displays the resulting scene
;    in a pop-up window

"should see a pop-up window with an unchanging teal star in"
"    the center;"
"CLOSE that window to continue!"

(big-bang 50
  (to-draw teal-star-scene))

;-----
; each time you call function big-bang,
;    big-bang starts up a ticker that ticks about
;    28 times per second;
; each time the ticker ticks, big-bang calls to-draw's function
;    to depict the current world value's scene;
; BUT -- if you also have an on-tick clause --
;    at the event of each ticker tick,
;    big-bang calls the on-tick clause's function
;        with the current world value,
;    and what that function returns becomes the *new* world value

;=====
; fun fact: Racket has a function add1:
;-----
; signature: add1: number -> number
; purpose: expects a number, and returns 1 more than that
;    number

;-----
; if my world type is number,
;      I can use add1 as on-tick's argument,
;      and each time big-bang's ticker ticks,
;      big-bang will call add1 with the current world value
;      to result in a new world value:

"should see a pop-up window with a GROWING teal star in"
"    the center;"
"CLOSE that window to continue!"

(big-bang 50
  (to-draw teal-star-scene)
  (on-tick add1))

;=====
; fun fact: Racket has a function sub1:
;-----
; signature: sub1: number -> number
; purpose: expects a number and returns 1 less than that
;    number

;-----
; if my world type is number,
;      I can use sub1 as on-tick's argument,
;      and each time big-bang's ticker ticks,
;      big-bang will call sub1 with the current world value
;      to result in a new world value:

"should see a pop-up window with a SHRINKING teal star in"
"    the center;"
"CLOSE that window before world value gets to 0 to continue,"
"    otherwise big-bang will be stopped by the error that happens"
"    when teal-star-scene calls teal-star and teal-star calls"
"    function star with a non-zero size!"
"    "
"    (if you try out the error, you'll need to close the world pop-up"
"    window or it just sticks around...)"

(big-bang 300
  (to-draw teal-star-scene)
  (on-tick sub1))