#lang racket
(require gigls/unsafe)
(provide (all-defined-out))

;;CSC-151-02 Project
;;  Bingyue and Rae


;;;Procedure:
;;;   max-rgb
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Computes the largest RGB component of a color.
;;;Produces:
;;;   maximized, an IRGB-component
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   0 <= maximized <= 255

(define max-rgb
  (lambda (value)
    (max (rgb-red value) (rgb-green value) (rgb-blue value))))



;;;Procedure:
;;;   min-rgb
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Computes the smallest RGB component of a color.
;;;Produces:
;;;   minimized, an IRGB-component
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   0 <= minimized <= 255

(define min-rgb
  (lambda (value)
    (min (rgb-red value) (rgb-green value) (rgb-blue value))))



;;;Procedure:
;;;   chroma
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Computes the difference between the largest
;;;     and the smallest RGB components of a color.
;;;Produces:
;;;   chrome, a non-negative integer
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   0 <= chrome <= 255

(define chroma
  (lambda (value)
    (- (max-rgb value) (min-rgb value))))



;The following codes for [reddish-hue] [blueish-hue] and [greenish-hue] were copied with permission by Bingyue He from:
;Assignment 5: Conditionals and Colors
;Author: Bingyue He (2014)


;;;Procedure:
;;;   reddish-hue
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Returns the computed hue of an IRGB-color.
;;;Produces:
;;;   red-hued, a non-negative integer
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   if chrome = 0, red-hued = 0
;;;   0 <= red-hued <= 6

(define reddish-hue
  (lambda (value)
    (if (= (chroma value) 0)
        0
        (if (< (/ (- (irgb-green value) (irgb-blue value)) (chroma value)) 0)
            (+ 6 (/ (- (irgb-green value) (irgb-blue value)) (chroma value)))
            (/ (- (irgb-green value) (irgb-blue value)) (chroma value))))))



;;;Procedure:
;;;   greenish-hue
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Returns the computed hue of an IRGB-color.
;;;Produces:
;;;   green-hued, a non-negative integer
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   if chrome = 0, green-hued = 0
;;;   0 <= green-hued <= 6

(define greenish-hue
  (lambda (value)
    (if (= (chroma value) 0)
        0
        (if (< (+ (/ (- (irgb-blue value) (irgb-red value)) (chroma value)) 2) 0)
            (+ 6  (+ (/ (- (irgb-blue value) (irgb-red value)) (chroma value)) 2))
             (+ (/ (- (irgb-blue value) (irgb-red value)) (chroma value)) 2)))))



;;;Procedure:
;;;   blueish-hue
;;;Parameters:
;;;   value, an integer-encoded IRGB-color
;;;Purpose:
;;;   Returns the computed hue of an IRGB-color.
;;;Produces:
;;;   blue-hued, a non-negative integer
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   if chrome = 0, blue-hued = 0
;;;   0 <= blue-hued <= 6

(define blueish-hue
  (lambda (value)
    (if (= (chroma value) 0)
        0
        (if (<  (+ (/ (- (irgb-red value) (irgb-green value)) (chroma value)) 4) 0)
            (+ 6  (+ (/ (- (irgb-red value) (irgb-green value)) (chroma value)) 4))
             (+ (/ (- (irgb-red value) (irgb-green value)) (chroma value)) 4)))))



;;;Procedure:
;;;   irgb->hue-angle
;;;Parameters:
;;;   irgb, an integer-encoded IRGB-color
;;;Purpose:
;;;   Produces the computed hue of an IRGB-color.
;;;Produces:
;;;   hue, a non-negative real number
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   0 <= hue < 360

(define irgb->hue-angle
  (lambda (irgb)
    (cond
      [(equal? (max-rgb irgb) (rgb-red irgb)) (if (< (reddish-hue irgb) 0)
                                                  (round (* 60 (+ 6 (reddish-hue irgb))))
                                                  (round (* 60 (reddish-hue irgb))))]
      [(equal? (max-rgb irgb) (rgb-green irgb)) (if (< (greenish-hue irgb) 0)
                                                    (round (* 60 (+ 6(greenish-hue irgb))))
                                                    (round (* 60 (greenish-hue irgb))))]
      [(equal? (max-rgb irgb) (rgb-blue irgb)) (if (< (blueish-hue irgb) 0)
                                                   (round (* 60 (+ 6 (blueish-hue irgb))))
                                                   (round (* 60 (blueish-hue irgb))))])))




;The following code [irgb-change] is inspired by code and procedures mentioned in:
;J.Weinman and S. Rebelsky (2014)
;Assignment 5: Conditionals and Colors
;http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/assignments/conditionals-and-colors.html


;;;Procedure:
;;;   irgb-change
;;;Parameters:
;;;   irgb-color, an integer-encoded IRGB-color
;;;   layers, a non-negative integer
;;;   level, a non-negative integer
;;;Purpose:
;;;    Creates a new integer-encoded RGB color using 
;;;    the hue, saturation, and value of irgb-color. 
;;;Produces:
;;;   changed, an integer-encoded IRGB-color
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   changed varies according to the drawing level given.
;;;   (irgb? changed) = #t

(define irgb-change
  (lambda (irgb-color layers level)
    (hsv->irgb (list (irgb->hue-angle irgb-color)
                     (- (irgb->saturation irgb-color) (* (/ (irgb->saturation irgb-color) layers) level))
                     (irgb->value irgb-color)))))


