#lang racket
(require gigls/unsafe)
;Idea 2
;;; Procedure:
;;;   image-series
;;; Parameters:
;;;   n, a positive integer
;;;   width a positive integer
;;;   height, a positive integer
;;; Purpose:
;;;   Create an interesting image
;;; Produces:
;;;   awesome-image, an image
;;; Preconditions:
;;;   n must be between [0, 1000)
;;;   width cannot be 0 or negative     
;;;   height cannot be 0 or negative
;;; Postconditions:
;;;   awesome-image will be an image with a height of height and a width of width.
;;;   For each value of n, image-series will produce a different awesome-image by varying the top left corner of the squares as well as the color of the various design items.
;;;   awesome-image will scale based on width and height, however the turtles only scale with the width
(define image-series
  (lambda (n width height)
    (let* ([canvas (image-compute 
                    (lambda (col row)
                      (irgb 0 (* row (/ (/ width 2) 255)) (* col (/ (/ height 2) 255)))) width height)]
           [turtle1 (turtle-new canvas)]
           [turtle2 (turtle-new canvas)]
           [turtle3 (turtle-new canvas)]
           [turtle4 (turtle-new canvas)]
           [turtle5 (turtle-new canvas)]
           [turtle6 (turtle-new canvas)]
           [turtle7 (turtle-new canvas)]
           [turtle8 (turtle-new canvas)]
           [turtle9 (turtle-new canvas)]
           [turtle10 (turtle-new canvas)]
           [turtle11 (turtle-new canvas)]
           [turtle12 (turtle-new canvas)]
           [turtle13 (turtle-new canvas)]
           [turtle14 (turtle-new canvas)]
           [turtle15 (turtle-new canvas)]
           [turtle16 (turtle-new canvas)]
           [turtle17 (turtle-new canvas)]
           [turtles (list turtle1 turtle2 turtle3 turtle4 turtle5 turtle6 turtle7 turtle8 turtle9)])
      (turtle-teleport! turtle10 0 (* 1/9 height))
      (turtle-set-color! turtle10 "red")
      (turtle-set-brush! turtle10 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle10 width height)
      (turtle-teleport! turtle11 0 (* 2/9 height))
      (turtle-set-color! turtle11 "orange")
      (turtle-set-brush! turtle11 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle11 width height)
      (turtle-teleport! turtle12 0 (* 3/9 height))
      (turtle-set-color! turtle12 "yellow")
      (turtle-set-brush! turtle12 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle12 width height)
      (turtle-teleport! turtle13 0 (* 4/9 height))
      (turtle-set-color! turtle13 "green")
      (turtle-set-brush! turtle13 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle13 width height)
      (turtle-teleport! turtle14 0 (* 5/9 height))
      (turtle-set-color! turtle14 "skyblue")
      (turtle-set-brush! turtle14 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle14 width height)
      (turtle-teleport! turtle15 0 (* 6/9 height))
      (turtle-set-color! turtle15 "blue")
      (turtle-set-brush! turtle15 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle15 width height)
      (turtle-teleport! turtle16 0 (* 7/9 height))
      (turtle-set-color! turtle16 "darkblue")
      (turtle-set-brush! turtle16 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle16 width height)
      (turtle-teleport! turtle17 0 (* 8/9 height))
      (turtle-set-color! turtle17 "purple")
      (turtle-set-brush! turtle17 "2. Hardness 100" 4)
      (turtle-repeat-movement! turtle17 width height)
      (for-each turtle-teleport! turtles (make-list 9 (* 1/2 width)) (make-list 9 (* 1/2 height)))
      (turtle-set-color! turtle1 (irgb (truncate (abs (* 256 (cos n))))
                                       (truncate (abs (* 40 (sin n))))
                                       (mod n 40)))
      (turtle-set-brush! turtle1 "2. Hardness 100" 4)
      (turtle-set-color! turtle2 (irgb (truncate (abs (* 256 (sin n))))
                                       (truncate (abs (* 40 (cos n))))
                                       (mod n 40)))
      (turtle-set-brush! turtle2 "2. Hardness 100" 4)
      (turtle-set-color! turtle3 (irgb (truncate (abs (* 256 (sin n))))
                                       (truncate (abs (* 40 (sin n))))
                                       (mod n 40)))
      (turtle-set-brush! turtle3 "2. Hardness 100" 4)
      (turtle-set-color! turtle4 (irgb (truncate (abs (* 256 (cos n))))
                                       (truncate (abs (* 40 (cos n))))
                                       (mod n 40)))
      (turtle-set-brush! turtle4 "2. Hardness 100" 4)
      (turtle-set-color! turtle5 (irgb (truncate (abs (* 256 (sin n))))
                                       (mod n 40)
                                       (truncate (abs (* 40 (sin n))))))
      (turtle-set-brush! turtle5 "2. Hardness 100" 4)
      (turtle-set-color! turtle6 (irgb 255
                                       (mod n 40)
                                       (truncate (abs (* 40 (sin n))))))
      (turtle-set-brush! turtle6 "2. Hardness 100" 4)
      (turtle-set-color! turtle7 (irgb (truncate (abs (* 256 (sin n))))
                                       40
                                       (truncate (abs (* 40 (sin n))))))
      (turtle-set-brush! turtle7 "2. Hardness 100" 4)
      (turtle-set-color! turtle8 (irgb (truncate (abs (* 256 (sin n))))
                                       (mod n 40)
                                       40))
      (turtle-set-brush! turtle8 "2. Hardness 100" 4)
      (turtle-set-color! turtle9 (irgb (mod n 255)
                                       40
                                       (truncate (abs (* 40 (sin n))))))
      (turtle-set-brush! turtle9 "2. Hardness 100" 4)
      (for-each turtle-turn! turtles (map (l-s * 40) (iota 9)))
      (for-each (r-s turtle-design! 40) turtles)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (/ (* width (abs (cos n))) 3)
                               (/ (* height (abs (cos n)))3) 
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (cos n))))
                             (truncate (abs (* 40 (sin n))))
                             (mod n 40)))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (- (/ (* width (abs (cos n))) 3)
                                  (* 1/10 (/ (* width (abs (cos n))) 3)))
                               (- (/ (* height (abs (cos n))) 3)
                                  (* 1/10 (/ (* height (abs (cos n))) 3)))
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (sin n))))
                             (truncate (abs (* 40 (cos n))))
                             (mod n 40)))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (- (/ (* width (abs (cos n))) 3)
                                  (* 2/10 (/ (* width (abs (cos n))) 3)))
                               (- (/ (* height (abs (cos n))) 3)
                                  (* 2/10 (/ (* height (abs (cos n))) 3)))
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (sin n))))
                             (truncate (abs (* 40 (sin n))))
                             (mod n 40)))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (- (/ (* width (abs (cos n))) 3)
                                  (* 3/10 (/ (* width (abs (cos n))) 3)))
                               (- (/ (* height (abs (cos n))) 3)
                                  (* 3/10 (/ (* height (abs (cos n))) 3)))
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (cos n))))
                             (truncate (abs (* 40 (cos n))))
                             (mod n 40)))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (- (/ (* width (abs (cos n))) 3)
                                     (* 4/10 (/ (* width (abs (cos n))) 3))) 1)
                               (+ (- (/ (* height (abs (cos n))) 3)
                                     (* 4/10 (/ (* height (abs (cos n))) 3))) 1)
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (sin n))))
                             (mod n 40)
                             (truncate (abs (* 256 (sin n))))))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (- (/ (* width (abs (cos n))) 3)
                                     (* 5/10 (/ (* width (abs (cos n))) 3))) 1)
                               (+ (- (/ (* height (abs (cos n))) 3)
                                     (* 5/10 (/ (* height (abs (cos n))) 3))) 1)
                               )
      (context-set-fgcolor! (irgb
                             255
                             (mod n 40)
                             (truncate (abs (* 40 (sin n))))))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (- (/ (* width (abs (cos n))) 3)
                                     (* 6/10 (/ (* width (abs (cos n))) 3))) 1)
                               (+ (- (/ (* height (abs (cos n))) 3)
                                     (* 6/10 (/ (* height (abs (cos n))) 3))) 1)
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (sin n))))
                             40
                             (truncate (abs (* 40 (sin n))))))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (- (/ (* width (abs (cos n))) 3)
                                     (* 7/10 (/ (* width (abs (cos n))) 3))) 1)
                               (+ (- (/ (* height (abs (cos n))) 3)
                                     (* 7/10 (/ (* height (abs (cos n))) 3))) 1)
                               )
      (context-set-fgcolor! (irgb
                             (truncate (abs (* 256 (sin n))))
                             (mod n 40)
                             40))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (- (/ (* width (abs (cos n))) 3)
                                     (* 8/10 (/ (* width (abs (cos n))) 3))) 1)
                               (+ (- (/ (* height (abs (cos n))) 3)
                                     (* 8/10 (/ (* height (abs (cos n))) 3))) 1)
                               )
      (context-set-fgcolor! (irgb
                             (mod n 255)
                             (truncate (abs (* 40 (sin n))))
                             (truncate (abs (* 256 (sin n))))))
      (context-set-brush! "1. Pixel" 4)
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas)
      (image-select-rectangle! canvas REPLACE 
                               (/ (* width (abs (cos n))) 2)
                               (/ (* height (abs (cos n))) 2)
                               (+ (ceiling (- (/ (* width (abs (cos n))) 3)
                                              (* 9/10 (/ (* width (abs (cos n))) 3)))) 1)
                               (+ (ceiling (- (/ (* height (abs (cos n))) 3)
                                              (* 9/10 (/ (* height (abs (cos n))) 3)))) 1)
                               )
      (context-set-fgcolor! (irgb
                             (mod n 255)
                             40
                             (truncate (abs (* 40 (sin n))))))
      (context-set-brush! "1. Pixel" 4) 
      (image-stroke-selection! canvas)
      (image-fill-selection! canvas)
      (image-select-nothing! canvas))))
