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

; CS 111 - Week 4 Labs - 11:00 lab
; Sharon Tuttle
; last modified: 2016-09-16

(define WIDTH 300)
(define HEIGHT 200)
(define BACKDROP (empty-scene WIDTH HEIGHT))

;-------
; another big-bang clause:
; *   on-key
;     it expects the name of a function that expects
;     the current world value, and a string representing
;     a keystroke, and that returns the new world
;     value based on that keystroke
;
; when big-bang is running,
;     whenever the user types a key,
;     big-bang now CALLS on-key's function with
;         the current world value and a string
;         representing the key typed,
;     and then it calls to-draw's function with the
;     new world value (I think)

;========
; on-key example #1

; proof of concept: can I have a world JUST driven
;     by keystrokes?
; YES!

; can I have a function that expects a world-string
;    and a keystroke-string, and returns a new
;    world that is just that keystroke string?

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

;(define (change-world-string curr-world key-typed)
;    ...
;)

(check-expect (change-world-string "moo" "k")
              "k")
(check-expect (change-world-string "k" "p")
              "p")

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


;========
; FROM W4-2 examples:
;--------
; signature: draw-string-world: string -> scene
; purpose: expects a world-string, and returns
;    a scene with that world-string in its center,
;    in blue 40-point letters

;(define (draw-string-world world-string)
;   ...
;)

(check-expect (draw-string-world "Hi!")
              (place-image
                  (text "Hi!" 40 "blue")
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))
(check-expect (draw-string-world "Lo!")
              (place-image
                  (text "Lo!" 40 "blue")
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))

(define (draw-string-world world-string)
   (place-image
       (text world-string 40 "blue")
       (/ WIDTH 2)
       (/ HEIGHT 2)
       BACKDROP)
)
;======== end of part from W4-2 examples

; let's use that in big-bang!

(big-bang "moo"
          (to-draw draw-string-world)
          (on-key change-world-string))


;========
; FROM W3-2 examples:
;--------

;============
; signature: purple-star: number -> image
; purpose: expects the desire distance in pixels
;    between points of a 5-pointed star,
;    and returns a solid purple star image
;    of that size

(check-expect (purple-star 15)
              (star 15 "solid" "purple"))
(check-expect (purple-star 30)
              (star 30 "solid" "purple"))

(define (purple-star size)
    (star size "solid" "purple")
)

;--------
; signature: purple-star-scene: number -> scene
; purpose: expects a star-size,
;    and returns a scene of a centered purple star of
;    that size
; (in a scene of size WIDTH and HEIGHT,
;    that already has a little circle, star, and triangle in it)

;(define (purple-star-scene star-size)
;    ...
;)

(check-expect (purple-star-scene 25)
              (place-image
                  (purple-star 25)
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))
(check-expect (purple-star-scene 160)
              (place-image
                  (purple-star 160)
                  (/ WIDTH 2)
                  (/ HEIGHT 2)
                  BACKDROP))

(define (purple-star-scene star-size)
    (place-image (purple-star star-size)
                 (/ WIDTH 2)
                 (/ HEIGHT 2)
                 BACKDROP)
)

;======== end of part from W3-2 examples

;========
; I'd like to add a way for keystrokes to change
;     the size of the purple star;
; I could do that by having a keystroke change
;     the current world value;

; I decide:
;   a left-arrow keystroke -- "left" --
;     should DECREASE the star's size by 25
;   a right-arrow keystroke -- "right" --
;     should INCREASE the star's size by 25
;   I decide any other keystroke leaves it unchanged

;=====
; DATA DEFINITION:
; an ArrowKey is one of:
;    "up", "down", "left", "right"

(define SIZE-CHANGE 25)

; signature: change-star-size: number ArrowKey -> number
; purpose: expects a world number and an arrow key,
;    and if the arrow key is "left", returns the
;        world decreased by SIZE-CHANGE,
;    and if the arrow key is "right", returns the
;        world increased by SIZE-CHANGE,
;    and for any other arrow key (or "bad" key, for that
;        matter), returns the world unchanged

;(define (change-star-size world-num an-arrow-key)
;  ...
;)

(check-expect (change-star-size 150 "left")
              (- 150 SIZE-CHANGE))
(check-expect (change-star-size 135 "right")
              (+ 135 SIZE-CHANGE))
(check-expect (change-star-size 60 "up")
              60)
(check-expect (change-star-size 600 "down")
              600)
(check-expect (change-star-size 6 "m")
              6)

; say I decide to start with a cond-template for
;    the "classic" enumeration case:
;    a branch for each value of the enumeration
;    PLUS one for "anything else":

;(define (change-star-size world-num an-arrow-key)
;    (cond
;        [... ...]
;        [... ...]
;        [... ...]
;        [... ...]
;        [... ...]
;    )
;)

;(define (change-star-size world-num an-arrow-key)
;    (cond
;        [(string=? "left" an-arrow-key)
;                   (- world-num SIZE-CHANGE)]
;        [(string=? "right" an-arrow-key)
;                   (+ world-num SIZE-CHANGE)]
;        [(string=? "up" an-arrow-key)
;                   world-num]
;        [(string=? "down" an-arrow-key)
;                   world-num]
;        [else      world-num]
;    )
;)

; I decide to refactor that,
;    because "up" and "down" have the same result
;    expression as the else case --
;    why not combine them? (or delete "up" and
;    "down" cases in THIS case?)

(define (change-star-size world-num an-arrow-key)
    (cond
        [(string=? "left" an-arrow-key)
                   (- world-num SIZE-CHANGE)]
        [(string=? "right" an-arrow-key)
                   (+ world-num SIZE-CHANGE)]
        [else      world-num]
    )
)

(big-bang 0
          (to-draw purple-star-scene)
          (on-tick add1)
          (on-key change-star-size))