                :alpha (int 4)
                :cmyk (int 5)})
 
-(defn
-  ^{:requires-bindings true
-    :processing-name "colorMode()"
-    :category "Color"
-    :subcategory "Creating & Reading"
-    :added "1.0"}
-  color-mode
-  "Changes the way Processing interprets color data. Available modes
-  are :rgb and :hsb.By default, the parameters for fill, stroke,
-  background, and color are defined by values between 0 and 255 using
-  the :rgb color model. The color-mode fn is used to change the
-  numerical range used for specifying colors and to switch color
-  systems. For example, calling
-  (color-mode :rgb 1.0) will specify that values are specified between
-  0 and 1. The limits for defining colors are altered by setting the
-  parameters range1, range2, range3, and range 4."
-  ([mode]
-     (let [mode (resolve-constant-key mode color-modes)]
-       (.colorMode (current-graphics) (int mode))))
-  ([mode max]
-     (let [mode (resolve-constant-key mode color-modes)]
-       (.colorMode (current-graphics) (int mode) (float max))))
-  ([mode max-x max-y max-z]
-     (let [mode (resolve-constant-key mode color-modes)]
-       (.colorMode (current-graphics) (int mode) (float max-x) (float max-y) (float max-z))))
-  ([mode max-x max-y max-z max-a]
-     (let [mode (resolve-constant-key mode color-modes)]
-       (.colorMode (current-graphics) (int mode) (float max-x) (float max-y) (float max-z) (float max-a)))))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "constrain()"
-    :category "Math"
-    :subcategory "Calculation"
-    :added "1.0"}
-  constrain-float
-  "Constrains a value to not exceed a maximum and minimum value. All
-  args are cast to floats."
-  [amt low high]
-  (PApplet/constrain (float amt) (float low) (float high)))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "constrain()"
-    :category "Math"
-    :subcategory "Calculation"
-    :added "1.0"}
-  constrain-int
-  "Constrains a value to not exceed a maximum and minimum value. All
-  args are cast to ints."
-  [amt low high]
-  (PApplet/constrain (int amt) (int low) (int high)))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "constrain()"
-    :category "Math"
-    :subcategory "Calculation"
-    :added "1.0"}
-  constrain
-  "Constrains a value to not exceed a maximum and minimum value."
-  [amt low high]
-  (if (int-like? amt)
-    (constrain-int amt low high)
-    (constrain-float amt low high)))
-
-#+clj
-(defn
-  ^{:requires-bindings true
-    :processing-name "copy()"
-    :category "Image"
-    :subcategory "Pixels"
-    :added "1.0"}
-  copy
-  "Copies a region of pixels from the one image to another. If src-img
-  is not specified it defaults to current-graphics. If dest-img is not
-  specified - it defaults to current-graphics. If the source
-  and destination regions aren't the same size, it will automatically
-  resize the source pixels to fit the specified target region. No
-  alpha information is used in the process, however if the source
-  image has an alpha channel set, it will be copied as well. "
-  ([[sx sy swidth sheight] [dx dy dwidth dheight]]
-     (copy (current-graphics) (current-graphics) [sx sy swidth sheight] [dx dy dwidth dheight]))
-
-  ([^PImage src-img [sx sy swidth sheight] [dx dy dwidth dheight]]
-     (copy src-img (current-graphics) [sx sy swidth sheight] [dx dy dwidth dheight]))
-
-  ([^PImage src-img ^PImage dest-img [sx sy swidth sheight] [dx dy dwidth dheight]]
-     (.copy dest-img src-img (int sx) (int sy) (int swidth) (int sheight)
-            (int dx) (int dy) (int dwidth) (int dheight))))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "cos()"
-    :category "Math"
-    :subcategory "Trigonometry"
-    :added "1.0"}
-  cos
-  "Calculates the cosine of an angle. This function expects the values
-  of the angle parameter to be provided in radians (values from 0 to
-  Math/PI*2). Values are returned in the range -1 to 1."
-  [angle]
-  (PApplet/cos (float angle)))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name nil
-    :category "Typography"
-    :subcategory "Loading & Displaying"
-    :added "1.0"}
-  font-available?
-  "Returns true if font (specified as a string) is available on this
-  system, false otherwise"
-  [font-str]
-  (if (some #{font-str} (available-fonts))
-    true
-    false))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "createFont()"
-    :category "Typography"
-    :subcategory "Loading & Displaying"
-    :added "1.0"}
-  create-font
-  "Dynamically converts a font to the format used by Processing (a
-  PFont) from either a font name that's installed on the computer, or
-  from a .ttf or .otf file inside the sketches 'data' folder. This
-  function is an advanced feature for precise control.
-
-  Use available-fonts to obtain the names for the fonts recognized by
-  the computer and are compatible with this function.
-
-  The size parameter states the font size you want to generate. The
-  smooth parameter specifies if the font should be antialiased or not,
-  and the charset parameter is an array of chars that specifies the
-  characters to generate.
-
-  This function creates a bitmapped version of a font It loads a font
-  by name, and converts it to a series of images based on the size of
-  the font. When possible, the text function will use a native font
-  rather than the bitmapped version created behind the scenes with
-  create-font. For instance, when using the default renderer
-  setting (JAVA2D), the actual native version of the font will be
-  employed by the sketch, improving drawing quality and
-  performance. With the :p2d, :p3d, and :opengl renderer settings, the
-  bitmapped version will be used. While this can drastically improve
-  speed and appearance, results are poor when exporting if the sketch
-  does not include the .otf or .ttf file, and the requested font is
-  not available on the machine running the sketch."
-  ([name size] (.createFont (current-applet) (str name) (float size)))
-  ([name size smooth] (.createFont (current-applet) (str name) (float size) smooth))
-  ([name size smooth ^chars charset]
-     (.createFont (current-applet) (str name) (float size) smooth charset)))
-
-#+clj
-(defn
-  ^{:requires-bindings true
-    :processing-name "createGraphics()"
-    :category "Image"
-    :subcategory "Rendering"
-    :added "1.0"}
-  create-graphics
-  "Creates and returns a new PGraphics object of the types :p2d, :p3d,
-  :java2d, :pdf. By default :java2d is used. Use this class if you
-  need to draw into an off-screen graphics buffer. It's not possible
-  to use create-graphics with the :opengl renderer, because it doesn't
-  allow offscreen use. The :pdf renderer requires the filename parameter.
-
-  It's important to call any drawing commands between (.beginDraw graphics) and
-  (.endDraw graphics) statements or use with-graphics macro. This is also true
-  for any commands that affect drawing, such as smooth or color-mode.
-
-  If you're using :pdf renderer - don't forget to call (.dispose graphics)
-  as last command inside with-graphics macro, otherwise graphics won't be
-  saved.
-
-  Unlike the main drawing surface which is completely opaque, surfaces
-  created with create-graphics can have transparency. This makes it
-  possible to draw into a graphics and maintain the alpha channel. By
-  using save to write a PNG or TGA file, the transparency of the
-  graphics object will be honored. Note that transparency levels are
-  binary: pixels are either complete opaque or transparent. This means
-  that text characters will be opaque blocks."
-  ([w h]
-     (.createGraphics (current-applet) (int w) (int h)))
-  ([w h renderer]
-     (.createGraphics (current-applet) (int w) (int h) (resolve-renderer renderer)))
-  ([w h renderer path]
-     (.createGraphics (current-applet) (int w) (int h) (resolve-renderer renderer)
-                      (absolute-path path))))
-
 #+clj
 (def ^{:private true}
   image-formats {:rgb PApplet/RGB
                 :argb PApplet/ARGB
                 :alpha PApplet/ALPHA})
