#lang racket
(require gigls/unsafe)

;;; Procedure:
;;;   lines!
;;; Parameters:
;;;   image, an image
;;;   n, an integer
;;;   sx1, a real number ("source" x1)
;;;   sy1, a real number ("source" y1)
;;;   sx2, a real number 
;;;   sy2, a real number
;;;   tx1, a real number ("target" x1)
;;;   ty1, a real number
;;;   tx2, a real number
;;;   ty2, a real number
;;; Purpose:
;;;   Draw n lines with the current brush and color.  
;;;   One endpoint of each line is evenly spaced along the line 
;;;     from (sx1,xy1) to (sx2,sy2). 
;;;   The other endpoint of each line is evenly spaced along the
;;;      line from (tx1,ty1) to (tx2,ty2).
;;; Preconditions:
;;;   n >= 2
;;; Postconditions:
;;;   The image contains n additional lines.
;;;   One line is from (xs1,ys1) to (xt1,yt1)
;;;   One line is from (xs2,ys2) to (xt2,yt2)
;;;   The remaining lines are evenly distributed between those points.
(define lines!
  (lambda (image n sx1 sy1 sx2 sy2 tx1 ty1 tx2 ty2)
    (let ([delta-sx (/ (- sx2 sx1) (- n 1))]
          [delta-sy (/ (- sy2 sy1) (- n 1))]
          [delta-tx (/ (- tx2 tx1) (- n 1))]
          [delta-ty (/ (- ty2 ty1) (- n 1))])
      (for-each (lambda (i)
                  (image-draw-line! image
                                    (+ sx1 (* i delta-sx))
                                    (+ sy1 (* i delta-sy))
                                    (+ tx1 (* i delta-tx))
                                    (+ ty1 (* i delta-ty))))
                (iota n)))))

; (image-draw-line2! image sx sy tx ty)
;   Draw a line from (sx,sy) to (tx,ty)
;   Display waht we're doing
(define image-draw-line2! 
  (lambda (image sx sy tx ty)
    (display (list 'image-draw-line! image sx sy tx ty)) (newline)
    (image-draw-line! image sx sy tx ty)))

; EXAMPLE-WIDTH
;   The width we use for example images
(define EXAMPLE-WIDTH 300)

; EXAMPLE-HEIGHT
;   The height we use for example images
(define EXAMPLE-HEIGHT 300)

; EXAMPLE-LEFT
;   The left edge of the example image
(define EXAMPLE-LEFT 0)

; EXAMPLE-TOP
;   The top edge of the example image
(define EXAMPLE-TOP 0)

; EXAMPLE-RIGHT
;   The right edge of the example image
(define EXAMPLE-RIGHT (- EXAMPLE-WIDTH 1))

; EXAMPLE-BOTTOM
;   Te bottom edge of the example image
(define EXAMPLE-BOTTOM (- EXAMPLE-HEIGHT 1))



; (example n sx1 sy1 sx2 sy2 tx1 ty1 tx2 ty2)
;   Build an image using those points
(define example
  (lambda (n sx1 sy1 sx2 sy2 tx1 ty1 tx2 ty2)
    (let ([image (image-show (image-new EXAMPLE-WIDTH EXAMPLE-HEIGHT))])
      (context-set-brush! "2. Hardness 050" 3)
      (context-set-fgcolor! "black")
      (lines! image n sx1 sy1 sx2 sy2 tx1 ty1 tx2 ty2)
      (context-set-brush! "2. Hardness 100" 5)
      (context-set-fgcolor! "red")
      (image-draw-line! image sx1 sy1 sx2 sy2)
      (context-set-fgcolor! "blue")
      (image-draw-line! image tx1 ty1 tx2 ty2))))

; (examplep n sx1% sy1% sx2% sy2% tx1% ty1% tx2% ty2%)
;   Like example, but coords are now expressed as a percent of width or height
(define examplep
  (lambda (n sx1% sy1% sx2% sy2% tx1% ty1% tx2% ty2%)
    (example n
             (* EXAMPLE-WIDTH sx1%) (* EXAMPLE-HEIGHT sy1%)
             (* EXAMPLE-WIDTH sx2%) (* EXAMPLE-HEIGHT sy2%)
             (* EXAMPLE-WIDTH tx1%) (* EXAMPLE-HEIGHT ty1%)
             (* EXAMPLE-WIDTH tx2%) (* EXAMPLE-HEIGHT ty2%))))

; (examplep 20 .25 0 .75 0 0 1 1 1)
; (examplep 20 0 .25 .25 0 0 1 1 0)
; (examplep 20 0 0 0 1 1 1 1 0)

; (example1 n)
;   the mesh from exam 1
(define example1
  (lambda (n)
    (examplep n
              0 0
              0 1
              0 1
              1 1)))

; (example2 n)
;   an interesting variant of the mesh
(define example2
  (lambda (n)
    (examplep n
              0 1
              1 0
              1 0
              1 1)))

; (example3
