#lang racket

(require gigls/unsafe)

;list of cool colors to use for either background or forground, depending on given number
(define cool-colors
  (list "blue" "cadetblue" "navy" "teal" "turquoise" "olive" "forestgreen"))

;list of warm colors to use for either background or forground, depending on given number
(define warm-colors
  (list "chocolate" "indigo" "yellow" "crimson" "tomato" "fuchsia" "gold" "violet" "lime" "magenta" "maroon"))

;list of colors across the color spectrum to use for lines in the corner
(define line-colors
  (list "darkslateblue" "darkviolet" "deepskyblue" "seagreen" "mediumseagreen" "springgreen" "yellowgreen" "greenyellow" "yellow" "orange" "darkorange" "red" "darkred"))



(define image-series
  (lambda (n width height)
    (cond
      [(< n 91)
       (context-set-brush! "2. Hardness 100" 1)]
      [(< n 182)
       (context-set-brush! "2. Hardness 100" 2)]
      [(< n 273)
       (context-set-brush! "2. Hardness 100" 3)]
      [(< n 364)
       (context-set-brush! "2. Hardness 100" 4)]
      [(< n 455)
       (context-set-brush! "2. Hardness 100" 5)]
      [(< n 546)
       (context-set-brush! "2. Hardness 100" 6)]
      [(< n 637)
       (context-set-brush! "2. Hardness 100" 7)]
      [(< n 728)
       (context-set-brush! "2. Hardness 100" 8)]
      [(< n 819)
       (context-set-brush! "2. Hardness 100" 9)]
      [(< n 910)
       (context-set-brush! "2. Hardness 100" 10)]
      [else
       (context-set-brush! "2. Hardness 100" 11)])
    (context-set-fgcolor! (list-ref line-colors (mod n (length line-colors))))
    (if (even? n)
        (cool-background n width height)
        (warm-background n width height))))



;Citations for individual parts of code are contained within the procedure at the appropriate location
(define cool-background
  (lambda (n width height)
    (let ([canvas (radial-blend width height 0 (- height 1) (* 1.3 (- height 1)) (list-ref cool-colors (mod n (length cool-colors))))])
      ;The following let statement for drawing lines was inspired from code contained in a weekly quiz
      (let draw-lines ([start-col 0]
                       [row 0])
        (when (< start-col (- (image-width canvas) 1))
          (image-draw-line! canvas start-col 0 (- (image-width canvas) 1) row)
          (draw-lines (+ start-col (* 0.0375 (image-width canvas))) (+ row (* 0.0375 (image-height canvas))))))
      ;The code for drawing polygons was taken from code written for Exam 3
      ; and added to in order to create repetion. 
      (let ([dave (turtle-new canvas)]
            [original-side-length (/ (min (image-width canvas) (image-height canvas)) 8)])
        (turtle-set-color! dave (list-ref warm-colors (mod n (length warm-colors))))
        (turtle-set-brush! dave "2. Block 03" 5)
        (turtle-teleport! dave (/ (image-width canvas) 10) (* .8 (image-height canvas)))
        (let turtle-shapes ([num-sides (+ 3 (mod n 3))]
                            [side-length original-side-length]
                            [num-shapes 4]
                            [repeats 4])
          (when (and (> num-shapes 0) (> repeats 0))
            (repeat num-sides draw-single-side-of-polygon! dave side-length num-sides)
            (when (> num-shapes 1)
              (cond
                [(= repeats 4)
                 (turtle-teleport! dave (+ (turtle-col dave) original-side-length (* 0.025 (image-width canvas))) (turtle-row dave))]
                [(= repeats 3)
                 (turtle-teleport! dave (turtle-col dave) (- (turtle-row dave) original-side-length (* 0.025 (image-height canvas))))]
                [(= repeats 2)
                 (turtle-teleport! dave (- (turtle-col dave) original-side-length (* 0.025 (image-width canvas))) (turtle-row dave))]
                [else
                 (turtle-teleport! dave (turtle-col dave) (+ (turtle-row dave) original-side-length (* 0.025 (image-height canvas))))]))
            (turtle-shapes num-sides (* side-length 0.6) (- num-shapes 1) repeats))
          (when (= num-shapes 0)
            (turtle-shapes num-sides original-side-length 4 (- repeats 1)))))
      (image-show canvas))))