-
-#+clj
-(defn
-  ^{:requires-bindings true
-    :processing-name "createImage()"
-    :category "Image"
-    :subcategory nil
-    :added "1.0"}
-  create-image
-  "Creates a new PImage (the datatype for storing images). This
-  provides a fresh buffer of pixels to play with. Set the size of the
-  buffer with the width and height parameters. The format parameter
-  defines how the pixels are stored. See the PImage reference for more
-  information.
-
-  Possible formats: :rgb, :argb, :alpha (grayscale alpha channel)
-
-  Prefer using create-image over initialising new PImage instances
-  directly."
-  [w h format]
-  (let [format (resolve-constant-key format image-formats)]
-    (.createImage (current-applet) (int w) (int h) (int format))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "fillColor()"
-    :category "Color"
-    :subcategory "Creating & Reading"}
-  current-fill
-  "Return the current fill color."
-  []
-  (.fillColor (current-graphics)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "strokeColor()"
-    :category "Color"
-    :subcategory "Creating & Reading"}
-  current-stroke
-  "Return the current stroke color."
-  []
-  (.strokeColor (current-graphics)))
-
-#+clj
-(def ^{:private true}
-  cursor-modes {:arrow PConstants/ARROW
-                :cross PConstants/CROSS
-                :hand PConstants/HAND
-                :move PConstants/MOVE
-                :text PConstants/TEXT
-                :wait PConstants/WAIT})
-
-#+clj
-(defn
-  ^{:requires-bindings true
-    :processing-name "cursor()"
-    :category "Environment"
-    :subcategory nil
-    :added "1.0"}
-  cursor
-  "Sets the cursor to a predefined symbol or makes it
-  visible if already hidden (after no-cursor was called).
-
-  Available modes: :arrow, :cross, :hand, :move, :text, :wait
-
-  See cursor-image for specifying a generic image as the cursor
-  symbol."
-  ([] (.cursor (current-applet)))
-  #+clj ([cursor-mode] (.cursor (current-applet) (int (resolve-constant-key cursor-mode cursor-modes)))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "cursor()"
-    :category "Environment"
-    :subcategory nil
-    :added "1.0"}
-    cursor-image
-  "Set the cursor to a predefined image. The horizontal and vertical
-  active spots of the cursor may be specified with hx and hy.
-  It is recommended to make the size 16x16 or 32x32 pixels."
-  ([^PImage img] (.cursor (current-applet) img))
-  ([^PImage img hx hy] (.cursor (current-applet) img (int hx) (int hy))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "curve()"
-    :category "Shape"
-    :subcategory "Curves"
-    :added "1.0"}
-  curve
-  "Draws a curved line on the screen. The first and second parameters
-  specify the beginning control point and the last two parameters
-  specify the ending control point. The middle parameters specify the
-  start and stop of the curve. Longer curves can be created by putting
-  a series of curve fns together or using curve-vertex. An additional
-  fn called curve-tightness provides control for the visual quality of
-  the curve. The curve fn is an implementation of Catmull-Rom
-  splines."
-  ([x1 y1 x2 y2 x3 y3 x4 y4]
-     (.curve (current-graphics)
-             (float x1) (float y1)
-             (float x2) (float y2)
-             (float x3) (float y3)
-             (float x4) (float y4)))
-  ([x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4]
-     (.curve (current-graphics)
-             (float x1) (float y1) (float z1)
-             (float x2) (float y2) (float z2)
-             (float x3) (float y3) (float z3)
-             (float x4) (float y4) (float z4))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "curveDetail()"
-    :category "Shape"
-    :subcategory "Curves"
-    :added "1.0"}
-  curve-detail
-  "Sets the resolution at which curves 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]
-  (.curveDetail (current-graphics) (int detail)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "curvePoint()"
-    :category "Shape"
-    :subcategory "Curves"
-    :added "1.0"}
-  curve-point
-  "Evalutes the curve 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 c
-  and 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 curve at t."
-  [a b c d t]
-  (.curvePoint (current-graphics) (float a) (float b) (float c) (float d) (float t)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "curveTangent()"
-    :category "Shape"
-    :subcategory "Curves"
-    :added "1.0"}
-  curve-tangent
-  "Calculates the tangent of a point on a curve.
-  See: http://en.wikipedia.org/wiki/Tangent"
-  [a b c d t]
-  (.curveTangent (current-graphics) (float a) (float b) (float c) (float d) (float t)))
-
-(defn
-  ^{:requires-bindings true
-   :processing-name "curveTightness()"
-    :category "Shape"
-    :subcategory "Curves"
-    :added "1.0"}
-  curve-tightness
-  "Modifies the quality of forms created with curve and
-  curve-vertex. The parameter squishy determines how the curve fits
-  to the vertex points. The value 0.0 is the default value for
-  squishy (this value defines the curves to be Catmull-Rom splines)
-  and the value 1.0 connects all the points with straight
-  lines. Values within the range -5.0 and 5.0 will deform the curves
-  but will leave them recognizable and as values increase in
-  magnitude, they will continue to deform."
-  [ti]
-  (.curveTightness (current-graphics) (float ti)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "curveVertex()"
-    :category "Shape"
-    :subcategory "Vertex"
-    :added "1.0"}
-  curve-vertex
-  "Specifies vertex coordinates for curves. This function may only be
-  used between begin-shape and end-shape and only when there is no
-  mode keyword specified to begin-hape. The first and last points in a
-  series of curve-vertex lines will be used to guide the beginning and
-  end of a the curve. A minimum of four points is required to draw a
-  tiny curve between the second and third points. Adding a fifth point
-  with curveVertex will draw the curve between the second, third, and
-  fourth points. The curveVertex function is an implementation of
-  Catmull-Rom splines."
-  ([x y] (.curveVertex (current-graphics) (float x) (float y)))
-  ([x y z] (.curveVertex (current-graphics) (float x) (float y) (float z))))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "day()"
-    :category "Input"
-    :subcategory "Time & Date"
-    :added "1.0"}
-  day
-  "Get the current day of the month (1 through 31)."
-  []
-  (PApplet/day))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "degrees()"
-    :category "Math"
-    :subcategory "Trigonometry"
-    :added "1.0"}
-  degrees
-  "Converts a radian measurement to its corresponding value in
-  degrees. Radians and degrees are two ways of measuring the same
-  thing. There are 360 degrees in a circle and (* 2 Math/PI) radians
-  in a circle. For example, (= 90° (/ Math/PI 2) 1.5707964). All
-  trigonometric methods in Processing require their parameters to be
-  specified in radians."
-  [radians]
-  (PApplet/degrees (float radians)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "delay()"
-    :category "Structure"
-    :subcategory nil
-    :added "1.0"}
-  delay-frame
-  "Forces the program to stop running for a specified time. Delay
-  times are specified in thousandths of a second, therefore the
-  function call (delay 3000) will stop the program for three
-  seconds. Because the screen is updated only at the end of draw,
-  the program may appear to 'freeze', because the screen will not
-  update when the delay fn is used. This function has no affect
-  inside setup."
-  [freeze-ms]
-  (.delay (current-applet) (int freeze-ms)))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "directionalLight()"
-    :category "Lights, Camera"
-    :subcategory "Lights"
-    :added "1.0"}
-  directional-light
-  "Adds a directional light. Directional light comes from one
-  direction and is stronger when hitting a surface squarely and weaker
-  if it hits at a a gentle angle. After hitting a surface, a
-  directional lights scatters in all directions. Lights need to be
-  included in the draw fn to remain persistent in a looping
-  program. Placing them in the setup fn of a looping program will cause
-  them to only have an effect the first time through the loop. The
-  affect of the r, g, and b parameters is determined by the current
-  color mode. The nx, ny, and nz parameters specify the direction the
-  light is facing. For example, setting ny to -1 will cause the
-  geometry to be lit from below (the light is facing directly upward)"
-  [r g b nx ny nz]
-  (.directionalLight (current-graphics) (float r) (float g) (float b)
-                     (float nx) (float ny) (float nz)))
-
-#+clj
-(defn
-  ^{:requires-bindings false
-    :processing-name "dist()"
-    :category "Math"
-    :subcategory "Calculation"
-    :added "1.0"}
-  dist
-  "Calculates the distance between two points"
-  ([x1 y1 x2 y2] (PApplet/dist (float x1) (float y1) (float x2) (float y2)))
-  ([x1 y1 z1 x2 y2 z2] (PApplet/dist (float x1) (float y1) (float z1)
-                               (float x2) (float y2) (float z2))))
-
-(defn
-  ^{:requires-bindings true
-    :processing-name "ellipse()"
-    :category "Shape"
-    :subcategory "2D Primitives"
-    :added "1.0"}
-  ellipse
-  "Draws an ellipse (oval) in the display window. An ellipse with an
-  equal width and height is a circle.  The origin may be changed with
-  the ellipse-mode function"
-  [x y width height]
-  (.ellipse (current-graphics) (float x) (float y) (float width) (float height)))
 
 #+clj
 (def ^{:private true}

                    :model PApplet/MODEL})

