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

;;; File:
;;;   geometric-art-lab.scm
;;; Authors:
;;;   Janet Davis
;;;   Samuel A. Rebelsky
;;;   Jerod Weinman
;;;   YOUR NAME HERE
;;; Summary:
;;;   Code for the lab entitled "Geometric Art"

;;; Procedure:
;;;   position->color
;;; Parameters:
;;;   col, an integer
;;;   row, an integer
;;; Purpose:
;;;   Compute a color based on col and row.
;;; Produces:
;;;   color, an RGB color
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   Different col/row combinations are likely to give different colors.
;;;   Nearby col/row combinations may give similar colors.
(define position->color
  (lambda (col row)
    (rgb-new (+ 128 (* 128 (sin (* pi row 0.0625))))
             (+ 128 (* 128 (cos (* pi col 0.0625))))
             (+ 128 (* 128 (sin (* pi (+ row col) 0.0625)))))))

;;; Procedure:
;;;   draw-circle!
;;; Parameters:
;;;   image, an image
;;;   col, an integer
;;;   row, an integer
;;;   radius, an integer
;;; Purpose:
;;;   Draws a circle with the specified in the current brush and color, centered at (col,row).
;;; Produces:
;;;   [Nothing; Called for the side effect]
;;; Preconditions:
;;;   0 <= col < (image-width image)
;;;   0 <= row < (image-height image)
;;;   0 < radius
;;; Postconditions:
;;;   The image now contains the specified circle.  (The circle may not be visible.)
(define draw-circle!
  (lambda (image col row radius)
    (image-select-ellipse! image REPLACE
                           (- col radius) (- row radius)
                           (+ radius radius) (+ radius radius))
    (image-stroke-selection! image)
    (image-select-nothing! image)))

;;; Procedure:
;;;   draw-three-parallel-lines!
;;; Parameters:
;;;   image, an image
;;;   start-col, an integer
;;;   start-row, an integer
;;;   end-col, an integer
;;;   end-row, an integer
;;;   hoffset, an integer
;;;   voffset, an integer
;;; Purpose:
;;;   Draw three parallel lines, with the first from (start-col,start-row)
;;;     to (end-col,end-row) and the starting point of the next two offset
;;;     horizontally by hoffset (and 2*hoffset) and vertically by voffset
;;;     (and 2*voffset).
;;; Produces:
;;;   [Nothing; Called for the side effect.]
;;; Preconditions:
;;;   All three parallel lines can be drawn on the image.
;;; Postcondtions:
;;;   The image has been appropriately modified.
(define draw-three-parallel-lines!
  (lambda (image start-col start-row end-col end-row hoffset voffset)
    (image-draw-line! image 
                      start-col start-row 
                      end-col end-row)
    (image-draw-line! image 
                      (+ hoffset start-col) (+ voffset start-row)
                      (+ hoffset end-col) (+ voffset end-row))
    (image-draw-line! image 
                      (+ (* 2 hoffset) start-col) (+ (* 2 voffset) start-row)
                      (+ (* 2 hoffset) end-col) (+ (* 2 voffset) end-row))))

;;; Procedure:
;;;   draw-parallel-lines!
;;; Parameters:
;;;   image, an image
;;;   n, an integer
;;;   start-col, an integer
;;;   start-row, an integer
;;;   end-col, an integer
;;;   end-row, an integer
;;;   hoffset, an integer
;;;   voffset, an integer
;;; Purpose:
;;;   Draw n parallel lines, with the first from (start-col,start-row)
;;;     to (end-col,end-row) and each subsequent one offset by the 
;;;     appropriate multiple of hoffset and voffset.
;;; Produces:
;;;   [Nothing; Called for the side effect.]
;;; Preconditions:
;;;   All parallel lines can be drawn on the image.
;;; Postcondtions:
;;;   The image has been appropriately modified.
(define draw-parallel-lines!
  (lambda (image n start-col start-row end-col end-row hoffset voffset)
    (cond
      ((> n 0)
       (image-draw-line! image 
                         start-col start-row 
                         end-col end-row)
       (draw-parallel-lines! image
                             (- n 1)
                             (+ hoffset start-col) (+ voffset start-row)
                             (+ hoffset end-col) (+ voffset end-row)
                             hoffset voffset)))))

(define draw-colored-parallel-lines!
  (lambda (image n start-col start-row end-col end-row hoff voff)
    (cond
      ((> n 0)
       (context-set-fgcolor! (position->color start-col start-row))
       (image-draw-line! image 
                         start-col start-row 
                         end-col end-row)
       (draw-colored-parallel-lines! image
                                     (- n 1)
                                     (+ hoff start-col) (+ voff start-row)
                                     (+ hoff end-col) (+ voff end-row)
                                     hoff voff)))))

;;; Procedure:
;;;   draw-sin-with-parallel-lines!
;;; Parameters:
;;;   image, an image
;;;   n, an integer
;;;   offset, an integer
;;;   start-col, an integer
;;;   mid-row, an integer
;;; Purpose:
;;;   Draw a sequence of parallel lines, with the height of the
;;;   parallel line dependent on the column.
;;; Produces:
;;;   [Nothing, called for the side effect.]
(define draw-sin-with-parallel-lines!
  (lambda (image n offset start-col mid-row)
     (cond 
       ((> n 0)
        (image-draw-line! image 
                          start-col mid-row
                          start-col (+ mid-row (* mid-row (sin (* n pi 0.1)))))
        (draw-sin-with-parallel-lines! 
           image (- n 1) offset 
           (+ start-col offset) mid-row)))))

;;; Procedure:
;;;   draw-parallel-lines-with-decreasing-spacing!
;;; Parameters:
;;;   image, an image
;;;   col, an integer
;;;   start-row, an integer
;;;   end-row, an integer
;;;   spacing
;;;   close-enough
;;; Purpose:
;;;   Draw a sequence of vertical lines (each running from start-row
;;;   to end-row) starting at col, then spaced by spacing from col,
;;;   then by spacing/2 from that column, then spacing/4 from that
;;;   column, and so on and so forth until the distance between columns 
;;;   is less than or equal to close-enough.
;;; Produces:
;;;   [Nothing. Called for the side effects.]
(define draw-parallel-lines-with-decreasing-spacing!
  (lambda (image col start-row end-row spacing close-enough)
    (image-draw-line! image col start-row col end-row)
    (when (> spacing close-enough)
      (draw-parallel-lines-with-decreasing-spacing!
       image 
       (+ col spacing) start-row end-row
       (* spacing 0.5)
       close-enough))))