;;;Procedure:
;;;   position-get-explosion
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   turtle, a turtle
;;;   s-length, a non-negative real number
;;;   image, an image
;;;   level, a positive integer
;;;Purpose:
;;;    Draws a turtle-graphic (similar to an explosion shape) on an existing image. 
;;;    Helper procedure for 6-explosion.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   turtle must be predefined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image should be rendered. 

(define position-get-explosion
  (lambda (n turtle s-length image level)
    (turtle-up! turtle)
    (let* ([pos-get (lambda (turtle) (position-new (turtle-col turtle) (turtle-row turtle)))]
           [pos1 ((lambda (turtle)
                    (turtle-face! turtle 0)
                    (turtle-turn! turtle 60)
                    (pos-get turtle)) turtle)]
           [pos2 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)]
           [pos3 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos4 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)]
           [pos5 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos6 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)]
           [pos7 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos8 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)]
           [pos9 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos10 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)]
           [pos11 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos12 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle -60)
                    (pos-get turtle)) turtle)])
      (image-select-polygon! image REPLACE (list pos1 pos2 pos3 pos4 pos5 pos6 pos7 pos8
                                                 pos9 pos10 pos11 pos12))
      (context-set-fgcolor! (irgb-change (list-ref center-colors (modulo n 7)) 6 level))
      (image-fill-selection! image)
      (image-refresh-display! image)
      (image-select-nothing! image))))




;;;Procedure:
;;;   drawing-with-turtle
;;;Parameters:
;;;   n, a integer between 0 and 999
;;;   turtle, a turtle
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   col, a positive integer
;;;   row, a positive integer
;;;   drawing-proc, a GIMP drawing procedure
;;;   side, a positive integer
;;;   s-length, a non-negative real number
;;;   image, an image
;;;Purpose:
;;;    Helper-procedure for procedures that require the use of turtle(s) to create graphics. 
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   turtle must be predefined.
;;;   drawing-proc must be a valid procedure that Scheme and GIMP recognize.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   [dependent on procedure it is applied to]

(define drawing-with-turtle
  (lambda (n turtle width height level col row drawing-proc s-length image)
    (turtle-teleport! turtle (round (* col (/ width 12))) (round (* row (/ height 12))))
    (drawing-proc n turtle (round (* s-length (ceiling (/ (+ height width) 24)))) image level)))               


;;;Procedure:
;;;   6-explosion
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Draws a turtle-graphic (similar to an explosion shape) on background, an existing image. 
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   background must be predefined and "open" to display the side-effect.
;;;   drawing-with-turtle must be defined.
;;;   position-get-explosion must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image, background, should be rendered. 
;;;   Explosion-shape should have six "points".

(define 6-explosion
  (lambda (n width height image)
    (let* ([tursion (turtle-new image)])
      (drawing-with-turtle n tursion width height 5.8 6 -3.5 position-get-explosion 5.5 image)                                
      (drawing-with-turtle n tursion width height 5 6 -1 position-get-explosion 4 image)
      (drawing-with-turtle n tursion width height 4 6 1.2 position-get-explosion 2.7 image)
      (drawing-with-turtle n tursion width height 3 6 3 position-get-explosion 1.7 image)
      (drawing-with-turtle n tursion width height 2 6 4.2 position-get-explosion 1 image)
      (drawing-with-turtle n tursion width height 1 6 5 position-get-explosion 0.5 image))))




;;;Procedure:
;;;   position-get-diamond
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   turtle, a turtle
;;;   s-length, a non-negative real number
;;;   image, an image
;;;   level, a positive integer
;;;Purpose:
;;;    Draws a turtle-graphic (similar to a diamond shape) on an existing image. 
;;;    Helper procedure for diamond.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   turtle must be predefined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image should be rendered. 

(define position-get-diamond
  (lambda (n turtle s-length image level)
    (turtle-up! turtle)
    (let* ([pos-get (lambda (turtle) (position-new (turtle-col turtle) (turtle-row turtle)))]
           [pos1 ((lambda (turtle)
                    (turtle-face! turtle 0)
                    (turtle-turn! turtle 60)
                    (pos-get turtle)) turtle)]
           [pos2 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 60)
                    (pos-get turtle)) turtle)]
           [pos3 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos4 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 60)
                    (pos-get turtle)) turtle)])
      (image-select-polygon! image REPLACE (list pos1 pos2 pos3 pos4))
      (context-set-fgcolor! (irgb-change (list-ref center-colors (modulo n 7)) 6 level))
      (image-fill-selection! image)
      (image-refresh-display! image)
      (image-select-nothing! image))))
                    



;;;Procedure:
;;;   diamond
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Draws a turtle-graphic (similar to a diamond shape) on background, an existing image. 
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   background must be predefined and "open" to display the side-effect.
;;;   drawing-with-turtle must be defined.
;;;   turtle-diamond! must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image, background, should be rendered with a diamond-like shape.

(define diamond
  (lambda (n width height image)
    (let* ([turmond (turtle-new image)])
      (background n)
      (drawing-with-turtle n turmond width height 5.8 6 -4.7 position-get-diamond 12.5 image)
      (drawing-with-turtle n turmond width height 5 6 -2.5 position-get-diamond 10 image)
      (drawing-with-turtle n turmond width height 4 6 0.25 position-get-diamond 7 image)
      (drawing-with-turtle n turmond width height 3 6 2.5 position-get-diamond 4.5 image)
      (drawing-with-turtle n turmond width height 2 6 4.25 position-get-diamond 2.5 image)
      (drawing-with-turtle n turmond width height 1 6 5.5 position-get-diamond 1 image))))

 