;turtle-action! and turtle-design! were taken from the reading on Iteration
;written by Professor Jerod Weinman.
;URL: http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/readings/iteration-reading.html
;;; Procedure:
;;;   turtle-action!
;;; Parameters:
;;;   turtle, a turtle
;;;   angle, an integer
;;; Purpose:
;;;   make a turtle perform an action
;;; Produces:
;;;   action, a procedure
;;; Preconditions:
;;;   angle must be 0 <= angle <= 360
;;; Postconditions:
;;;   action will move a turtle forward a certain amount and will also turn the turtle a certain amount.
(define turtle-action!
  (lambda (turtle angle)
    (turtle-forward! turtle (/ (image-width (turtle-world turtle)) 20))
    (turtle-turn! turtle angle)))
;;; Procedure:
;;;   turtle-design!
;;; Parameters:
;;;   turtle, a turtle
;;;   steps, an integer
;;; Purpose:
;;;   apply turtle-action! to a list of turtles
;;; Produces:
;;;   design, a changed image
;;; Preconditions:
;;;   steps must be greater than 0
;;; Postconditions:
;;;   design will be the same image just changed by the turtle. 
(define turtle-design!
  (lambda (turtle steps)
    (for-each (l-s turtle-action! turtle)
              (list-drop (iota (+ 1 steps)) 1))))
;;; Procedure:
;;;   turtle-movement!
;;; Parameters:
;;;   turtle, a turtle
;;;   width, an integer
;;;   height, an integer
;;; Purpose:
;;;   move a turtle
;;; Produces:
;;;   movement, an changed image
;;; Preconditions:
;;;   width must be greater than 0
;;;   height must be greater than 0
;;; Postconditions:
;;;   movement will be the same image just changed by the turtle.
(define turtle-movement!
  (lambda (turtle width height)
    (turtle-face! turtle 325)
    (turtle-forward! turtle (* 1/5 height))
    (turtle-face! turtle 45)
    (turtle-forward! turtle (* 1/5 height))))
;;; Procedure:
;;;   turtle-repeat-movement!
;;; Parameters:
;;;   turtle, a turtle
;;;   width, an integer
;;;   height, an integer
;;; Purpose:
;;;   repeat turtle-movement! 30 times
;;; Produces:
;;;   img, a changed image
;;; Preconditions:
;;;   width must be greater than 0
;;;   height must be greater than 0
;;; Postconditions:
;;;   img will be the same image just changed by the turtle. 
(define turtle-repeat-movement!
  (lambda (turtle width height)
    (repeat 30 turtle-movement! turtle width height)))