#lang racket
(require gigls/unsafe)
;;; Procedure: 
;;;   project
;;; Parameters:
;;;   n, an integer
;;;   width, an integer
;;;   height, an integer
;;; Purpose: 
;;;   Create a visually interesting image
;;; Produces: 
;;;   image, an image
;;; Preconditions:
;;;   0<=n<=999
;;;   width>0
;;;   height>0
;;; Postconditions:
;;;   images dimensions are width by height
;;;   image changes depending on what n is used
;;;   image scales along with changes in width and height
(define project
  (lambda (n width height)
    (let* (
           ;;;Variables 
           [house-width (/ width (+ 1 (modulo n 4)))]
           ;;;Circle dimensions 
           [c1-top (round (/ height (+ 2 (modulo (* n 14) 17))))]
           [c1-left (round (/ width (+ 1.1 (modulo n 9) (modulo (* n 9) 2))))]
           [c1-width (ceiling (/ (* 2 width) (* 3 (+ 1 (modulo n 8)))))]
           [c1-height (ceiling (/ (* 2 height) (* 3 (+ 1 (modulo n 8)))))]
           [c2-top (round (/ height (+ 2.5 (modulo (* n 18) 9))))]
           [c2-left (round (/ width (+ 1.1 (modulo n 7) (modulo (* n 22) 2))))]
           [c2-width (ceiling (/ (/ width 8) (+ 1 (modulo (* n 8) 4))))]
           [c2-height (ceiling (+ c2-width (/ (/ height 4) (+ 1 (modulo (* n 32) 3)))))]
           [c3-top (round (/ height (+ 2 (modulo (* n 4) 6))))]
           [c3-left (round (/ width (+ 1.1 (modulo n 6) (modulo (* n 7) 2))))]
           [c3-height (ceiling (+ 1 (/ height 30) (/ (/ height 9) (+ 1 (modulo (* n 17) 5)))))]
           [c3-width (ceiling (+ c3-height (/ (/ width 3) (+ 1 (modulo (* n 11) 2)))))]
           ;;;Background gradient
           [background
            (image-compute
             (lambda (col row) 
               (rgb-new 
                (+ (+ 40 (modulo (* n 13) 100)) (/ (* 255 row) height)) 
                (+ (modulo (* n 9) 100) (/ (* 255 row) height)) 
                (+ (+ 180 (modulo (* n 8) 70)) (* -1 (/ (* 255 row) height)))))
             width height)]
           ;;;House helper
           [make-houses 
            (lambda (n width height house-shift) 
              (image-select-polygon! background REPLACE 
                                     (position-new (round house-shift) height) 
                                     (position-new (round (+ house-shift (/ house-width 2))) (round (- height (+ (/ height 10) (/ height (* 5 (+ 1 (modulo n 4)))))))) 
                                     (position-new (round (+ house-shift house-width)) height))
              (context-set-fgcolor! "black")
              (image-fill-selection! background)
              (image-select-nothing! background))])
      ;;;Holes to the sky  
      (image-select-ellipse! background REPLACE c1-left c1-top c1-width c1-height)
      (image-select-ellipse! background ADD c2-left c2-top c2-width c2-height)
      (image-select-ellipse! background ADD c3-left c3-top c3-width c3-height)
      (context-set-fgcolor! (rgb-new 0 0 (+ 30 (modulo (* n 9) 50))))
      (image-fill-selection! background)
      (image-select-ellipse! background REPLACE c1-left (+ c1-top (/ height 75)) c1-width c1-height)
      (image-select-ellipse! background ADD c2-left (+ c2-top (/ height 75)) c2-width c2-height)
      (image-select-ellipse! background ADD c3-left (+ c3-top (/ height 75)) c3-width c3-height)
      (context-set-fgcolor! (rgb-new 0 0 (+ 50 (modulo (* n 9) 50))))
      (image-fill-selection! background)
      ;;;Stars
      (context-set-brush! "Sparks")
      (context-set-fgcolor! (rgb-new (+ 200 (modulo (* n 13) 55)) (+ 200 (modulo (* n 27) 55)) (+ 200 (modulo (* n 7) 55))))
      (gimp-context-set-paint-mode 6)
      (if (even? n)
          (image-draw-line! background c1-left c1-top (+ c1-left c1-width) (+ c1-top c1-height))
          (image-draw-line! background (+ c1-left c1-width) c1-top c1-left (+ c1-top c1-height)))
      (image-draw-line! background (+ c2-left (/ c2-width  2)) 0 (+ c2-left (/ c2-width 2)) height)
      (image-draw-line! background 0 (+ c3-top (/ c3-height 2)) width (+ c3-top (/ 2 c3-height)))
      (image-select-nothing! background)
      ;;;Houses
      (for-each make-houses 
                (make-list (+ 1 (modulo n 4)) n) 
                (make-list (+ 1 (modulo n 4)) width) 
                (make-list (+ 1 (modulo n 4)) height) 
                (map (l-s * house-width) (iota (+ 1 (modulo n 4)))))
      (image-select-nothing! background))))