;The following code was created AFTER we received our results from Exam 3: Recursion and Repetition.
;Thus, the following code and documentation were inspired by:
;CSC-151-02 Exam 3: Recursion and Repetition (2014)
;http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/assignments/exam3.2014F.html


;;;Procedure:
;;;   turtle-polygon!
;;;Parameters:
;;;   turtle, a turtle
;;;   side, a positive integer
;;;   s-length, a non-negative real number
;;;Purpose:
;;;   Uses a turtle to draw a regular polygon with the specified
;;;   number of sides, with each side of the specified length.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   turtle must be defined.
;;;Postconditions:
;;;   The image should be rendered.
;;;   Polygon drawn must have equal sides and angles (regular).

(define turtle-polygon!
  (lambda (turtle side s-length)
    (let ([action
           (lambda (turtle)
             (turtle-forward! turtle s-length)
             (turtle-turn! turtle (/ 360 side)))])   
      (turtle-down! turtle)
      (repeat side action turtle))))



;;;Procedure:
;;;   position-get-hexagon
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   turtle, a turtle
;;;   s-length, a non-negative real number
;;;   image, an image
;;;   level, a positive integer
;;;Purpose:
;;;    Draws a turtle-graphic (similar to a hexagon shape) on an existing image. 
;;;    Helper procedure for hexagon.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   turtle must be predefined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image should be rendered. 