;This procedure is near identical to the previous, with only the switching of warm and cool colors from the forground to the background, respectively
;Code contained in this procedure was inspired, taken, and modified from the same code as its counterpart code in cool-background
(define warm-background
  (lambda (n width height)
    (let ([canvas (radial-blend width height 0 (- height 1) (* 1.3 (- height 1)) (list-ref warm-colors (mod n (length warm-colors))))])
      (let draw-lines ([start-col 0]
                       [row 0])
        (when (< start-col (- (image-width canvas) 1))
          (image-draw-line! canvas start-col 0 (- (image-width canvas) 1) row)
          (draw-lines (+ start-col (* 0.0375 (image-width canvas))) (+ row (* 0.0375 (image-height canvas))))))
      (let ([dave (turtle-new canvas)]
            [original-side-length (/ (min (image-width canvas) (image-height canvas)) 8)])
        (turtle-set-color! dave (list-ref cool-colors (mod n (length cool-colors))))
        (turtle-set-brush! dave "2. Block 03" 5)
        (turtle-teleport! dave (/ (image-width canvas) 10) (* .8 (image-height canvas)))
        (let turtle-shapes ([num-sides (+ 3 (mod n 3))]
                            [side-length original-side-length]
                            [num-shapes 4]
                            [repeats 4])
          (when (and (> num-shapes 0) (> repeats 0))
            (repeat num-sides draw-single-side-of-polygon! dave side-length num-sides)
            (when (> num-shapes 1)
              (cond
                [(= repeats 4)
                 (turtle-teleport! dave (+ (turtle-col dave) original-side-length (* 0.025 (image-width canvas))) (turtle-row dave))]
                [(= repeats 3)
                 (turtle-teleport! dave (turtle-col dave) (- (turtle-row dave) original-side-length (* 0.025 (image-height canvas))))]
                [(= repeats 2)
                 (turtle-teleport! dave (- (turtle-col dave) original-side-length (* 0.025 (image-width canvas))) (turtle-row dave))]
                [else
                 (turtle-teleport! dave (turtle-col dave) (+ (turtle-row dave) original-side-length (* 0.025 (image-height canvas))))]))
            (turtle-shapes num-sides (* side-length 0.6) (- num-shapes 1) repeats))
          (when (= num-shapes 0)
            (turtle-shapes num-sides original-side-length 4 (- repeats 1)))))
      (image-show canvas))))


;The following procedure was taken from code previously written for exam 3
; in order to draw polygons in warm-background and cool-background

;;; Procedure:
;;;   draw-single-side-of-polygon!
;;; Parameters:
;;;   trtle, a turtle
;;;   side-len, a positive number
;;;   num-sides, a positive number
;;; Purpose:
;;;   creates a line of length side-len and turns turtle (/ 360 num-sides)
;;; Preconditions:
;;;   The turtle is within the bounds of its underlying image.
;;; Postconditions:
;;;   The turtle's pen is down.
;;;   The turtle is facing (/ 360 num-sides) degrees to the 
;;;     right of where it started
;;;   The image now contains a line, drawn with the turtle's
;;;     current brush and color.
;;;   The line is at the angle in which the turtle is facing.
;;;   The first point of the line is at the turtle's original position 
(define draw-single-side-of-polygon!
  (lambda (trtle side-len num-sides)
    (turtle-forward! trtle side-len)
    (turtle-turn! trtle (/ 360 num-sides))))



;This procedure was taken from previous work done on Exam 2
; and has been modified for the purposes of this project
;Some code for the following definition was inspired by
;   Davis, J., Weinman, J., and Rebelsky, S. (2014).  The DrRacket
;   Programming Environment.  Online document available at 
;   http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/readings/iterate-positions-reading.html