#+clj
(defn
  ^{:requires-bindings true
    :processing-name "strokeCap()"
    :category "Shape"
    :subcategory "Attributes"
    :added "1.0"}
  stroke-cap
  "Sets the style for rendering line endings. These ends are either
  squared, extended, or rounded and specified with the corresponding
  parameters :square, :project, and :round. The default cap is :round."
  [cap-mode]
  (let [cap-mode (resolve-constant-key cap-mode stroke-cap-modes)]
    (.strokeCap (current-graphics) (int cap-mode))))

#+clj
(def ^{:private true}
  stroke-join-modes {:miter PConstants/MITER
                     :bevel PConstants/BEVEL
                     :round PConstants/ROUND})

#+clj
(defn
  ^{:requires-bindings true
    :processing-name "strokeJoin()"
    :category "Shape"
    :subcategory "Attributes"
    :added "1.0"}
  stroke-join
  "Sets the style of the joints which connect line
  segments. These joints are either mitered, beveled, or rounded and
  specified with the corresponding parameters :miter, :bevel, and
  :round. The default joint is :miter.

  This function is not available with the :p2d, :p3d, or :opengl
  renderers."
  [join-mode]
  (let [join-mode (resolve-constant-key join-mode stroke-join-modes)]
    (.strokeJoin (current-graphics) (int join-mode))))