(define position-get-hexagon
  (lambda (n turtle s-length image level)
    (turtle-up! turtle)
    (let* ([pos-get (lambda (turtle) (position-new (turtle-col turtle) (turtle-row turtle)))]
           [pos1 ((lambda (turtle)
                    (turtle-face! turtle 0)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)]
           [pos2 ((lambda (turtle)
                    (turtle-turn! turtle 60)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)]
           [pos3 ((lambda (turtle)
                    (turtle-turn! turtle 60)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)]
           [pos4 ((lambda (turtle)
                    (turtle-turn! turtle 60)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)]
           [pos5 ((lambda (turtle)
                    (turtle-turn! turtle 60)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)]
           [pos6 ((lambda (turtle)
                    (turtle-turn! turtle 60)
                    (turtle-forward! turtle s-length)
                    (pos-get turtle)) turtle)])
      (image-select-polygon! image REPLACE (list pos1 pos2 pos3 pos4 pos5 pos6))
      (context-set-fgcolor! (irgb-change (list-ref center-colors (modulo n 7)) 6 level))
      (image-fill-selection! image)
      (image-refresh-display! image)
      (image-select-nothing! image))))



; Triangles----------------------------------------


;;;Procedure:
;;;   position-get-triangle
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   turtle, a turtle
;;;   s-length, a non-negative real number
;;;   image, an image
;;;   level, a positive integer
;;;Purpose:
;;;    Draws a turtle-graphic (triangle-shape) on an existing image. 
;;;    Helper procedure for triangles.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   turtle must be predefined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   The image should be rendered. 

(define position-get-triangle
  (lambda (n turtle s-length image level)
    (turtle-up! turtle)
    (let* ([pos-get (lambda (turtle) (position-new (turtle-col turtle) (turtle-row turtle)))]
           [pos1 ((lambda (turtle)
                    (turtle-face! turtle 0)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos2 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)]
           [pos3 ((lambda (turtle)
                    (turtle-forward! turtle s-length)
                    (turtle-turn! turtle 120)
                    (pos-get turtle)) turtle)])
      (image-select-polygon! image REPLACE (list pos1 pos2 pos3))
      (context-set-fgcolor! (irgb-change (list-ref center-colors (modulo n 7)) 6 level))
      (image-fill-selection! image)
      (image-refresh-display! image)
      (image-select-nothing! image))))




;;;Procedure:
;;;   triangles
;;;Parameters:
;;;   n, a positive integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses turtles to draw a series of equilateral triangles
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   center-colors must be defined.
;;;   An image must be predefined and "open" to display the side-effect.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   position-get-triangle must be defined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;Postconditions:
;;;   The image should be rendered.

(define triangles
  (lambda (n width height level layer image)
    (let ([tri-turts (map turtle-new (make-list 8 image))])
      (for-each turtle-teleport! tri-turts (map (r-s + (/ width 50)) (hoff-list width layer)) (map (r-s - (round (/ height 30))) (voff-list height layer)))
      (for-each (lambda (turtle)
                  (position-get-triangle n turtle (/ width 20) image level)) tri-turts))))



;;;Procedure:
;;;   hexagon
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to draw a hexagon on an image.
;;;Produces:
;;;   Nothing. Called for its side-effect.
;;;Preconditions:
;;;   An image must be predefined and "open" to display the side-effect.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   drawing-with-turtle must be pre-defined.
;;;   position-get-hexagon must be predefined.
;;;Postconditions:
;;;   The image should be rendered.
                    
(define hexagon
  (lambda (n width height image)
    (let ([texagon (turtle-new image)])
       (background n)
       (drawing-with-turtle n texagon width height 5.8 2 -0.5 position-get-hexagon 8 image)
       (drawing-with-turtle n texagon width height 5 2.75 0.5 position-get-hexagon 6.5 image)
       (drawing-with-turtle n texagon width height 4 3.5 1.7 position-get-hexagon 5 image)
       (drawing-with-turtle n texagon width height 3 4.2 3 position-get-hexagon 3.5 image)
       (drawing-with-turtle n texagon width height 2 5 4.4 position-get-hexagon 2 image)
       (drawing-with-turtle n texagon width height 1 5.67 5.5 position-get-hexagon 0.7 image))))



;list-hues creates a list of hues to be used for the concentric background-shapes' gradient.

(define list-hues
  (map (o irgb->hue-angle color->irgb) (list "cyan" "red" "darkorange" "darkblue" "purple" "gold" "green")))


;center-colors creates a list of integer-encoded IRGB colors to be used for the concentric background-shapes.

(define center-colors
  (map color->irgb (list "cyan" "red" "darkorange" "darkblue" "purple" "gold" "green")))




;;;Procedure:
;;;   basic-drawing
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   off-factor, a positive number
;;;   scale-factor, a positive number 
;;;   level, a positive number < 6
;;;   basic-draw-proc, a procedure
;;;Purpose:
;;;   A helper procedure for the simple-drawing procedures, circles and squares.
;;;     Generates an image of a shape (either a circle or a square).
;;;Produces:
;;;   basics, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   basic-draw-proc must be a drawing procedure GIMP and Scheme recognize.
;;;Postconditions:
;;;   (drawing-type basics) =  drawing-unit-circle OR drawing-unit-square
;;;   (drawing-width basics) = (round (* scale-factor (/ width 12)))
;;;   (drawing-height basics) = (round (* scale-factor (/ height 12)))

(define basic-drawing
  (lambda (n width height center scale-factor level basic-draw-proc)
    (recolor-drawing
     (irgb-change (list-ref center-colors (modulo n 7)) 6 level)
     (hshift-drawing (round (* center width))
                     (vshift-drawing (round (* center height))
                                     (hscale-drawing (round (* scale-factor (/ width 12)))
                                                     (vscale-drawing (round (* scale-factor (/ height 12)))
                                                                     basic-draw-proc)))))))



;;;Procedure:
;;;   circles
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing of concentric circles.
;;;   Additionally, it is a helper procedure for bg-shapes-draw.
;;;Produces:
;;;   circled, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   basic-drawing must be pre-defined.
;;;Postconditions:
;;;   circled is a drawing of 6 concentric circles.
;;;   (drawing-type circled) = drawing-unit-circle(s)
;;;   (drawing-width circled) = width
;;;   (drawing-height circled) = height

(define circles
  (lambda (n width height)
     (drawing-group
      (basic-drawing n width height 0.5 13 5.8 drawing-unit-circle)
      (basic-drawing n width height 0.5 10 5 drawing-unit-circle)
      (basic-drawing n width height 0.5 7 4 drawing-unit-circle)
      (basic-drawing n width height 0.5 4.5 3 drawing-unit-circle)
      (basic-drawing n width height 0.5 2.5 2 drawing-unit-circle)
      (basic-drawing n width height 0.5 1 1 drawing-unit-circle))))



;;;Procedure:
;;;   squares
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing of concentric squares.
;;;   Additionally, it is a helper procedure for bg-shapes-draw.
;;;Produces:
;;;   squared, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   basic-drawing must be pre-defined.
;;;Postconditions:
;;;   squared is a drawing of 6 concentric squares.
;;;   (drawing-type squared) = drawing-unit-square(s)
;;;   (drawing-width squared) = width
;;;   (drawing-height squared) = height

(define squares
  (lambda (n width height)
     (drawing-group
      (basic-drawing n width height 0.5 13 5.8 drawing-unit-square)
      (basic-drawing n width height 0.5 10 5 drawing-unit-square)
      (basic-drawing n width height 0.5 7 4 drawing-unit-square)
      (basic-drawing n width height 0.5 4.5 3 drawing-unit-square)
      (basic-drawing n width height 0.5 2.5 2 drawing-unit-square)
      (basic-drawing n width height 0.5 1 1 drawing-unit-square))
     ))
 


;bg-colors produces a list of integer-encoded IRGB-colors for the background/ "canvas".

(define bg-colors
  (map color->irgb (list "white" "black" "linen")))




;Following code modified and inspired by code from:
;Laboratory: "Writing Your Own Procedures"
;http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/code/procedures-lab.rkt


;;;Procedure:
;;;   hoff-list
;;;Parameters:
;;;   width, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a list of horizontal offsets dependent on the "ring"
;;;      of the concentric shapes. I.E. The offsets correspond to the layer
;;;      on which the graphics/drawings will be placed.
;;;Produces:
;;;   hoffed, a list
;;;Preconditions:
;;;   [No additional]
;;;Postconditions:
;;;   (length hoffed) = 8

(define hoff-list
  (lambda (width layer)
    (cond
      [(= 0 layer)
       (list (round (* 6 (/ width 12)))
             (round (* 6.75 (/ width 12)))
             (round (* 7 (/ width 12)))
             (round (* 6.75 (/ width 12)))
             (round (* 6 (/ width 12)))
             (round (* 5.25 (/ width 12)))
             (round (* 5 (/ width 12)))
             (round (* 5.25 (/ width 12)))
             )]
      [(= 1 layer)
       (list (round (* 6 (/ width 12)))
             (round (* 7.5 (/ width 12)))
             (round (* 7.75 (/ width 12)))
             (round (* 7.5 (/ width 12)))
             (round (* 6 (/ width 12)))
             (round (* 4.5 (/ width 12)))
             (round (* 4.25 (/ width 12)))
             (round (* 4.5 (/ width 12))))]
      [(= 2 layer)
       (list (round (* 6 (/ width 12)))
             (round (* 8 (/ width 12)))
             (round (* 8.75 (/ width 12)))
             (round (* 8 (/ width 12)))
             (round (* 6 (/ width 12)))
             (round (* 4 (/ width 12)))
             (round (* 3.25 (/ width 12)))
             (round (* 4 (/ width 12))))]
      [else
       (list (round (* 6 (/ width 12)))
             (round (* 9 (/ width 12)))
             (round (* 10 (/ width 12)))
             (round (* 9 (/ width 12)))
             (round (* 6 (/ width 12)))
             (round (* 3 (/ width 12)))
             (round (* 2 (/ width 12)))
             (round (* 3 (/ width 12))))])))



;;;Procedure:
;;;   voff-list
;;;Parameters:
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a list of vertical offsets dependent on the "ring"
;;;      of the concentric shapes. I.E. The offsets correspond to the layer
;;;      on which the graphics/drawings will be placed.
;;;Produces:
;;;   voffed, a list
;;;Preconditions:
;;;   [No additional]
;;;Postconditions:
;;;   (length voffed) = 8

(define voff-list
  (lambda (height layer)
    (cond
      [(= 0 layer)
       (list (round (* 5 (/ height 12)))
             (round (* 5.5 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 6.5 (/ height 12)))
             (round (* 7 (/ height 12)))
             (round (* 6.5 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 5.5 (/ height 12))))]
      [(= 1 layer)
       (list (round (* 4.25 (/ height 12)))
             (round (* 5 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 7 (/ height 12)))
             (round (* 7.75 (/ height 12)))
             (round (* 7 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 5 (/ height 12))))]
      [(= 2 layer)
       (list (round (* 3 (/ height 12)))
             (round (* 4 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 8 (/ height 12)))
             (round (* 9 (/ height 12)))
             (round (* 8 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 4 (/ height 12))))]
      [else
       (list (round (* 2 (/ height 12)))
             (round (* 3 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 9 (/ height 12)))
             (round (* 10 (/ height 12)))
             (round (* 9 (/ height 12)))
             (round (* 6 (/ height 12)))
             (round (* 3 (/ height 12))))])))




;;;Procedure:
;;;   multiple-basic-draw
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;   hscale, a positive number
;;;   vscale, a positive number
;;;   color, a RGB color
;;;   proc, a drawing-shape procedure
;;;Purpose:
;;;   Helper procedure for project-eyes.
;;;   Generates drawings with the specified color 
;;;     and scaled appropriately according to the image-width and height.
;;;Produces:
;;;   many-basics, a drawing
;;;Preconditions:
;;;   proc must be pre-defined.
;;;   color must be a color Scheme recognizes
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions:
;;;   many-basics will draw the appropriate shape defined by proc.

(define multiple-basic-draw
  (lambda (width height hscale vscale color proc)
    (hscale-drawing (ceiling (/ width hscale))
                    (vscale-drawing (ceiling (/ height vscale))
                                    (recolor-drawing color proc)))))



;;;Procedure:
;;;   project-eyes
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing of an eye. 
;;;   Helper procedure for 8-eyes.
;;;Produces:
;;;   eyed, a drawing
;;;Preconditions:
;;;   multiple-basic-draw must be predefined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   eyed looks like an eye.

(define project-eyes
  (lambda (width height)
     (drawing-group
      (multiple-basic-draw width height 15 23 "darkgray" drawing-unit-circle)
      (multiple-basic-draw width height 16 24 "black" drawing-unit-circle)
      (vshift-drawing
       (ceiling (/ width 150))
       (multiple-basic-draw width height 17 30 "white" drawing-unit-circle))
      (multiple-basic-draw width height 30 30 "black" drawing-unit-circle)
      (hshift-drawing
       (* -1 (ceiling (/ width 200)))
       (vshift-drawing
        (* -1 (ceiling (/ height 200)))
        (multiple-basic-draw width height 100 110 "white" drawing-unit-circle))))))



;;;Procedure:
;;;   8-eyes
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a drawing of 8 eyes. 
;;;Produces:
;;;   eight-eyed, a drawing
;;;Preconditions:
;;;   project-eyes must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   eight-eyed is a drawing of eight eyes. 

(define 8-eyes
  (lambda (width height layer)
     (drawing-compose
      (map vshift-drawing (voff-list height layer)
           (map hshift-drawing (hoff-list width layer)
                (make-list 8 (project-eyes width height)))))))



; Bull-eyes--------------------------------------

;Following codes inspired and modified from code found in:
;Zachary Segall and Rae Kuhlman (2014)
;Assignment 3: Drawing Generally and Concisely


;;;Procedure:
;;;   bull-eye
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing of a bulls-eye to be rendered on an image.
;;;Produces:
;;;   target, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   target is a blue-and-orange colored bulls-eye.

(define bull-eye
  (lambda (width height)
    (letrec ([scale-ref (ceiling (/ height 20))]
             [orange-circle (recolor-drawing "darkorange" drawing-unit-circle)]
             [blue-circle (recolor-drawing "blue" drawing-unit-circle)]
             [scaling scale-drawing])
      (drawing-group (scaling scale-ref orange-circle)
                     (scaling (ceiling (/ (* 4 scale-ref) 5)) blue-circle)
                     (scaling (ceiling (/ (* 3 scale-ref) 5)) orange-circle)
                     (scaling (ceiling (/ (* 2 scale-ref) 5)) blue-circle)
                     (scaling (ceiling (/ scale-ref 5)) orange-circle)))))



;;;Procedure:
;;;   bulls-eyes
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a drawing of 8 bulls-eyes. 
;;;Produces:
;;;   bull-eyed, a drawing
;;;Preconditions:
;;;   bull-eye must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   bull-eyed is a drawing of 8 orange-and-blue bulls-eyes.

(define bulls-eyes
  (lambda (width height layer)
    (drawing-compose
     (map vshift-drawing (voff-list height layer)
          (map hshift-drawing (hoff-list width layer)
               (make-list 8 (bull-eye width height)))))))



; Spirals---------------------------------------------
(define canvas (image-new 500 500))


;Following code [spiral] is modified from code found in:
;J. Weinman and S. Rebelsky (2014)
;CSC-151-02 Reading: Iteration
;http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/readings/iteration-reading.html



;;;Procedure:
;;;   spiral
;;;Parameters:
;;;   turtle, a turtle
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Uses a turtle to draw a spiral-like graphic onto an image. 
;;;   Helper procedure for spirals.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define spiral
  (lambda (turtle width height)
    (let* ([turtles (map turtle-clone (make-list 6 turtle))]
           [actions
            (lambda (turtle angle)
              (turtle-forward! turtle 2)
              (turtle-turn! turtle angle))]
           [turtle-spiral!
            (lambda (turtle steps)
              (for-each (l-s actions turtle)
                        (list-drop (iota (+ 1 steps)) 1)))])
      (for-each (r-s turtle-set-color!"goldenrod") turtles)
      (turtle-down! turtle)
      (for-each turtle-turn! turtles (map (l-s * 60) (iota 6)))
      (for-each (r-s turtle-spiral! 40) turtles))))



;;;Procedure:
;;;   spirals
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to draw a series of spiral-like graphics onto an image. 
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   spiral must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with turtle-graphics.

(define spirals
  (lambda (n width height level layer image)
    (let ([turals (map turtle-new (make-list 8 image))])
      (for-each turtle-teleport! turals (hoff-list width layer) (map (r-s - (ceiling (/ height 25))) (voff-list height layer)))
      (for-each (lambda (turtle)
                  (spiral turtle width height)) turals))))

    

; Mini-hexagon--------------------------------------


;;;Procedure:
;;;   mini-hexagons
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to draw a hexagon graphic onto an image. 
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   position-get-hexagon must be defined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define mini-hexagons
  (lambda (n width height level layer image)
    (let* ([Leonardos (map (o (r-s turtle-set-color! "maroon") turtle-new) (make-list 8 image))])
      (for-each turtle-teleport! Leonardos (map (r-s - (ceiling (/ width 50))) (hoff-list width layer)) (map (r-s - (round (/ height 40))) (voff-list height layer)))
      (for-each (lambda (turtle)
                  (position-get-hexagon n turtle (ceiling (/ (+ width height) 70)) image level)) Leonardos))))




; Concentric-squares-----------------------------


;;;Procedure:
;;;   silly-square
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing of concentric squares to be rendered on an image.
;;;Produces:
;;;   sillied, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   sillied is a drawing of concentric squares.

(define silly-square
  (lambda (width height)
    (letrec ([scale-ref (ceiling (/ (+ width height) 40))]
             [pink-square
              (recolor-drawing "lightpink" drawing-unit-square)]
             [blue-square
              (recolor-drawing "skyblue" drawing-unit-square)]
             [yellow-square
              (recolor-drawing "yellow" drawing-unit-square)]
             [orange-square
              (recolor-drawing "orange" drawing-unit-square)])
      (drawing-group (scale-drawing scale-ref blue-square)
                     (scale-drawing (ceiling (/ (* 4 scale-ref) 5)) yellow-square)
                     (scale-drawing (ceiling (/ (* 3 scale-ref) 5)) orange-square)
                     (scale-drawing (ceiling (/ (* 2 scale-ref) 5)) pink-square)
                     (scale-drawing (ceiling (/ scale-ref 5)) blue-square)))))



;;;Procedure:
;;;   silly-squares
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a drawing of 8 copies of silly-square. 
;;;Produces:
;;;   sil-sq, a drawing
;;;Preconditions:
;;;   silly-square must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   sil-sq is a drawing of 8 copies of silly-square.

(define silly-squares
  (lambda (width height layer)
    (drawing-compose
     (map vshift-drawing (voff-list height layer)
          (map hshift-drawing (hoff-list width layer)
               (make-list 8 (silly-square width height)))))))



; Star -------------------------------------------


;;;Procedure:
;;;   star
;;;Parameters:
;;;   turtle, a turtle
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Uses a turtle to draw a star graphic onto an image. 
;;;   Helper procedure for stars.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;   turtle must be defined.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define star
  (lambda (turtle width height)
    (turtle-down! turtle)
    (turtle-set-color! turtle "goldenrod")
    (turtle-forward! turtle 1)))



;;;Procedure:
;;;   stars
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to create a graphic of 8 stars onto an image.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   star must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.


(define stars
  (lambda (n width height level layer image)
    (let ([starry (map turtle-new (make-list 8 image))])
      (for-each turtle-teleport! starry (hoff-list width layer) (voff-list height layer))
      (for-each (lambda (turtle)
                  (turtle-set-brush! turtle "2. Star" (round (* 17 (+ 1 layer))))) starry)
      ; add 1 brush-size
      (for-each (lambda (turtle)
                  (star turtle width height)) starry))))



; Mini-Explosion-------------------------------------



;;;Procedure:
;;;   mini-explosions
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to create a graphic of 8 
;;;      "explosion-like"/6-pointed star shapes onto an image.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   position-get-explosion must be predefined.
;;;   center-colors must be defined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define mini-explosions
  (lambda (n width height level layer image)
    (let ([turplosions (map turtle-new (make-list 8 image))])
      (for-each turtle-teleport! turplosions (hoff-list width layer) (map (r-s - (round (/ height 25))) (voff-list height layer)))
      (for-each (lambda (turtle)
                  (position-get-explosion n turtle (round (/ (+ width height) 100)) image level)) turplosions))))




;Swirls-----------------------------


;Following code modified from code found in:
;J. Weinman and S. Rebelsky (2014)
;CSC-151-02 Laboratory: Iteration
;http://www.cs.grinnell.edu/~weinman/courses/CSC151/2014F/labs/iteration-lab.html



;;;Procedure:
;;;   swirling
;;;Parameters:
;;;   turtle, a turtle
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Uses a turtle to create a graphic of a swirl onto an image.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   An image must exist.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define swirling
  (lambda (turtle width height)
    (let ([action1!
              (lambda (turtle distance)
                (turtle-forward! turtle distance)
                (turtle-turn! turtle 60))])
      (for-each (l-s action1! turtle)
                (list-drop (iota 16) 1)))))


;;;Procedure:
;;;   swirlings
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to create a graphic of 8 
;;;      swirly shapes onto an image.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   swirling must be predefined.
;;;   center-colors must be defined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define swirlings
  (lambda (n width height level layer image)
    (let* ([swirlies (map turtle-new (make-list 8 image))])
      (for-each turtle-set-color! swirlies (make-list 8 (irgb-complement (list-ref center-colors (mod n 5)))))
      (for-each turtle-teleport! swirlies (hoff-list width layer) (voff-list height layer))
      (for-each (lambda (turtle)
                  (swirling turtle width height)) swirlies))))




