;;
;;
;; Squares fractal exercise sample solution.
;;

;; define the threshold - the minimum size square that is
;;  draw (anything smaller than this is not drawn recursively).
(define THRESH 5)

;;
;; draw-fractal-square consumes a posn (top left) and a width
;;   and produces true.
;;
;; (draw-fractal-square ipos width) 
;;  draws a fractal square with top left coordinates ipos (a posn)
;;  and width specified. 
;;  
;;  If the width specified is smaller than THRESH, the square
;;    is drawn using draw-solid-rect, otherwise the square is
;;    divided into 9 equal parts, 5 of which are drawn using
;;    draw-fractal-square (the other 4 are not drawn at all...)

(define (draw-fractal-square ipos width)
  (cond
   ;; if the width is small, just draw a square (in black)
   [(< width THRESH) (draw-solid-rect ipos width width 'black)]
   [else
	(local
	 (
	  ;; compute the x and y coordinates of 1/3 and 2/3 lines
	  ;; and 1/3 of the width
	  ;; x13 is one third of the way across the square
	  ;; x23 is two thirds of the way ...
	  (define x13 (+ (posn-x ipos) (* width 1/3)))
	  (define x23 (+ (posn-x ipos) (* width 2/3)))
	  (define y13 (+ (posn-y ipos) (* width 1/3)))
	  (define y23 (+ (posn-y ipos) (* width 2/3)))
	  ;; force width to be an int (keeps the drawing functions happy)
	  (define width3 (floor (/ width 3)))
	  )
	 (and
	  ;; draw each of the 5 squares
	  (draw-fractal-square ipos width3)
	  (draw-fractal-square (make-posn x23 (posn-y ipos)) width3)
	  (draw-fractal-square (make-posn x13 y13) width3)
	  (draw-fractal-square (make-posn (posn-x ipos) y23) width3)
	  (draw-fractal-square (make-posn x23 y23) width3)))]))

;; test code
(start 500 500)
(draw-fractal-square (make-posn 100 100) 300)