(define radial-blend
  (lambda (width height center-col center-row radius color)
    (image-compute
     (lambda (col row)
       (let ([distance-from-center (sqrt (+ (square (- col center-col)) (square (- row center-row))))])
         (cond 
           [(equal? color "blue")
            (if (<= distance-from-center radius)
                (irgb  0 
                       0
                       (* distance-from-center (/ 255 radius)))
                (irgb 0 0 255))]
           [(equal? color "navy")
            (if (<= distance-from-center radius)
                (irgb  0 
                       0
                       (* distance-from-center (/ 128 radius)))
                (irgb 0 0 128))]
           [(equal? color "teal")
            (if (<= distance-from-center radius)
                (irgb  0 
                       (* distance-from-center (/ 128 radius))
                       (* distance-from-center (/ 128 radius)))
                (irgb 0 128 128))]
           [(equal? color "olive")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 128 radius)) 
                       (* distance-from-center (/ 128 radius))
                       0)
                (irgb 128 128 0))]
           [(equal? color "yellow")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 255 radius))
                       (* distance-from-center (/ 255 radius))
                       0)
                (irgb 255 255 0))]
           [(equal? color "fuchsia")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 255 radius))
                       0
                       (* distance-from-center (/ 255 radius)))
                (irgb 255 0 255))]
           [(equal? color "lime")
            (if (<= distance-from-center radius)
                (irgb  0
                       (* distance-from-center (/ 255 radius))
                       0)
                (irgb 0 255 0))]
           [(equal? color "magenta")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 255 radius))
                       0
                       (* distance-from-center (/ 255 radius)))
                (irgb 255 0 255))]
           [(equal? color "maroon")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 128 radius)) 
                       0
                       0)
                (irgb 128 0 0))]
           [(equal? color "cadetblue")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 95 radius)) 
                       (* 1.66 (* distance-from-center (/ 95 radius)))
                       (* 1.68 (* distance-from-center (/ 95 radius))))
                (irgb 95 158 160))]
           [(equal? color "turquoise")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 64 radius)) 
                       (* 3.5 (* distance-from-center (/ 64 radius)))
                       (* 3.25 (* distance-from-center (/ 64 radius))))
                (irgb 64 224 208))]
           [(equal? color "forestgreen")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 34 radius)) 
                       (* 4.08 (* distance-from-center (/ 34 radius)))
                       (* distance-from-center (/ 34 radius)))
                (irgb 34 139 34))]
           [(equal? color "chocolate")
            (if (<= distance-from-center radius)
                (irgb  (* 7 (* distance-from-center (/ 30 radius)))
                       (* 3.5 (* distance-from-center (/ 30 radius)))
                       (* distance-from-center (/ 30 radius)))
                (irgb 210 105 30))]
           [(equal? color "indigo")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 75 radius)) 
                       0
                       (* 1.73 (* distance-from-center (/ 75 radius))))
                (irgb 75 0 130))]
           [(equal? color "crimson")
            (if (<= distance-from-center radius)
                (irgb  (* 11 (* distance-from-center (/ 20 radius)))
                       (* distance-from-center (/ 20 radius))
                       (* 3 (* distance-from-center (/ 20 radius))))
                (irgb 220 20 60))]
           [(equal? color "tomato")
            (if (<= distance-from-center radius)
                (irgb  (* 3.59 (* distance-from-center (/ 71 radius))) 
                       (* 1.39 (* distance-from-center (/ 71 radius)))
                       (* distance-from-center (/ 71 radius)))
                (irgb 255 99 71))]
           [(equal? color "cadetblue")
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 95 radius)) 
                       (* 1.66 (* distance-from-center (/ 95 radius)))
                       (* 1.68 (* distance-from-center (/ 95 radius))))
                (irgb 95 158 160))]
           [(equal? color "gold")
            (if (<= distance-from-center radius)
                (irgb  (* 1.18 (* distance-from-center (/ 215 radius))) 
                       (* distance-from-center (/ 215 radius))
                       0)
                (irgb 255 215 0))]
           [(equal? color "violet")
            (if (<= distance-from-center radius)
                (irgb  (* 1.83 (* distance-from-center (/ 130 radius)))
                       (* distance-from-center (/ 130 radius))
                       (* 1.83 (* distance-from-center (/ 130 radius))))
                (irgb 238 130 238))]
           [else
            (if (<= distance-from-center radius)
                (irgb  (* distance-from-center (/ 255 radius)) 
                       (* distance-from-center (/ 255 radius))
                       (* distance-from-center (/ 255 radius)))
                (irgb 255 255 255))])))
     width height)))
;this procedure returns an image
