;=====
; CS 111 - extra example
; (fits in about Week 4 Lecture 2)
;
; big-bang with another world type

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

;-----
; how about: an initial world of type string?

;-----
; the simplest big-bang expression needs at least
;    an initial world value as its first argument,
;    and a to-draw clause whose argument is the name
;    of a function that expects that world's type
;    and returns a scene based on that given world value

;-----
; signature: draw-string-world: string -> scene
; purpose: expects any string, and return a scene depicting
;    that string in the center, in blue 40-point characters

(define STR-FONT-SIZE 40)
(define SC-WIDTH 700)
(define SC-HEIGHT 100)
(define BACKDROP (empty-scene SC-WIDTH SC-HEIGHT))
(define CENTER-X (/ SC-WIDTH 2))
(define CENTER-Y (/ SC-HEIGHT 2))

(check-expect (draw-string-world "moo")
              (place-image
                  (text "moo" STR-FONT-SIZE "blue")
                  CENTER-X
                  CENTER-Y
                  BACKDROP))

(check-expect (draw-string-world "hello")
              (place-image
                  (text "hello" STR-FONT-SIZE "blue")
                  CENTER-X
                  CENTER-Y
                  BACKDROP))

(define (draw-string-world a-string)
    (place-image
        (text a-string STR-FONT-SIZE "blue")
        CENTER-X
        CENTER-Y
        BACKDROP)
)

(draw-string-world "moo")

;=====
; reminder: you can CHANGE the speed of big-bang's "ticker"
;    using an optional second argument in its on-tick clause;
;
; this argument's value: the rate of the ticker, in number of
;    seconds per tick;
; (default ticker rate is 1/28th second per tick (or about 28 ticks
;    per second)
;

;===== COPIED from Week 4 Lecure 2 examples
;
; signature: next-sound: string -> string
; purpose: expects an animal sound, and returns the "next" animal
;    sound (based on Sandra Boynton's "Moo, Baa, La la la")
;    *    for moo, return baa
;    *    for baa, return la la la
;    *    for la la la, return oink
;    *    for oink, return moo
;    *    for anything else, return "???"

(check-expect (next-sound "moo") "baa")
(check-expect (next-sound "baa") "la la la")
(check-expect (next-sound "la la la") "oink")
(check-expect (next-sound "oink") "moo")
(check-expect (next-sound "woof") "???")

(define (next-sound animal-sound)
    (cond
        [(string=? animal-sound "moo") "baa"]
        [(string=? animal-sound "baa") "la la la"]
        [(string=? animal-sound "la la la") "oink"]
        [(string=? animal-sound "oink") "moo"]
        [else "???"]
    )
)

(next-sound "baa")
(next-sound "oink")

;====
; big-bang's on-tick clause expects a function that expects the
;    current world type, and returns the current world type
; ...hey, next-sound expects a string and returns a string!

"====="
"this changes the world using the next-sound function"
"====="

(big-bang "moo"
    (to-draw draw-string-world)
    (on-tick next-sound 1))

;=====
; big-bang's on-key function provides a way for a user keystroke
;    to change its world value;
; on-key expects a function name for a function that expects
;   TWO arguments: the first of the current world type,
;   and the second a string representing a keystroke --
;   and its returns the current world type
;
; Then, when big-bang runs, each time the user types something
;    big-bang converts that keystroke to a string and calls
;    on-key's function with that string and with the current world
;    value, and what is returned becomes the NEW world value

;=====
; here's a VERY simple function we can use to try on-key
;    AND also see what strings big-bang uses for different keystrokes:
;
; it will simply make the keystroke string the NEW world value;

;-----
; signature: change-world-string: string string -> string
; purpose: expects a "world" string and a string representing a keystroke,
;    and simply returns that keystroke

(check-expect (change-world-string "moo" "f")
              "f")
(check-expect (change-world-string "h" "i")
              "i")

(define (change-world-string curr-world-str key-typed)
    key-typed
)

"======"
"type ANY string and see what happens!"
"======"

(big-bang "type any character"
    (on-key change-world-string)
    (to-draw draw-string-world))

;=====
; big-bang's stop-when clause expects the name of a function
;     that expects the current world type and returns a boolean.
; Then, while running, this function gets called at each "ticker" tick
;     with the current world, and if this function returns #true,
;     big-bang stops and returns the current world (but you still need
;     to hand-close the World window...)

;-----
; signature: time-to-quit?: string -> boolean
; purpose: expects a world-string, and returns #true if that string is
;    "q" or "Q", and returns #false otherwise

; need at least 3 tests here! (enumeration-style data -- "q" or "Q"! and
;   function specifies an action for anything else)

(check-expect (time-to-quit? "q")
              #true)

(check-expect (time-to-quit? "Q")
              #true)

(check-expect (time-to-quit? "k")
              #false)

(define (time-to-quit? world-string)
    (or (string=? world-string "q")
        (string=? world-string "Q"))
)

"====="
"type any characters, type q or Q to quit"
"====="

(big-bang "type any character or q or Q to quit"
    (on-key change-world-string)
    (to-draw draw-string-world)
    (stop-when time-to-quit?))