;Simple Saturn------------------


;;;Procedure:
;;;   saturn
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates a drawing to be rendered onto an image.
;;;Produces:
;;;   planet, a drawing
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   planet is a drawing of saturn.

(define saturn
  (lambda (width height)
    (letrec ([planet (lambda (color num)
                       (recolor-drawing color (scale-drawing (/ (+ width height) num) drawing-unit-circle)))]
             [ring (recolor-drawing "orange" (hscale-drawing (/ (+ width height) 25) drawing-unit-circle))])
      (drawing-group
       (planet "lavender" 50)
       (planet "purple" 55)
       (vscale-drawing (ceiling (/ (+ width height) 500)) ring)))))



;;;Procedure:
;;;   saturns
;;;Parameters:
;;;   width, a positive integer
;;;   height, a positive integer
;;;   layer, a non-negative integer
;;;Purpose:
;;;   Creates a drawing of 8 copies of saturn. 
;;;Produces:
;;;   planeted, a drawing
;;;Preconditions:
;;;   saturn must be predefined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   planeted is a drawing of 8 copies of saturn.

(define saturns
  (lambda (width height layer)
    (drawing-compose
     (map vshift-drawing (voff-list height layer)
          (map hshift-drawing (hoff-list width layer)
               (make-list 8 (saturn width height)))))))




