 
 (defn normal [nx ny nz] (.normal *applet* (float nx) (float ny) (float nz)))
 
-(defn no-smooth [] (.noSmooth *applet*))
+(defn no-smooth
+  "Draws all geometry with jagged (aliased) edges."
+  [] (.noSmooth *applet*))
 
 (defn no-stroke [] (.noStroke *applet*))
 


;; utility functions. clj-processing specific

(defn width [] (.getWidth *applet*))

(defmacro with-translation
  "Berforms body with translation, restores current transformation on exit."

                 :quad-strip QUAD_STRIP})

(defmacro begin-shape
  "Enables the creation of complex forms. begin-shape begins recording vertices
  for a shape and end-shape stops recording. Use the mode keyword to specify
  which shape create from the provided vertices. With no mode specified, the
  shape can be any irregular polygon.

  The available mode keywords are :points, :lines, :triangles, :triangle-fan,
                                  :triangle-strip, :quads, :quad-strip.


  After calling the begin-shape function, a series of vertex commands must
  follow. To stop drawing the shape, call end-shape. The vertex function with
  two parameters specifies a position in 2D and the vertex function with three
  parameters specifies a position in 3D. Each shape will be outlined with the
  current stroke color and filled with the fill color.

  Transformations such as translate, rotate, and scale do not work within
  begin-shape. It is also not possible to use other shapes, such as ellipse
  or rect within begin-shape."
  ([] `(.beginShape *applet*))
  ([mode]
     (let [kind (shapes-map mode)]
       `(.beginShape *applet* (int ~kind)))))

(defn bezier
  "Draws a Bezier curve on the screen. These curves are defined by a series of
  anchor and control points. The first two parameters specify the first anchor
  point and the last two parameters specify the other anchor point. The middle
  parameters specify the control points which define the shape of the curve."
  ([x1 y1 cx1 cy1 cx2 cy2 x2 y2]
     (.bezier *applet*
              (float x1) (float y1)
              (float cx1) (float cy1)
              (float cx2) (float cy2)
              (float x2) (float y2)))
  ([x1 y1 z1 cx1 cy1 cz1 cx2 cy2 cz2 x2 y2 z2]
     (.bezier *applet*
              (float x1) (float y1) (float z1)
              (float cx1) (float cy1) (float cz1)
              (float cx2) (float cy2) (float cz2)
              (float x2) (float y2) (float z2))))

(defn bezier-detail
  "Sets the resolution at which Beziers display. The default value is 20. This
  function is only useful when using the P3D or OPENGL renderer as the
  default (JAVA2D) renderer does not use this information."
  [detail]
  (.bezierDetail *applet* (int detail)))

(defn bezier-point
  "Evaluates the Bezier at point t for points a, b, c, d. The parameter t varies
  between 0 and 1, a and d are points on the curve, and b and c are the control
  points. This can be done once with the x coordinates and a second time with
  the y coordinates to get the location of a bezier curve at t."
  [a b c d t]
  (.bezierPoint *applet* (float a) (float b) (float c)
                (float d) (float t)))

(defn bezier-tangent
  "Calculates the tangent of a point on a Bezier curve.
  (See http://en.wikipedia.org/wiki/Tangent)"
  [a b c d t]
  (.bezierTangent *applet* (float a) (float b) (float c)
                  (float d) (float t)))

(defn bezier-vertex
  "Specifies vertex coordinates for Bezier curves. Each call to bezier-vertex
  defines the position of two control points and one anchor point of a Bezier
  curve, adding a new segment to a line or shape. The first time bezier-vertex
  is used within a begin-shape call, it must be prefaced with a call to
  vertex to set the first anchor point. This function must be used between
  begin-shape and end-shape and only when there is no parameter specified
  to begin-shape."
  ([cx1 cy1 cx2 cy2 x y]
     (.bezierVertex *applet*
                    (float cx1) (float cx1)
                    (float cx2) (float cy2)
                    (float x) (float y)))
  ([cx1 cy1 cz1 cx2 cy2 cz2 x y z]
     (.bezierVertex *applet*
                    (float cx1) (float cy1) (float cz1)
                    (float cx2) (float cy2) (float cz2)
                    (float x) (float y) (float z))))

;; $$binary

(def ^{:private true}
  blend-map {:blend BLEND
             :add ADD
             :subtract SUBTRACT
             :darkest DARKEST
             :lightest LIGHTEST
             :difference DIFFERENCE
             :exclusion EXCLUSION
             :multiply MULTIPLY
             :screen SCREEN
             :overlay OVERLAY
             :hard-light HARD_LIGHT
             :soft-light SOFT_LIGHT
             :dodge DODGE
             :burn BURN})

(defn- resolve-mode
  [mode]
  (if (keyword? mode)
    (get blend-map mode)
    mode))

(defmacro blend
  "Blends a region of pixels from one image into another (or in itself again) with full alpha channel support."
  ([x y width height dx dy dwidth dheight mode]
     (let [mode (resolve-mode mode)]
       `(.blend *applet* (int x) (int y) (int width) (int height)
                (int dx) (int dy) (int dwidth) (int dheight) (int ~mode))))
  ([^PImage src x y width height dx dy dwidth dheight mode]
     (let [mode (resolve-mode mode)]
       `(.blend *applet* src (int x) (int y) (int width) (int height)
                (int dx) (int dy) (int dwidth) (int dheight) (int ~mode)))))

(defn blend-color
  [c1 c2 mode] (PApplet/blendColor (int c1) (int c2) (int mode)))