(defn
  ^{:requires-bindings true
    :processing-name "strokeWeight()"
    :category "Shape"
    :subcategory "Attributes"
    :added "1.0"}
  stroke-weight
  "Sets the width of the stroke used for lines, points, and the border
  around shapes. All widths are set in units of pixels. "
  [weight]
  (.strokeWeight (current-graphics) (float weight)))

#+clj
(defn
  ^{:requires-bindings false
    :processing-name "tan()"
    :category "Math"
    :subcategory "Trigonometry"
    :added "1.0"}
  tan
  "Calculates the ratio of the sine and cosine of an angle. This
  function expects the values of the angle parameter to be provided in
  radians (values from 0 to PI*2). Values are returned in the range
  infinity to -infinity."
  [angle]
  (PApplet/tan (float angle)))

#+clj
(defn
  ^{:requires-bindings true
    :category "Environment"
    :subcategory nil
    :added "1.5.0"}
  target-frame-rate
  "Returns the target framerate specified with the fn frame-rate"
  []
  @(quil.applet/target-frame-rate))

(defn
  ^{:requires-bindings true
    :processing-name "text()"
    :category "Typography"
    :subcategory "Loading & Displaying"
    :added "1.0"}
  text-char
  "Draws a char to the screen in the specified position. See text fn
  for more details."
  ([c x y] (.text (current-graphics) (char c) (float x) (float y)))
  ([c x y z] (.text (current-graphics) (char c) (float x) (float y) (float z))))