;Diamond---------------------


;;;Procedure:
;;;   mini-diamonds
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   level, a positive integer
;;;   layer, a non-negative integer
;;;   image, an image
;;;Purpose:
;;;   Uses a turtle to create a graphic of 8 
;;;      diamond shapes onto an image.
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   position-get-diamond must be predefined.
;;;   center-colors must be defined.
;;;   hoff-list must be defined.
;;;   voff-list must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   An image must exist.
;;;Postconditions: 
;;;   An existing image is rendered with a turtle-graphic.

(define mini-diamonds
  (lambda (n width height level layer image)
    (let* ([turmonds (map turtle-new (make-list 8 image))])
      (for-each turtle-set-color! turmonds (make-list 8 (list-ref center-colors (mod n 5))))
      (for-each turtle-teleport! turmonds (hoff-list width layer) (map (r-s - (round (/ height 25))) (voff-list height layer)))
      (for-each (lambda (turtle)
                  (position-get-diamond n turtle (round (/ (+ width height) 50)) image level)) turmonds))))



;;;Procedure:
;;;   background
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;Purpose:
;;;   Sets the background color for the images produced on GIMP.
;;;Produces:
;;;   Nothing, called for its side-effect.
;;;Preconditions:
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;   bg-colors must be pre-defined.
;;;Postconditions:
;;;   background color of the canvas on GIMP should be one of
;;;      the three colors in bg-colors.

(define background
  (lambda (n)
    (context-set-bgcolor! (list-ref bg-colors (modulo n 3)))))



;A list of procedures for creating the background shapes.
(define bg-shapes
  (list squares circles hexagon 6-explosion diamond))

;A list of procedures for creating the foreground shapes.
(define shapes
  (list silly-squares 8-eyes saturns bulls-eyes mini-explosions
        mini-diamonds swirlings triangles stars spirals mini-hexagons))



;;;Procedure:
;;;   basic-render
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   image, an image
;;;Purpose:
;;;   Helper-procedure for my-project
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   [No additional]
;;;Postconditions: 
;;;   Refer to my-project

(define basic-render
  (lambda (n width height image)
    (drawing-render! ((list-ref shapes (modulo n 11)) width height (modulo n 4)) image)))


;;;Procedure:
;;;   turtle-render
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;   image, an image
;;;Purpose:
;;;   Helper-procedure for my-project
;;;Produces:
;;;   [Nothing. Called for its side-effect.]
;;;Preconditions:
;;;   [No additional]
;;;Postconditions: 
;;;   Refer to my-project

(define turtle-render
  (lambda (n width height image)
    ((list-ref shapes (modulo n 11)) n width height (modulo n 6) (modulo n 4) image)))


;;;Procedure:
;;;   my-project
;;;Parameters:
;;;   n, an integer between 0 and 999
;;;   width, a positive integer
;;;   height, a positive integer
;;;Purpose:
;;;   Creates an image. It is an image-series.
;;;Produces:
;;;   projected, an image
;;;Preconditions:
;;;   bg-shapes must be predefined.
;;;   shapes must be defined.
;;;   basic-render must be defined.
;;;   turtle-render must be defined.
;;;   GIMP must be enabled with (require gigls/unsafe) and the DBUS server.
;;;Postconditions: 
;;;   projected is different for every value of n provided.
;;;   (image-width projected) = width
;;;   (image-height projected) = height