(defn
  ^{:requires-bindings true
    :processing-name "text()"
    :category "Typography"
    :subcategory "Loading & Displaying"
    :added "1.0"}
  text-num
  "Draws a number to the screen in the specified position. See text fn
  for more details."
  ([num x y] (.text (current-graphics) (float num) (float x) (float y)))
  ([num x y z] (.text (current-graphics) (float num) (float x) (float y) (float z))))

(defn
  ^{:requires-bindings true
    :processing-name "text()"
    :category "Typography"
    :subcategory "Loading & Displaying"
    :added "1.0"}
  text
  "Draws text to the screen in the position specified by the x and y
  parameters and the optional z parameter. A default font will be used
  unless a font is set with the text-font fn. Change the color of the
  text with the fill fn. The text displays in relation to the
  text-align fn, which gives the option to draw to the left, right, and
  center of the coordinates.

  The x1, y1, x2 and y2 parameters define a
  rectangular area to display within and may only be used with string
  data. For text drawn inside a rectangle, the coordinates are
  interpreted based on the current rect-mode setting."
  ([^String s x y] (.text (current-graphics) s (float x) (float y)))
  ([^String s x y z] (.text (current-graphics) s (float x) (float y) (float z)))
  ([^String s x1 y1 x2 y2] (.text (current-graphics) s (float x1) (float y1) (float x2) (float y2))))

#+clj
(def ^{:private true}

                            :baseline PApplet/BASELINE})

#+clj
(def ^{:private true}
  text-modes {:model PConstants/MODEL
              :shape PConstants/SHAPE})

#+clj
(def ^{:private true}
  texture-modes {:image PApplet/IMAGE
                 :normal PApplet/NORMAL})

#+clj
(def ^{:private true}
  texture-wrap-modes {:clamp PApplet/CLAMP
                      :repeat PApplet/REPEAT})

;;; Useful trig constants
#+clj (def PI  (float Math/PI))