(define my-project
  (lambda (n width height)
    (let* ([bg-image (image-new width height)])
      (background n)
      (cond   
        [(and (>= 1 (modulo n 5)) (= 0 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (basic-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (= 1 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (basic-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (= 2 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (basic-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (turtle-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (= 3 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (basic-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)
         (turtle-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (< 3 (modulo n 11) 8))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (turtle-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)((list-ref shapes (modulo (+ 1 n) 11)) n width height (modulo (+ 1 n) 6) (modulo (+ 1 n) 4) bg-image)
         (turtle-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (= 8 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (turtle-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)
         (turtle-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (>= 1 (modulo n 5)) (= 9 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (turtle-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
         
        [(and (>= 1 (modulo n 5)) (= 10 (modulo n 11)))
         (image-show bg-image)
         (drawing-render! ((list-ref bg-shapes (modulo n 5)) n width height) bg-image)
         (turtle-render  n width height bg-image)((list-ref shapes (modulo n 11)) n width height (modulo n 6) (modulo n 4) bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (< 1 (modulo n 5)) (= 0 (modulo n 11)))
         (image-show bg-image)
         ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
         (basic-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
         [(and (< 1 (modulo n 5)) (= 1 (modulo n 11)))
         (image-show bg-image)
         ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
         (basic-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (turtle-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
         
         [(and (< 1 (modulo n 5)) (= 2 (modulo n 11)))
          (image-show bg-image)
          ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
          (basic-render n width height bg-image)
          (basic-render (+ 1 n) width height bg-image)
          (turtle-render (+ 2 n) width height bg-image)
          (turtle-render (+ 3 n) width height bg-image)                     
          (image-refresh-display! bg-image)]
         
         [(and (< 1 (modulo n 5)) (= 3 (modulo n 11)))
          (image-show bg-image)
          ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
          (basic-render n width height bg-image)
          (turtle-render (+ 1 n) width height bg-image)
          (turtle-render (+ 2 n) width height bg-image)
          (turtle-render (+ 3 n) width height bg-image)
          (image-refresh-display! bg-image)]
         
         [(and (< 1 (modulo n 5)) (< 3 (modulo n 11) 8))
          (image-show bg-image)
          ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
          (turtle-render n width height bg-image)
          (turtle-render (+ 1 n) width height bg-image)
          (turtle-render (+ 2 n) width height bg-image)
          (turtle-render (+ 3 n) width height bg-image)
          (image-refresh-display! bg-image)]
         
         [(and (< 1 (modulo n 5)) (= 8 (modulo n 11)))
         (image-show bg-image)
         ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
         (turtle-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)
         (turtle-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
        
        [(and (< 1 (modulo n 5)) (= 9 (modulo n 11)))
         (image-show bg-image)
         ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
         (turtle-render n width height bg-image)
         (turtle-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]
         
        [else
         ;(and (>= 1 (modulo n 5)) (= 10 (modulo n 11)))
         (image-show bg-image)
         ((list-ref bg-shapes (modulo n 5)) n width height bg-image)
         (turtle-render n width height bg-image)
         (basic-render (+ 1 n) width height bg-image)
         (basic-render (+ 2 n) width height bg-image)
         (basic-render (+ 3 n) width height bg-image)
         (image-refresh-display! bg-image)]))))
