/*
** Copyright (c) 2012 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
var WebGLTestUtils = (function() {
"use strict";

/**
 * Wrapped logging function.
 * @param {string} msg The message to log.
 */
var log = function(msg) {
  bufferedLogToConsole(msg);
};

/**
 * Wrapped logging function.
 * @param {string} msg The message to log.
 */
var error = function(msg) {
  // For the time being, diverting this to window.console.log rather
  // than window.console.error. If anyone cares enough they can
  // generalize the mechanism in js-test-pre.js.
  log(msg);
};

/**
 * Turn off all logging.
 */
var loggingOff = function() {
  log = function() {};
  error = function() {};
};

/**
 * Converts a WebGL enum to a string.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} value The enum value.
 * @return {string} The enum as a string.
 */
var glEnumToString = function(gl, value) {
  // Avoid returning "NO_ERROR" if the arguments are totally wrong.
  if (gl.NO_ERROR === undefined || value === undefined) {
    return undefined;
  }
  // Optimization for the most common enum:
  if (value === gl.NO_ERROR) {
    return "NO_ERROR";
  }
  for (var p in gl) {
    if (gl[p] == value) {
      if (p == 'drawingBufferWidth' || p == 'drawingBufferHeight') {
        continue;
      }
      return p;
    }
  }
  return "0x" + Number(value).toString(16);
};

var lastError = "";

/**
 * Returns the last compiler/linker error.
 * @return {string} The last compiler/linker error.
 */
var getLastError = function() {
  return lastError;
};

/**
 * Whether a haystack ends with a needle.
 * @param {string} haystack String to search
 * @param {string} needle String to search for.
 * @param {boolean} True if haystack ends with needle.
 */
var endsWith = function(haystack, needle) {
  return haystack.substr(haystack.length - needle.length) === needle;
};

/**
 * Whether a haystack starts with a needle.
 * @param {string} haystack String to search
 * @param {string} needle String to search for.
 * @param {boolean} True if haystack starts with needle.
 */
var startsWith = function(haystack, needle) {
  return haystack.substr(0, needle.length) === needle;
};

/**
 * A vertex shader for a single texture.
 * @type {string}
 */
var simpleTextureVertexShader = [
  'attribute vec4 vPosition;',
  'attribute vec2 texCoord0;',
  'varying vec2 texCoord;',
  'void main() {',
  '    gl_Position = vPosition;',
  '    texCoord = texCoord0;',
  '}'].join('\n');

/**
 * A fragment shader for a single texture.
 * @type {string}
 */
var simpleTextureFragmentShader = [
  'precision mediump float;',
  'uniform sampler2D tex;',
  'varying vec2 texCoord;',
  'void main() {',
  '    gl_FragData[0] = texture2D(tex, texCoord);',
  '}'].join('\n');

/**
 * A fragment shader for a single cube map texture.
 * @type {string}
 */
var simpleCubeMapTextureFragmentShader = [
  'precision mediump float;',
  'uniform samplerCube tex;',
  'uniform highp int face;',
  'varying vec2 texCoord;',
  'void main() {',
  // Transform [0, 1] -> [-1, 1]
  '    vec2 texC2 = (texCoord * 2.) - 1.;',
  // Transform 2d tex coord. to each face of TEXTURE_CUBE_MAP coord.
  '    vec3 texCube = vec3(0., 0., 0.);',
  '    if (face == 34069) {',         // TEXTURE_CUBE_MAP_POSITIVE_X
  '        texCube = vec3(1., -texC2.y, -texC2.x);',
  '    } else if (face == 34070) {',  // TEXTURE_CUBE_MAP_NEGATIVE_X
  '        texCube = vec3(-1., -texC2.y, texC2.x);',
  '    } else if (face == 34071) {',  // TEXTURE_CUBE_MAP_POSITIVE_Y
  '        texCube = vec3(texC2.x, 1., texC2.y);',
  '    } else if (face == 34072) {',  // TEXTURE_CUBE_MAP_NEGATIVE_Y
  '        texCube = vec3(texC2.x, -1., -texC2.y);',
  '    } else if (face == 34073) {',  // TEXTURE_CUBE_MAP_POSITIVE_Z
  '        texCube = vec3(texC2.x, -texC2.y, 1.);',
  '    } else if (face == 34074) {',  // TEXTURE_CUBE_MAP_NEGATIVE_Z
  '        texCube = vec3(-texC2.x, -texC2.y, -1.);',
  '    }',
  '    gl_FragData[0] = textureCube(tex, texCube);',
  '}'].join('\n');

/**
 * A vertex shader for a single texture.
 * @type {string}
 */
var noTexCoordTextureVertexShader = [
  'attribute vec4 vPosition;',
  'varying vec2 texCoord;',
  'void main() {',
  '    gl_Position = vPosition;',
  '    texCoord = vPosition.xy * 0.5 + 0.5;',
  '}'].join('\n');

/**
 * A vertex shader for a uniform color.
 * @type {string}
 */
var simpleVertexShader = [
  'attribute vec4 vPosition;',
  'void main() {',
  '    gl_Position = vPosition;',
  '}'].join('\n');

/**
 * A fragment shader for a uniform color.
 * @type {string}
 */
var simpleColorFragmentShader = [
  'precision mediump float;',
  'uniform vec4 u_color;',
  'void main() {',
  '    gl_FragData[0] = u_color;',
  '}'].join('\n');

/**
 * A fragment shader for a uniform color.
 * @type {string}
 */
var simpleColorFragmentShaderESSL300 = [
  '#version 300 es',
  'precision mediump float;',
  'out vec4 out_color;',
  'uniform vec4 u_color;',
  'void main() {',
  '    out_color = u_color;',
  '}'].join('\n');

/**
 * A vertex shader for vertex colors.
 * @type {string}
 */
var simpleVertexColorVertexShader = [
  'attribute vec4 vPosition;',
  'attribute vec4 a_color;',
  'varying vec4 v_color;',
  'void main() {',
  '    gl_Position = vPosition;',
  '    v_color = a_color;',
  '}'].join('\n');

/**
 * A fragment shader for vertex colors.
 * @type {string}
 */
var simpleVertexColorFragmentShader = [
  'precision mediump float;',
  'varying vec4 v_color;',
  'void main() {',
  '    gl_FragData[0] = v_color;',
  '}'].join('\n');

/**
 * Creates a program, attaches shaders, binds attrib locations, links the
 * program and calls useProgram.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<!WebGLShader|string>} shaders The shaders to
 *        attach, or the source, or the id of a script to get
 *        the source from.
 * @param {!Array.<string>} opt_attribs The attribs names.
 * @param {!Array.<number>} opt_locations The locations for the attribs.
 * @param {boolean} opt_logShaders Whether to log shader source.
 */
var setupProgram = function(
    gl, shaders, opt_attribs, opt_locations, opt_logShaders) {
  var realShaders = [];
  var program = gl.createProgram();
  var shaderCount = 0;
  for (var ii = 0; ii < shaders.length; ++ii) {
    var shader = shaders[ii];
    var shaderType = undefined;
    if (typeof shader == 'string') {
      var element = document.getElementById(shader);
      if (element) {
        if (element.type != "x-shader/x-vertex" && element.type != "x-shader/x-fragment")
          shaderType = ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER;
        shader = loadShaderFromScript(gl, shader, shaderType, undefined, opt_logShaders);
      } else if (endsWith(shader, ".vert")) {
        shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER, undefined, opt_logShaders);
      } else if (endsWith(shader, ".frag")) {
        shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER, undefined, opt_logShaders);
      } else {
        shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER, undefined, opt_logShaders);
      }
    } else if (opt_logShaders) {
      throw 'Shader source logging requested but no shader source provided';
    }
    if (shader) {
      ++shaderCount;
      gl.attachShader(program, shader);
    }
  }
  if (shaderCount != 2) {
    error("Error in compiling shader");
    return null;
  }
  if (opt_attribs) {
    for (var ii = 0; ii < opt_attribs.length; ++ii) {
      gl.bindAttribLocation(
          program,
          opt_locations ? opt_locations[ii] : ii,
          opt_attribs[ii]);
    }
  }
  gl.linkProgram(program);

  // Check the link status
  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!linked) {
      // something went wrong with the link
      lastError = gl.getProgramInfoLog (program);
      error("Error in program linking:" + lastError);

      gl.deleteProgram(program);
      return null;
  }

  gl.useProgram(program);
  return program;
};

/**
 * Creates a program, attaches shader, sets up trasnform feedback varyings,
 * binds attrib locations, links the program and calls useProgram.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<!WebGLShader|string>} shaders The shaders to
 *        attach, or the source, or the id of a script to get
 *        the source from.
 * @param {!Array.<string>} varyings The transform feedback varying names.
 * @param {number} bufferMode The mode used to capture the varying variables.
 * @param {!Array.<string>} opt_attribs The attribs names.
 * @param {!Array.<number>} opt_locations The locations for the attribs.
 * @param {boolean} opt_logShaders Whether to log shader source.
 */
var setupTransformFeedbackProgram = function(
    gl, shaders, varyings, bufferMode, opt_attribs, opt_locations, opt_logShaders, opt_skipCompileStatus) {
  var realShaders = [];
  var program = gl.createProgram();
  var shaderCount = 0;
  for (var ii = 0; ii < shaders.length; ++ii) {
    var shader = shaders[ii];
    var shaderType = undefined;
    if (typeof shader == 'string') {
      var element = document.getElementById(shader);
      if (element) {
        if (element.type != "x-shader/x-vertex" && element.type != "x-shader/x-fragment")
          shaderType = ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER;
        shader = loadShaderFromScript(gl, shader, shaderType, undefined, opt_logShaders, opt_skipCompileStatus);
      } else if (endsWith(shader, ".vert")) {
        shader = loadShaderFromFile(gl, shader, gl.VERTEX_SHADER, undefined, opt_logShaders, opt_skipCompileStatus);
      } else if (endsWith(shader, ".frag")) {
        shader = loadShaderFromFile(gl, shader, gl.FRAGMENT_SHADER, undefined, opt_logShaders, opt_skipCompileStatus);
      } else {
        shader = loadShader(gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER, undefined, opt_logShaders, undefined, undefined, opt_skipCompileStatus);
      }
    } else if (opt_logShaders) {
      throw 'Shader source logging requested but no shader source provided';
    }
    if (shader) {
      ++shaderCount;
      gl.attachShader(program, shader);
    }
  }
  if (shaderCount != 2) {
    error("Error in compiling shader");
    return null;
  }

  if (opt_attribs) {
    for (var ii = 0; ii < opt_attribs.length; ++ii) {
      gl.bindAttribLocation(
          program,
          opt_locations ? opt_locations[ii] : ii,
          opt_attribs[ii]);
    }
  }

  gl.transformFeedbackVaryings(program, varyings, bufferMode);

  gl.linkProgram(program);

  // Check the link status
  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!linked) {
      // something went wrong with the link
      lastError = gl.getProgramInfoLog (program);
      error("Error in program linking:" + lastError);

      gl.deleteProgram(program);
      return null;
  }

  gl.useProgram(program);
  return program;
};

/**
 * Creates a simple texture program.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @return {WebGLProgram}
 */
var setupNoTexCoordTextureProgram = function(gl) {
  return setupProgram(gl,
                      [noTexCoordTextureVertexShader, simpleTextureFragmentShader],
                      ['vPosition'],
                      [0]);
};

/**
 * Creates a simple texture program.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_texcoordLocation The attrib location for texture coords.
 * @return {WebGLProgram}
 */
var setupSimpleTextureProgram = function(
    gl, opt_positionLocation, opt_texcoordLocation) {
  opt_positionLocation = opt_positionLocation || 0;
  opt_texcoordLocation = opt_texcoordLocation || 1;
  return setupProgram(gl,
                      [simpleTextureVertexShader, simpleTextureFragmentShader],
                      ['vPosition', 'texCoord0'],
                      [opt_positionLocation, opt_texcoordLocation]);
};

/**
 * Creates a simple cube map texture program.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_texcoordLocation The attrib location for texture coords.
 * @return {WebGLProgram}
 */
var setupSimpleCubeMapTextureProgram = function(
    gl, opt_positionLocation, opt_texcoordLocation) {
  opt_positionLocation = opt_positionLocation || 0;
  opt_texcoordLocation = opt_texcoordLocation || 1;
  return setupProgram(gl,
                      [simpleTextureVertexShader, simpleCubeMapTextureFragmentShader],
                      ['vPosition', 'texCoord0'],
                      [opt_positionLocation, opt_texcoordLocation]);
};

/**
 * Creates a simple vertex color program.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_vertexColorLocation The attrib location
 *        for vertex colors.
 * @return {WebGLProgram}
 */
var setupSimpleVertexColorProgram = function(
    gl, opt_positionLocation, opt_vertexColorLocation) {
  opt_positionLocation = opt_positionLocation || 0;
  opt_vertexColorLocation = opt_vertexColorLocation || 1;
  return setupProgram(gl,
                      [simpleVertexColorVertexShader, simpleVertexColorFragmentShader],
                      ['vPosition', 'a_color'],
                      [opt_positionLocation, opt_vertexColorLocation]);
};

/**
 * Creates a simple color program.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @return {WebGLProgram}
 */
var setupSimpleColorProgram = function(gl, opt_positionLocation) {
  opt_positionLocation = opt_positionLocation || 0;
  return setupProgram(gl,
                      [simpleVertexShader, simpleColorFragmentShader],
                      ['vPosition'],
                      [opt_positionLocation]);
};

/**
 * Creates buffers for a textured unit quad and attaches them to vertex attribs.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_texcoordLocation The attrib location for texture coords.
 * @param {!Object} various options. See setupQuad for details.
 * @return {!Array.<WebGLBuffer>} The buffer objects that were
 *      created.
 */
var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation, options) {
  return setupQuadWithTexCoords(gl, [ 0.0, 0.0 ], [ 1.0, 1.0 ],
                                opt_positionLocation, opt_texcoordLocation,
                                options);
};

/**
 * Creates buffers for a textured quad with specified lower left
 * and upper right texture coordinates, and attaches them to vertex
 * attribs.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} lowerLeftTexCoords The texture coordinates for the lower left corner.
 * @param {!Array.<number>} upperRightTexCoords The texture coordinates for the upper right corner.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_texcoordLocation The attrib location for texture coords.
 * @param {!Object} various options. See setupQuad for details.
 * @return {!Array.<WebGLBuffer>} The buffer objects that were
 *      created.
 */
var setupQuadWithTexCoords = function(
    gl, lowerLeftTexCoords, upperRightTexCoords,
    opt_positionLocation, opt_texcoordLocation, options) {
  var defaultOptions = {
    positionLocation: opt_positionLocation || 0,
    texcoordLocation: opt_texcoordLocation || 1,
    lowerLeftTexCoords: lowerLeftTexCoords,
    upperRightTexCoords: upperRightTexCoords
  };
  if (options) {
    for (var prop in options) {
      defaultOptions[prop] = options[prop]
    }
  }
  return setupQuad(gl, defaultOptions);
};

/**
 * Makes a quad with various options.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Object} options
 *
 * scale: scale to multiply unit quad values by. default 1.0.
 * positionLocation: attribute location for position.
 * texcoordLocation: attribute location for texcoords.
 *     If this does not exist no texture coords are created.
 * lowerLeftTexCoords: an array of 2 values for the
 *     lowerLeftTexCoords.
 * upperRightTexCoords: an array of 2 values for the
 *     upperRightTexCoords.
 */
var setupQuad = function(gl, options) {
  var positionLocation = options.positionLocation || 0;
  var scale = options.scale || 1;

  var objects = [];

  var vertexObject = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
       1.0 * scale ,  1.0 * scale,
      -1.0 * scale ,  1.0 * scale,
      -1.0 * scale , -1.0 * scale,
       1.0 * scale ,  1.0 * scale,
      -1.0 * scale , -1.0 * scale,
       1.0 * scale , -1.0 * scale]), gl.STATIC_DRAW);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
  objects.push(vertexObject);

  if (options.texcoordLocation !== undefined) {
    var llx = options.lowerLeftTexCoords[0];
    var lly = options.lowerLeftTexCoords[1];
    var urx = options.upperRightTexCoords[0];
    var ury = options.upperRightTexCoords[1];

    vertexObject = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        urx, ury,
        llx, ury,
        llx, lly,
        urx, ury,
        llx, lly,
        urx, lly]), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(options.texcoordLocation);
    gl.vertexAttribPointer(options.texcoordLocation, 2, gl.FLOAT, false, 0, 0);
    objects.push(vertexObject);
  }

  return objects;
};

/**
 * Creates a program and buffers for rendering a textured quad.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for
 *        position. Default = 0.
 * @param {number} opt_texcoordLocation The attrib location for
 *        texture coords. Default = 1.
 * @param {!Object} various options. See setupQuad for details.
 * @return {!WebGLProgram}
 */
var setupTexturedQuad = function(
    gl, opt_positionLocation, opt_texcoordLocation, options) {
  var program = setupSimpleTextureProgram(
      gl, opt_positionLocation, opt_texcoordLocation);
  setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation, options);
  return program;
};

/**
 * Creates a program and buffers for rendering a color quad.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {!Object} various options. See setupQuad for details.
 * @return {!WebGLProgram}
 */
var setupColorQuad = function(gl, opt_positionLocation, options) {
  opt_positionLocation = opt_positionLocation || 0;
  var program = setupSimpleColorProgram(gl, opt_positionLocation);
  setupUnitQuad(gl, opt_positionLocation, 0, options);
  return program;
};

/**
 * Creates a program and buffers for rendering a textured quad with
 * specified lower left and upper right texture coordinates.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} lowerLeftTexCoords The texture coordinates for the lower left corner.
 * @param {!Array.<number>} upperRightTexCoords The texture coordinates for the upper right corner.
 * @param {number} opt_positionLocation The attrib location for position.
 * @param {number} opt_texcoordLocation The attrib location for texture coords.
 * @return {!WebGLProgram}
 */
var setupTexturedQuadWithTexCoords = function(
    gl, lowerLeftTexCoords, upperRightTexCoords,
    opt_positionLocation, opt_texcoordLocation) {
  var program = setupSimpleTextureProgram(
      gl, opt_positionLocation, opt_texcoordLocation);
  setupQuadWithTexCoords(gl, lowerLeftTexCoords, upperRightTexCoords,
                         opt_positionLocation, opt_texcoordLocation);
  return program;
};

/**
 * Creates a program and buffers for rendering a textured quad with
 * a cube map texture.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} opt_positionLocation The attrib location for
 *        position. Default = 0.
 * @param {number} opt_texcoordLocation The attrib location for
 *        texture coords. Default = 1.
 * @return {!WebGLProgram}
 */
var setupTexturedQuadWithCubeMap = function(
    gl, opt_positionLocation, opt_texcoordLocation) {
  var program = setupSimpleCubeMapTextureProgram(
      gl, opt_positionLocation, opt_texcoordLocation);
  setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation, undefined);
  return program;
};

/**
 * Creates a unit quad with only positions of a given resolution.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} gridRes The resolution of the mesh grid,
 *     expressed in the number of quads across and down.
 * @param {number} opt_positionLocation The attrib location for position.
 */
var setupIndexedQuad = function (
    gl, gridRes, opt_positionLocation, opt_flipOddTriangles) {
  return setupIndexedQuadWithOptions(gl,
    { gridRes: gridRes,
      positionLocation: opt_positionLocation,
      flipOddTriangles: opt_flipOddTriangles
    });
};

/**
 * Creates a quad with various options.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Object} options The options. See below.
 * @return {!Array.<WebGLBuffer>} The created buffers.
 *     [positions, <colors>, indices]
 *
 * Options:
 *   gridRes: number of quads across and down grid.
 *   positionLocation: attrib location for position
 *   flipOddTriangles: reverse order of vertices of every other
 *       triangle
 *   positionOffset: offset added to each vertex
 *   positionMult: multipier for each vertex
 *   colorLocation: attrib location for vertex colors. If
 *      undefined no vertex colors will be created.
 */
var setupIndexedQuadWithOptions = function (gl, options) {
  var positionLocation = options.positionLocation || 0;
  var objects = [];

  var gridRes = options.gridRes || 1;
  var positionOffset = options.positionOffset || 0;
  var positionMult = options.positionMult || 1;
  var vertsAcross = gridRes + 1;
  var numVerts = vertsAcross * vertsAcross;
  var positions = new Float32Array(numVerts * 3);
  var indices = new Uint16Array(6 * gridRes * gridRes);
  var poffset = 0;

  for (var yy = 0; yy <= gridRes; ++yy) {
    for (var xx = 0; xx <= gridRes; ++xx) {
      positions[poffset + 0] = (-1 + 2 * xx / gridRes) * positionMult + positionOffset;
      positions[poffset + 1] = (-1 + 2 * yy / gridRes) * positionMult + positionOffset;
      positions[poffset + 2] = 0;

      poffset += 3;
    }
  }

  var buf = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buf);
  gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
  objects.push(buf);

  if (options.colorLocation !== undefined) {
    var colors = new Float32Array(numVerts * 4);
    for (var yy = 0; yy <= gridRes; ++yy) {
      for (var xx = 0; xx <= gridRes; ++xx) {
        if (options.color !== undefined) {
          colors[poffset + 0] = options.color[0];
          colors[poffset + 1] = options.color[1];
          colors[poffset + 2] = options.color[2];
          colors[poffset + 3] = options.color[3];
        } else {
          colors[poffset + 0] = xx / gridRes;
          colors[poffset + 1] = yy / gridRes;
          colors[poffset + 2] = (xx / gridRes) * (yy / gridRes);
          colors[poffset + 3] = (yy % 2) * 0.5 + 0.5;
        }
        poffset += 4;
      }
    }

    buf = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buf);
    gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
    gl.enableVertexAttribArray(options.colorLocation);
    gl.vertexAttribPointer(options.colorLocation, 4, gl.FLOAT, false, 0, 0);
    objects.push(buf);
  }

  var tbase = 0;
  for (var yy = 0; yy < gridRes; ++yy) {
    var index = yy * vertsAcross;
    for (var xx = 0; xx < gridRes; ++xx) {
      indices[tbase + 0] = index + 0;
      indices[tbase + 1] = index + 1;
      indices[tbase + 2] = index + vertsAcross;
      indices[tbase + 3] = index + vertsAcross;
      indices[tbase + 4] = index + 1;
      indices[tbase + 5] = index + vertsAcross + 1;

      if (options.flipOddTriangles) {
        indices[tbase + 4] = index + vertsAcross + 1;
        indices[tbase + 5] = index + 1;
      }

      index += 1;
      tbase += 6;
    }
  }

  buf = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
  objects.push(buf);

  return objects;
};

/**
 * Returns the constructor for a typed array that corresponds to the given
 * WebGL type.
 * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
 * @param {number} type The WebGL type (eg, gl.UNSIGNED_BYTE)
 * @return {!Constructor} The typed array constructor that
 *      corresponds to the given type.
 */
var glTypeToTypedArrayType = function(gl, type) {
  switch (type) {
    case gl.BYTE:
      return window.Int8Array;
    case gl.UNSIGNED_BYTE:
      return window.Uint8Array;
    case gl.SHORT:
      return window.Int16Array;
    case gl.UNSIGNED_SHORT:
    case gl.UNSIGNED_SHORT_5_6_5:
    case gl.UNSIGNED_SHORT_4_4_4_4:
    case gl.UNSIGNED_SHORT_5_5_5_1:
      return window.Uint16Array;
    case gl.INT:
      return window.Int32Array;
    case gl.UNSIGNED_INT:
    case gl.UNSIGNED_INT_5_9_9_9_REV:
    case gl.UNSIGNED_INT_10F_11F_11F_REV:
    case gl.UNSIGNED_INT_2_10_10_10_REV:
    case gl.UNSIGNED_INT_24_8:
      return window.Uint32Array;
    case gl.HALF_FLOAT:
    case 0x8D61:  // HALF_FLOAT_OES
      return window.Uint16Array;
    case gl.FLOAT:
      return window.Float32Array;
    default:
      throw 'unknown gl type ' + glEnumToString(gl, type);
  }
};

/**
 * Returns the number of bytes per component for a given WebGL type.
 * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
 * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE)
 * @return {number} The number of bytes per component.
 */
var getBytesPerComponent = function(gl, type) {
  switch (type) {
    case gl.BYTE:
    case gl.UNSIGNED_BYTE:
      return 1;
    case gl.SHORT:
    case gl.UNSIGNED_SHORT:
    case gl.UNSIGNED_SHORT_5_6_5:
    case gl.UNSIGNED_SHORT_4_4_4_4:
    case gl.UNSIGNED_SHORT_5_5_5_1:
    case gl.HALF_FLOAT:
    case 0x8D61:  // HALF_FLOAT_OES
      return 2;
    case gl.INT:
    case gl.UNSIGNED_INT:
    case gl.UNSIGNED_INT_5_9_9_9_REV:
    case gl.UNSIGNED_INT_10F_11F_11F_REV:
    case gl.UNSIGNED_INT_2_10_10_10_REV:
    case gl.UNSIGNED_INT_24_8:
    case gl.FLOAT:
      return 4;
    default:
      throw 'unknown gl type ' + glEnumToString(gl, type);
  }
};

/**
 * Returns the number of typed array elements per pixel for a given WebGL
 * format/type combination. The corresponding typed array type can be determined
 * by calling glTypeToTypedArrayType.
 * @param {!WebGLRenderingContext} gl A WebGLRenderingContext.
 * @param {GLenum} format The WebGL format (eg, gl.RGBA)
 * @param {GLenum} type The WebGL type (eg, gl.UNSIGNED_BYTE)
 * @return {number} The number of typed array elements per pixel.
 */
var getTypedArrayElementsPerPixel = function(gl, format, type) {
  switch (type) {
    case gl.UNSIGNED_SHORT_5_6_5:
    case gl.UNSIGNED_SHORT_4_4_4_4:
    case gl.UNSIGNED_SHORT_5_5_5_1:
      return 1;
    case gl.UNSIGNED_BYTE:
      break;
    default:
      throw 'not a gl type for color information ' + glEnumToString(gl, type);
  }

  switch (format) {
    case gl.RGBA:
      return 4;
    case gl.RGB:
      return 3;
    case gl.LUMINANCE_ALPHA:
      return 2;
    case gl.LUMINANCE:
    case gl.ALPHA:
      return 1;
    default:
      throw 'unknown gl format ' + glEnumToString(gl, format);
  }
};

/**
 * Fills the given texture with a solid color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!WebGLTexture} tex The texture to fill.
 * @param {number} width The width of the texture to create.
 * @param {number} height The height of the texture to create.
 * @param {!Array.<number>} color The color to fill with.
 *        where each element is in the range 0 to 255.
 * @param {number} opt_level The level of the texture to fill. Default = 0.
 * @param {number} opt_format The format for the texture.
 * @param {number} opt_internalFormat The internal format for the texture.
 */
var fillTexture = function(gl, tex, width, height, color, opt_level, opt_format, opt_type, opt_internalFormat) {
  opt_level = opt_level || 0;
  opt_format = opt_format || gl.RGBA;
  opt_type = opt_type || gl.UNSIGNED_BYTE;
  opt_internalFormat = opt_internalFormat || opt_format;
  var pack = gl.getParameter(gl.UNPACK_ALIGNMENT);
  var numComponents = color.length;
  var bytesPerComponent = getBytesPerComponent(gl, opt_type);
  var rowSize = numComponents * width * bytesPerComponent;
  // See equation 3.10 in ES 2.0 spec and equation 3.13 in ES 3.0 spec for paddedRowLength calculation.
  // k is paddedRowLength.
  // n is numComponents.
  // l is width.
  // a is pack.
  // s is bytesPerComponent.
  var paddedRowLength;
  if (bytesPerComponent >= pack)
    paddedRowLength = numComponents * width;
  else
    paddedRowLength = Math.floor((rowSize + pack - 1) / pack) * pack / bytesPerComponent;
  var size = width * numComponents + (height - 1) * paddedRowLength;
  var buf = new (glTypeToTypedArrayType(gl, opt_type))(size);
  for (var yy = 0; yy < height; ++yy) {
    var off = yy * paddedRowLength;
    for (var xx = 0; xx < width; ++xx) {
      for (var jj = 0; jj < numComponents; ++jj) {
        buf[off++] = color[jj];
      }
    }
  }
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texImage2D(
      gl.TEXTURE_2D, opt_level, opt_internalFormat, width, height, 0,
      opt_format, opt_type, buf);
};

/**
 * Creates a texture and fills it with a solid color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} width The width of the texture to create.
 * @param {number} height The height of the texture to create.
 * @param {!Array.<number>} color The color to fill with. A 4 element array
 *        where each element is in the range 0 to 255.
 * @return {!WebGLTexture}
 */
var createColoredTexture = function(gl, width, height, color) {
  var tex = gl.createTexture();
  fillTexture(gl, tex, width, height, color);
  return tex;
};

var ubyteToFloat = function(c) {
  return c / 255;
};

var ubyteColorToFloatColor = function(color) {
  var floatColor = [];
  for (var ii = 0; ii < color.length; ++ii) {
    floatColor[ii] = ubyteToFloat(color[ii]);
  }
  return floatColor;
};

/**
 * Sets the "u_color" uniform of the current program to color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} color 4 element array of 0-1 color
 *      components.
 */
var setFloatDrawColor = function(gl, color) {
  var program = gl.getParameter(gl.CURRENT_PROGRAM);
  var colorLocation = gl.getUniformLocation(program, "u_color");
  gl.uniform4fv(colorLocation, color);
};

/**
 * Sets the "u_color" uniform of the current program to color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} color 4 element array of 0-255 color
 *      components.
 */
var setUByteDrawColor = function(gl, color) {
  setFloatDrawColor(gl, ubyteColorToFloatColor(color));
};

/**
 * Draws a previously setup quad in the given color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} color The color to draw with. A 4
 *        element array where each element is in the range 0 to
 *        1.
 */
var drawFloatColorQuad = function(gl, color) {
  var program = gl.getParameter(gl.CURRENT_PROGRAM);
  var colorLocation = gl.getUniformLocation(program, "u_color");
  gl.uniform4fv(colorLocation, color);
  gl.drawArrays(gl.TRIANGLES, 0, 6);
};


/**
 * Draws a previously setup quad in the given color.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} color The color to draw with. A 4
 *        element array where each element is in the range 0 to
 *        255.
 */
var drawUByteColorQuad = function(gl, color) {
  drawFloatColorQuad(gl, ubyteColorToFloatColor(color));
};

/**
 * Draws a previously setupUnitQuad.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 */
var drawUnitQuad = function(gl) {
  gl.drawArrays(gl.TRIANGLES, 0, 6);
};

var dummySetProgramAndDrawNothing = function(gl) {
  if (!gl._wtuDummyProgram) {
    gl._wtuDummyProgram = setupProgram(gl, [
      "void main() { gl_Position = vec4(0.0); }",
      "void main() { gl_FragColor = vec4(0.0); }"
    ], [], []);
  }
  gl.useProgram(gl._wtuDummyProgram);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
};

/**
 * Clears then Draws a previously setupUnitQuad.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!Array.<number>} opt_color The color to fill clear with before
 *        drawing. A 4 element array where each element is in the range 0 to
 *        255. Default [255, 255, 255, 255]
 */
var clearAndDrawUnitQuad = function(gl, opt_color) {
  opt_color = opt_color || [255, 255, 255, 255];
  gl.clearColor(
      opt_color[0] / 255,
      opt_color[1] / 255,
      opt_color[2] / 255,
      opt_color[3] / 255);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  drawUnitQuad(gl);
};

/**
 * Draws a quad previously setup with setupIndexedQuad.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} gridRes Resolution of grid.
 */
var drawIndexedQuad = function(gl, gridRes) {
  gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
};

/**
 * Draws a previously setupIndexedQuad
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number} gridRes Resolution of grid.
 * @param {!Array.<number>} opt_color The color to fill clear with before
 *        drawing. A 4 element array where each element is in the range 0 to
 *        255. Default [255, 255, 255, 255]
 */
var clearAndDrawIndexedQuad = function(gl, gridRes, opt_color) {
  opt_color = opt_color || [255, 255, 255, 255];
  gl.clearColor(
      opt_color[0] / 255,
      opt_color[1] / 255,
      opt_color[2] / 255,
      opt_color[3] / 255);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  drawIndexedQuad(gl, gridRes);
};

/**
 * Clips a range to min, max
 * (Eg. clipToRange(-5,7,0,20) would return {value:0,extent:2}
 * @param {number} value start of range
 * @param {number} extent extent of range
 * @param {number} min min.
 * @param {number} max max.
 * @return {!{value:number,extent:number}} The clipped value.
 */
var clipToRange = function(value, extent, min, max) {
  if (value < min) {
    extent -= min - value;
    value = min;
  }
  var end = value + extent;
  if (end > max) {
    extent -= end - max;
  }
  if (extent < 0) {
    value = max;
    extent = 0;
  }
  return {value:value, extent: extent};
};

/**
 * Determines if the passed context is an instance of a WebGLRenderingContext
 * or later variant (like WebGL2RenderingContext)
 * @param {CanvasRenderingContext} ctx The context to check.
 */
var isWebGLContext = function(ctx) {
  if (ctx instanceof WebGLRenderingContext)
    return true;

  if ('WebGL2RenderingContext' in window && ctx instanceof WebGL2RenderingContext)
    return true;

  return false;
};

/**
 * Creates a check rect is used by checkCanvasRects.
 * @param {number} x left corner of region to check.
 * @param {number} y bottom corner of region to check in case of checking from
 *        a GL context or top corner in case of checking from a 2D context.
 * @param {number} width width of region to check.
 * @param {number} height width of region to check.
 * @param {!Array.<number>} color The color expected. A 4 element array where
 *        each element is in the range 0 to 255.
 * @param {string} opt_msg Message to associate with success. Eg
 *        ("should be red").
 * @param {number} opt_errorRange Optional. Acceptable error in
 *        color checking. 0 by default.
 */
var makeCheckRect = function(x, y, width, height, color, msg, errorRange) {
  var rect = {
    'x': x, 'y': y,
    'width': width, 'height': height,
    'color': color, 'msg': msg,
    'errorRange': errorRange,

    'checkRect': function (buf, l, b, w) {
      for (var px = (x - l) ; px < (x + width - l) ; ++px) {
        for (var py = (y - b) ; py < (y + height - b) ; ++py) {
          var offset = (py * w + px) * 4;
          for (var j = 0; j < color.length; ++j) {
            if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
              testFailed(msg);
              var was = buf[offset + 0].toString();
              for (j = 1; j < color.length; ++j) {
                was += "," + buf[offset + j];
              }
              debug('at (' + px + ', ' + py +
                    ') expected: ' + color + ' was ' + was);
              return;
            }
          }
        }
      }
      testPassed(msg);
    }
  }
  return rect;
};

/**
 * Checks that a portions of a canvas or the currently attached framebuffer is 1 color.
 * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The
 *         WebGLRenderingContext or 2D context to use.
 * @param {!Array.<checkRect>} array of rects to check for matching color.
 */
var checkCanvasRects = function(gl, rects) {
  if (rects.length > 0) {
    var left = rects[0].x;
    var right = rects[0].x + rects[1].width;
    var bottom = rects[0].y;
    var top = rects[0].y + rects[0].height;
    for (var i = 1; i < rects.length; ++i) {
      left = Math.min(left, rects[i].x);
      right = Math.max(right, rects[i].x + rects[i].width);
      bottom = Math.min(bottom, rects[i].y);
      top = Math.max(top, rects[i].y + rects[i].height);
    }
    var width = right - left;
    var height = top - bottom;
    var buf = new Uint8Array(width * height * 4);
    gl.readPixels(left, bottom, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
    for (var i = 0; i < rects.length; ++i) {
      rects[i].checkRect(buf, left, bottom, width);
    }
  }
};

/**
 * Checks that a portion of a canvas or the currently attached framebuffer is 1 color.
 * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The
 *         WebGLRenderingContext or 2D context to use.
 * @param {number} x left corner of region to check.
 * @param {number} y bottom corner of region to check in case of checking from
 *        a GL context or top corner in case of checking from a 2D context.
 * @param {number} width width of region to check.
 * @param {number} height width of region to check.
 * @param {!Array.<number>} color The color expected. A 4 element array where
 *        each element is in the range 0 to 255.
 * @param {number} opt_errorRange Optional. Acceptable error in
 *        color checking. 0 by default.
 * @param {!function()} sameFn Function to call if all pixels
 *        are the same as color.
 * @param {!function()} differentFn Function to call if a pixel
 *        is different than color
 * @param {!function()} logFn Function to call for logging.
 * @param {TypedArray} opt_readBackBuf optional buffer to read back into.
 *        Typically passed to either reuse buffer, or support readbacks from
 *        floating-point framebuffers.
 * @param {GLenum} opt_readBackType optional read back type, defaulting to
 *        gl.UNSIGNED_BYTE. Can be used to support readback from floating-point
 *        framebuffers.
 */
var checkCanvasRectColor = function(gl, x, y, width, height, color, opt_errorRange, sameFn, differentFn, logFn, opt_readBackBuf, opt_readBackType) {
  if (isWebGLContext(gl) && !gl.getParameter(gl.FRAMEBUFFER_BINDING)) {
    // We're reading the backbuffer so clip.
    var xr = clipToRange(x, width, 0, gl.canvas.width);
    var yr = clipToRange(y, height, 0, gl.canvas.height);
    if (!xr.extent || !yr.extent) {
      logFn("checking rect: effective width or height is zero");
      sameFn();
      return;
    }
    x = xr.value;
    y = yr.value;
    width = xr.extent;
    height = yr.extent;
  }
  var errorRange = opt_errorRange || 0;
  if (!errorRange.length) {
    errorRange = [errorRange, errorRange, errorRange, errorRange]
  }
  var buf;
  if (isWebGLContext(gl)) {
    buf = opt_readBackBuf ? opt_readBackBuf : new Uint8Array(width * height * 4);
    var readBackType = opt_readBackType ? opt_readBackType : gl.UNSIGNED_BYTE;
    gl.readPixels(x, y, width, height, gl.RGBA, readBackType, buf);
  } else {
    buf = gl.getImageData(x, y, width, height).data;
  }
  for (var i = 0; i < width * height; ++i) {
    var offset = i * 4;
    for (var j = 0; j < color.length; ++j) {
      if (Math.abs(buf[offset + j] - color[j]) > errorRange[j]) {
        var was = buf[offset + 0].toString();
        for (j = 1; j < color.length; ++j) {
          was += "," + buf[offset + j];
        }
        differentFn('at (' + (x + (i % width)) + ', ' + (y + Math.floor(i / width)) +
                    ') expected: ' + color + ' was ' + was);
        return;
      }
    }
  }
  sameFn();
};

/**
 * Checks that a portion of a canvas or the currently attached framebuffer is 1 color.
 * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The
 *         WebGLRenderingContext or 2D context to use.
 * @param {number} x left corner of region to check.
 * @param {number} y bottom corner of region to check in case of checking from
 *        a GL context or top corner in case of checking from a 2D context.
 * @param {number} width width of region to check.
 * @param {number} height width of region to check.
 * @param {!Array.<number>} color The color expected. A 4 element array where
 *        each element is in the range 0 to 255.
 * @param {string} opt_msg Message to associate with success or failure. Eg
 *        ("should be red").
 * @param {number} opt_errorRange Optional. Acceptable error in
 *        color checking. 0 by default.
 * @param {TypedArray} opt_readBackBuf optional buffer to read back into.
 *        Typically passed to either reuse buffer, or support readbacks from
 *        floating-point framebuffers.
 * @param {GLenum} opt_readBackType optional read back type, defaulting to
 *        gl.UNSIGNED_BYTE. Can be used to support readback from floating-point
 *        framebuffers.
 */
var checkCanvasRect = function(gl, x, y, width, height, color, opt_msg, opt_errorRange, opt_readBackBuf, opt_readBackType) {
  checkCanvasRectColor(
      gl, x, y, width, height, color, opt_errorRange,
      function() {
        var msg = opt_msg;
        if (msg === undefined)
          msg = "should be " + color.toString();
        testPassed(msg);
      },
      function(differentMsg) {
        var msg = opt_msg;
        if (msg === undefined)
          msg = "should be " + color.toString();
        testFailed(msg + "\n" + differentMsg);
      },
      debug,
      opt_readBackBuf,
      opt_readBackType);
};

/**
 * Checks that an entire canvas or the currently attached framebuffer is 1 color.
 * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The
 *         WebGLRenderingContext or 2D context to use.
 * @param {!Array.<number>} color The color expected. A 4 element array where
 *        each element is in the range 0 to 255.
 * @param {string} msg Message to associate with success. Eg ("should be red").
 * @param {number} errorRange Optional. Acceptable error in
 *        color checking. 0 by default.
 */
var checkCanvas = function(gl, color, msg, errorRange) {
  checkCanvasRect(gl, 0, 0, gl.canvas.width, gl.canvas.height, color, msg, errorRange);
};

/**
 * Checks a rectangular area both inside the area and outside
 * the area.
 * @param {!WebGLRenderingContext|CanvasRenderingContext2D} gl The
 *         WebGLRenderingContext or 2D context to use.
 * @param {number} x left corner of region to check.
 * @param {number} y bottom corner of region to check in case of checking from
 *        a GL context or top corner in case of checking from a 2D context.
 * @param {number} width width of region to check.
 * @param {number} height width of region to check.
 * @param {!Array.<number>} innerColor The color expected inside
 *     the area. A 4 element array where each element is in the
 *     range 0 to 255.
 * @param {!Array.<number>} outerColor The color expected
 *     outside. A 4 element array where each element is in the
 *     range 0 to 255.
 * @param {!number} opt_edgeSize: The number of pixels to skip
 *     around the edges of the area. Defaut 0.
 * @param {!{width:number, height:number}} opt_outerDimensions
 *     The outer dimensions. Default the size of gl.canvas.
 */
var checkAreaInAndOut = function(gl, x, y, width, height, innerColor, outerColor, opt_edgeSize, opt_outerDimensions) {
  var outerDimensions = opt_outerDimensions || { width: gl.canvas.width, height: gl.canvas.height };
  var edgeSize = opt_edgeSize || 0;
  checkCanvasRect(gl, x + edgeSize, y + edgeSize, width - edgeSize * 2, height - edgeSize * 2, innerColor);
  checkCanvasRect(gl, 0, 0, x - edgeSize, outerDimensions.height, outerColor);
  checkCanvasRect(gl, x + width + edgeSize, 0, outerDimensions.width - x - width - edgeSize, outerDimensions.height, outerColor);
  checkCanvasRect(gl, 0, 0, outerDimensions.width, y - edgeSize, outerColor);
  checkCanvasRect(gl, 0, y + height + edgeSize, outerDimensions.width, outerDimensions.height - y - height - edgeSize, outerColor);
};

/**
 * Checks that an entire buffer matches the floating point values provided.
 * (WebGL 2.0 only)
 * @param {!WebGL2RenderingContext} gl The WebGL2RenderingContext to use.
 * @param {number} target The buffer target to bind to.
 * @param {!Array.<number>} expected The values expected.
 * @param {string} opt_msg Optional. Message to associate with success. Eg ("should be red").
 * @param {number} opt_errorRange Optional. Acceptable error in value checking. 0.001 by default.
 */
var checkFloatBuffer = function(gl, target, expected, opt_msg, opt_errorRange) {
  if (opt_msg === undefined)
    opt_msg = "buffer should match expected values";

  if (opt_errorRange === undefined)
    opt_errorRange = 0.001;

  var floatArray = new Float32Array(expected.length);
  gl.getBufferSubData(target, 0, floatArray);

  for (var i = 0; i < expected.length; i++) {
    if (Math.abs(floatArray[i] - expected[i]) > opt_errorRange) {
      testFailed(opt_msg);
      debug('at [' + i + '] expected: ' + expected[i] + ' was ' + floatArray[i]);
      return;
    }
  }
  testPassed(opt_msg);
};

/**
 * Loads a texture, calls callback when finished.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} url URL of image to load
 * @param {function(!Image): void} callback Function that gets called after
 *        image has loaded
 * @return {!WebGLTexture} The created texture.
 */
var loadTexture = function(gl, url, callback) {
    var texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    var image = new Image();
    image.onload = function() {
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        callback(image);
    };
    image.src = url;
    return texture;
};

/**
 * Checks whether the bound texture has expected dimensions. One corner pixel
 * of the texture will be changed as a side effect.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!WebGLTexture} texture The texture to check.
 * @param {number} width Expected width.
 * @param {number} height Expected height.
 * @param {GLenum} opt_format The texture's format. Defaults to RGBA.
 * @param {GLenum} opt_type The texture's type. Defaults to UNSIGNED_BYTE.
 */
var checkTextureSize = function(gl, width, height, opt_format, opt_type) {
  opt_format = opt_format || gl.RGBA;
  opt_type = opt_type || gl.UNSIGNED_BYTE;

  var numElements = getTypedArrayElementsPerPixel(gl, opt_format, opt_type);
  var buf = new (glTypeToTypedArrayType(gl, opt_type))(numElements);

  var errors = 0;
  gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height - 1, 1, 1, opt_format, opt_type, buf);
  if (gl.getError() != gl.NO_ERROR) {
    testFailed("Texture was smaller than the expected size " + width + "x" + height);
    ++errors;
  }
  gl.texSubImage2D(gl.TEXTURE_2D, 0, width - 1, height, 1, 1, opt_format, opt_type, buf);
  if (gl.getError() == gl.NO_ERROR) {
    testFailed("Texture was taller than " + height);
    ++errors;
  }
  gl.texSubImage2D(gl.TEXTURE_2D, 0, width, height - 1, 1, 1, opt_format, opt_type, buf);
  if (gl.getError() == gl.NO_ERROR) {
    testFailed("Texture was wider than " + width);
    ++errors;
  }
  if (errors == 0) {
    testPassed("Texture had the expected size " + width + "x" + height);
  }
};

/**
 * Makes a shallow copy of an object.
 * @param {!Object} src Object to copy
 * @return {!Object} The copy of src.
 */
var shallowCopyObject = function(src) {
  var dst = {};
  for (var attr in src) {
    if (src.hasOwnProperty(attr)) {
      dst[attr] = src[attr];
    }
  }
  return dst;
};

/**
 * Checks if an attribute exists on an object case insensitive.
 * @param {!Object} obj Object to check
 * @param {string} attr Name of attribute to look for.
 * @return {string?} The name of the attribute if it exists,
 *         undefined if not.
 */
var hasAttributeCaseInsensitive = function(obj, attr) {
  var lower = attr.toLowerCase();
  for (var key in obj) {
    if (obj.hasOwnProperty(key) && key.toLowerCase() == lower) {
      return key;
    }
  }
};

/**
 * Returns a map of URL querystring options
 * @return {Object?} Object containing all the values in the URL querystring
 */
var getUrlOptions = (function() {
  var _urlOptionsParsed = false;
  var _urlOptions = {};
  return function() {
    if (!_urlOptionsParsed) {
      var s = window.location.href;
      var q = s.indexOf("?");
      var e = s.indexOf("#");
      if (e < 0) {
        e = s.length;
      }
      var query = s.substring(q + 1, e);
      var pairs = query.split("&");
      for (var ii = 0; ii < pairs.length; ++ii) {
        var keyValue = pairs[ii].split("=");
        var key = keyValue[0];
        var value = decodeURIComponent(keyValue[1]);
        _urlOptions[key] = value;
      }
      _urlOptionsParsed = true;
    }

    return _urlOptions;
  }
})();

var default3DContextVersion = 1;

/**
 * Set the default context version for create3DContext.
 * Initially the default version is 1.
 * @param {number} Default version of WebGL contexts.
 */
var setDefault3DContextVersion = function(version) {
    default3DContextVersion = version;
};

/**
 * Get the default contex version for create3DContext.
 * First it looks at the URI option |webglVersion|. If it does not exist,
 * then look at the global default3DContextVersion variable.
 */
var getDefault3DContextVersion = function() {
    return parseInt(getUrlOptions().webglVersion, 10) || default3DContextVersion;
};

/**
 * Creates a webgl context.
 * @param {!Canvas|string} opt_canvas The canvas tag to get
 *     context from. If one is not passed in one will be
 *     created. If it's a string it's assumed to be the id of a
 *     canvas.
 * @param {Object} opt_attributes Context attributes.
 * @param {!number} opt_version Version of WebGL context to create.
 *     The default version can be set by calling setDefault3DContextVersion.
 * @return {!WebGLRenderingContext} The created context.
 */
var create3DContext = function(opt_canvas, opt_attributes, opt_version) {
  if (window.initTestingHarness) {
    window.initTestingHarness();
  }
  var attributes = shallowCopyObject(opt_attributes || {});
  if (!hasAttributeCaseInsensitive(attributes, "antialias")) {
    attributes.antialias = false;
  }
  if (!opt_version) {
    opt_version = parseInt(getUrlOptions().webglVersion, 10) || default3DContextVersion;
  }
  opt_canvas = opt_canvas || document.createElement("canvas");
  if (typeof opt_canvas == 'string') {
    opt_canvas = document.getElementById(opt_canvas);
  }
  var context = null;

  var names;
  switch (opt_version) {
    case 2:
      names = ["webgl2"]; break;
    default:
      names = ["webgl", "experimental-webgl"]; break;
  }

  for (var i = 0; i < names.length; ++i) {
    try {
      context = opt_canvas.getContext(names[i], attributes);
    } catch (e) {
    }
    if (context) {
      break;
    }
  }
  if (!context) {
    testFailed("Unable to fetch WebGL rendering context for Canvas");
  }
  return context;
};

/**
 * Defines the exception type for a GL error.
 * @constructor
 * @param {string} message The error message.
 * @param {number} error GL error code
 */
function GLErrorException (message, error) {
   this.message = message;
   this.name = "GLErrorException";
   this.error = error;
};

/**
 * Wraps a WebGL function with a function that throws an exception if there is
 * an error.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} fname Name of function to wrap.
 * @return {function()} The wrapped function.
 */
var createGLErrorWrapper = function(context, fname) {
  return function() {
    var rv = context[fname].apply(context, arguments);
    var err = context.getError();
    if (err != context.NO_ERROR) {
      var msg = "GL error " + glEnumToString(context, err) + " in " + fname;
      throw new GLErrorException(msg, err);
    }
    return rv;
  };
};

/**
 * Creates a WebGL context where all functions are wrapped to throw an exception
 * if there is an error.
 * @param {!Canvas} canvas The HTML canvas to get a context from.
 * @param {Object} opt_attributes Context attributes.
 * @param {!number} opt_version Version of WebGL context to create
 * @return {!Object} The wrapped context.
 */
function create3DContextWithWrapperThatThrowsOnGLError(canvas, opt_attributes, opt_version) {
  var context = create3DContext(canvas, opt_attributes, opt_version);
  var wrap = {};
  for (var i in context) {
    try {
      if (typeof context[i] == 'function') {
        wrap[i] = createGLErrorWrapper(context, i);
      } else {
        wrap[i] = context[i];
      }
    } catch (e) {
      error("createContextWrapperThatThrowsOnGLError: Error accessing " + i);
    }
  }
  wrap.getError = function() {
      return context.getError();
  };
  return wrap;
};

/**
 * Tests that an evaluated expression generates a specific GL error.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors.
 * @param {string} evalStr The string to evaluate.
 */
var shouldGenerateGLError = function(gl, glErrors, evalStr, opt_msg) {
  var exception;
  try {
    eval(evalStr);
  } catch (e) {
    exception = e;
  }
  if (exception) {
    testFailed(evalStr + " threw exception " + exception);
    return -1;
  } else {
    if (!opt_msg) {
      opt_msg = "after evaluating: " + evalStr;
    }
    return glErrorShouldBe(gl, glErrors, opt_msg);
  }
};

/**
 * Tests that an evaluated expression does not generate a GL error.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} evalStr The string to evaluate.
 */
var failIfGLError = function(gl, evalStr) {
  var exception;
  try {
    eval(evalStr);
  } catch (e) {
    exception = e;
  }
  if (exception) {
    testFailed(evalStr + " threw exception " + exception);
  } else {
    glErrorShouldBeImpl(gl, gl.NO_ERROR, false, "after evaluating: " + evalStr);
  }
};

/**
 * Tests that the first error GL returns is the specified error.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors.
 * @param {string} opt_msg Optional additional message.
 */
var glErrorShouldBe = function(gl, glErrors, opt_msg) {
  return glErrorShouldBeImpl(gl, glErrors, true, opt_msg);
};



/**
 * Tests that the first error GL returns is the specified error. Allows suppression of successes.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {number|Array.<number>} glErrors The expected gl error or an array of expected errors.
 * @param {boolean} reportSuccesses Whether to report successes as passes, or to silently pass.
 * @param {string} opt_msg Optional additional message.
 */
var glErrorShouldBeImpl = function(gl, glErrors, reportSuccesses, opt_msg) {
  if (!glErrors.length) {
    glErrors = [glErrors];
  }
  opt_msg = opt_msg || "";
  var err = gl.getError();
  var ndx = glErrors.indexOf(err);
  var errStrs = [];
  for (var ii = 0; ii < glErrors.length; ++ii) {
    errStrs.push(glEnumToString(gl, glErrors[ii]));
  }
  var expected = errStrs.join(" or ");
  if (ndx < 0) {
    var msg = "getError expected" + ((glErrors.length > 1) ? " one of: " : ": ");
    testFailed(msg + expected +  ". Was " + glEnumToString(gl, err) + " : " + opt_msg);
  } else if (reportSuccesses) {
    var msg = "getError was " + ((glErrors.length > 1) ? "one of: " : "expected value: ");
    testPassed(msg + expected + " : " + opt_msg);
  }
  return err;
};

/**
 * Links a WebGL program, throws if there are errors.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!WebGLProgram} program The WebGLProgram to link.
 * @param {function(string): void} opt_errorCallback callback for errors.
 */
var linkProgram = function(gl, program, opt_errorCallback) {
  var errFn = opt_errorCallback || testFailed;
  // Link the program
  gl.linkProgram(program);

  // Check the link status
  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!linked) {
    // something went wrong with the link
    var error = gl.getProgramInfoLog (program);

    errFn("Error in program linking:" + error);

    gl.deleteProgram(program);
  }
};

/**
 * Loads text from an external file. This function is asynchronous.
 * @param {string} url The url of the external file.
 * @param {!function(bool, string): void} callback that is sent a bool for
 *     success and the string.
 */
var loadTextFileAsync = function(url, callback) {
  log ("loading: " + url);
  var error = 'loadTextFileAsync failed to load url "' + url + '"';
  var request;
  if (window.XMLHttpRequest) {
    request = new XMLHttpRequest();
    if (request.overrideMimeType) {
      request.overrideMimeType('text/plain');
    }
  } else {
    throw 'XMLHttpRequest is disabled';
  }
  try {
    request.open('GET', url, true);
    request.onreadystatechange = function() {
      if (request.readyState == 4) {
        var text = '';
        // HTTP reports success with a 200 status. The file protocol reports
        // success with zero. HTTP does not use zero as a status code (they
        // start at 100).
        // https://developer.mozilla.org/En/Using_XMLHttpRequest
        var success = request.status == 200 || request.status == 0;
        if (success) {
          text = request.responseText;
          log("completed load request: " + url);
        } else {
          log("loading " + url + " resulted in unexpected status: " + request.status + " " + request.statusText);
        }
        callback(success, text);
      }
    };
    request.onerror = function(errorEvent) {
      log("error occurred loading " + url);
      callback(false, '');
    };
    request.send(null);
  } catch (err) {
    log("failed to load: " + url + " with exception " + err.message);
    callback(false, '');
  }
};

/**
 * Recursively loads a file as a list. Each line is parsed for a relative
 * path. If the file ends in .txt the contents of that file is inserted in
 * the list.
 *
 * @param {string} url The url of the external file.
 * @param {!function(bool, Array<string>): void} callback that is sent a bool
 *     for success and the array of strings.
 */
var getFileListAsync = function(url, callback) {
  var files = [];

  var getFileListImpl = function(url, callback) {
    var files = [];
    if (url.substr(url.length - 4) == '.txt') {
      loadTextFileAsync(url, function() {
        return function(success, text) {
          if (!success) {
            callback(false, '');
            return;
          }
          var lines = text.split('\n');
          var prefix = '';
          var lastSlash = url.lastIndexOf('/');
          if (lastSlash >= 0) {
            prefix = url.substr(0, lastSlash + 1);
          }
          var fail = false;
          var count = 1;
          var index = 0;
          for (var ii = 0; ii < lines.length; ++ii) {
            var str = lines[ii].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
            if (str.length > 4 &&
                str[0] != '#' &&
                str[0] != ";" &&
                str.substr(0, 2) != "//") {
              var names = str.split(/ +/);
              var new_url = prefix + str;
              if (names.length == 1) {
                new_url = prefix + str;
                ++count;
                getFileListImpl(new_url, function(index) {
                  return function(success, new_files) {
                    log("got files: " + new_files.length);
                    if (success) {
                      files[index] = new_files;
                    }
                    finish(success);
                  };
                }(index++));
              } else {
                var s = "";
                var p = "";
                for (var jj = 0; jj < names.length; ++jj) {
                  s += p + prefix + names[jj];
                  p = " ";
                }
                files[index++] = s;
              }
            }
          }
          finish(true);

          function finish(success) {
            if (!success) {
              fail = true;
            }
            --count;
            log("count: " + count);
            if (!count) {
              callback(!fail, files);
            }
          }
        }
      }());

    } else {
      files.push(url);
      callback(true, files);
    }
  };

  getFileListImpl(url, function(success, files) {
    // flatten
    var flat = [];
    flatten(files);
    function flatten(files) {
      for (var ii = 0; ii < files.length; ++ii) {
        var value = files[ii];
        if (typeof(value) == "string") {
          flat.push(value);
        } else {
          flatten(value);
        }
      }
    }
    callback(success, flat);
  });
};

/**
 * Gets a file from a file/URL.
 * @param {string} file the URL of the file to get.
 * @return {string} The contents of the file.
 */
var readFile = function(file) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", file, false);
  xhr.overrideMimeType("text/plain");
  xhr.send();
  return xhr.responseText.replace(/\r/g, "");
};

var readFileList = function(url) {
  var files = [];
  if (url.substr(url.length - 4) == '.txt') {
    var lines = readFile(url).split('\n');
    var prefix = '';
    var lastSlash = url.lastIndexOf('/');
    if (lastSlash >= 0) {
      prefix = url.substr(0, lastSlash + 1);
    }
    for (var ii = 0; ii < lines.length; ++ii) {
      var str = lines[ii].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
      if (str.length > 4 &&
          str[0] != '#' &&
          str[0] != ";" &&
          str.substr(0, 2) != "//") {
        var names = str.split(/ +/);
        if (names.length == 1) {
          var new_url = prefix + str;
          files = files.concat(readFileList(new_url));
        } else {
          var s = "";
          var p = "";
          for (var jj = 0; jj < names.length; ++jj) {
            s += p + prefix + names[jj];
            p = " ";
          }
          files.push(s);
        }
      }
    }
  } else {
    files.push(url);
  }
  return files;
};

/**
 * Loads a shader.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} shaderSource The shader source.
 * @param {number} shaderType The type of shader.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @param {boolean} opt_logShaders Whether to log shader source.
 * @param {string} opt_shaderLabel Label that identifies the shader source in
 *     the log.
 * @param {string} opt_url URL from where the shader source was loaded from.
 *     If opt_logShaders is set, then a link to the source file will also be
 *     added.
 * @param {boolean} Skip compilation status check. Default = false.
 * @return {!WebGLShader} The created shader.
 */
var loadShader = function(
    gl, shaderSource, shaderType, opt_errorCallback, opt_logShaders,
    opt_shaderLabel, opt_url, opt_skipCompileStatus) {
  var errFn = opt_errorCallback || error;
  // Create the shader object
  var shader = gl.createShader(shaderType);
  if (shader == null) {
    errFn("*** Error: unable to create shader '"+shaderSource+"'");
    return null;
  }

  // Load the shader source
  gl.shaderSource(shader, shaderSource);

  // Compile the shader
  gl.compileShader(shader);

  if (opt_logShaders) {
    var label = shaderType == gl.VERTEX_SHADER ? 'vertex shader' : 'fragment_shader';
    if (opt_shaderLabel) {
      label = opt_shaderLabel + ' ' + label;
    }
    addShaderSources(
        gl, document.getElementById('console'), label, shader, shaderSource, opt_url);
  }

  // Check the compile status
  if (!opt_skipCompileStatus) {
    var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compiled) {
      // Something went wrong during compilation; get the error
      lastError = gl.getShaderInfoLog(shader);
      errFn("*** Error compiling " + glEnumToString(gl, shaderType) + " '" + shader + "':" + lastError);
      gl.deleteShader(shader);
      return null;
    }
  }

  return shader;
}

/**
 * Loads a shader from a URL.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {file} file The URL of the shader source.
 * @param {number} type The type of shader.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @param {boolean} opt_logShaders Whether to log shader source.
 * @param {boolean} Skip compilation status check. Default = false.
 * @return {!WebGLShader} The created shader.
 */
var loadShaderFromFile = function(
    gl, file, type, opt_errorCallback, opt_logShaders, opt_skipCompileStatus) {
  var shaderSource = readFile(file);
  return loadShader(gl, shaderSource, type, opt_errorCallback,
      opt_logShaders, undefined, file, opt_skipCompileStatus);
};

var loadShaderFromFileAsync = function(
    gl, file, type, opt_errorCallback, opt_logShaders, opt_skipCompileStatus, callback) {
  loadTextFileAsync(file, function(gl, type, opt_errorCallback, opt_logShaders, file, opt_skipCompileStatus){
      return function(success, shaderSource) {
        if (success) {
          var shader = loadShader(gl, shaderSource, type, opt_errorCallback,
              opt_logShaders, undefined, file, opt_skipCompileStatus);
          callback(true, shader);
        } else {
          callback(false, null);
        }
      }
  }(gl, type, opt_errorCallback, opt_logShaders, file, opt_skipCompileStatus));
};

/**
 * Gets the content of script.
 * @param {string} scriptId The id of the script tag.
 * @return {string} The content of the script.
 */
var getScript = function(scriptId) {
  var shaderScript = document.getElementById(scriptId);
  if (!shaderScript) {
    throw("*** Error: unknown script element " + scriptId);
  }
  return shaderScript.text;
};

/**
 * Loads a shader from a script tag.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} scriptId The id of the script tag.
 * @param {number} opt_shaderType The type of shader. If not passed in it will
 *     be derived from the type of the script tag.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @param {boolean} opt_logShaders Whether to log shader source.
 * @param {boolean} Skip compilation status check. Default = false.
 * @return {!WebGLShader} The created shader.
 */
var loadShaderFromScript = function(
    gl, scriptId, opt_shaderType, opt_errorCallback, opt_logShaders, opt_skipCompileStatus) {
  var shaderSource = "";
  var shaderScript = document.getElementById(scriptId);
  if (!shaderScript) {
    throw("*** Error: unknown script element " + scriptId);
  }
  shaderSource = shaderScript.text;

  if (!opt_shaderType) {
    if (shaderScript.type == "x-shader/x-vertex") {
      opt_shaderType = gl.VERTEX_SHADER;
    } else if (shaderScript.type == "x-shader/x-fragment") {
      opt_shaderType = gl.FRAGMENT_SHADER;
    } else {
      throw("*** Error: unknown shader type");
      return null;
    }
  }

  return loadShader(gl, shaderSource, opt_shaderType, opt_errorCallback,
      opt_logShaders, undefined, undefined, opt_skipCompileStatus);
};

var loadStandardProgram = function(gl) {
  var program = gl.createProgram();
  gl.attachShader(program, loadStandardVertexShader(gl));
  gl.attachShader(program, loadStandardFragmentShader(gl));
  gl.bindAttribLocation(program, 0, "a_vertex");
  gl.bindAttribLocation(program, 1, "a_normal");
  linkProgram(gl, program);
  return program;
};

var loadStandardProgramAsync = function(gl, callback) {
  loadStandardVertexShaderAsync(gl, function(gl) {
    return function(success, vs) {
      if (success) {
        loadStandardFragmentShaderAsync(gl, function(vs) {
          return function(success, fs) {
            if (success) {
              var program = gl.createProgram();
              gl.attachShader(program, vs);
              gl.attachShader(program, fs);
              gl.bindAttribLocation(program, 0, "a_vertex");
              gl.bindAttribLocation(program, 1, "a_normal");
              linkProgram(gl, program);
              callback(true, program);
            } else {
              callback(false, null);
            }
          };
        }(vs));
      } else {
        callback(false, null);
      }
    };
  }(gl));
};

/**
 * Loads shaders from files, creates a program, attaches the shaders and links.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} vertexShaderPath The URL of the vertex shader.
 * @param {string} fragmentShaderPath The URL of the fragment shader.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @return {!WebGLProgram} The created program.
 */
var loadProgramFromFile = function(
    gl, vertexShaderPath, fragmentShaderPath, opt_errorCallback) {
  var program = gl.createProgram();
  var vs = loadShaderFromFile(
      gl, vertexShaderPath, gl.VERTEX_SHADER, opt_errorCallback);
  var fs = loadShaderFromFile(
      gl, fragmentShaderPath, gl.FRAGMENT_SHADER, opt_errorCallback);
  if (vs && fs) {
    gl.attachShader(program, vs);
    gl.attachShader(program, fs);
    linkProgram(gl, program, opt_errorCallback);
  }
  if (vs) {
    gl.deleteShader(vs);
  }
  if (fs) {
    gl.deleteShader(fs);
  }
  return program;
};

/**
 * Loads shaders from script tags, creates a program, attaches the shaders and
 * links.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} vertexScriptId The id of the script tag that contains the
 *        vertex shader.
 * @param {string} fragmentScriptId The id of the script tag that contains the
 *        fragment shader.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @return {!WebGLProgram} The created program.
 */
var loadProgramFromScript = function loadProgramFromScript(
    gl, vertexScriptId, fragmentScriptId, opt_errorCallback) {
  var program = gl.createProgram();
  gl.attachShader(
      program,
      loadShaderFromScript(
          gl, vertexScriptId, gl.VERTEX_SHADER, opt_errorCallback));
  gl.attachShader(
      program,
      loadShaderFromScript(
          gl, fragmentScriptId,  gl.FRAGMENT_SHADER, opt_errorCallback));
  linkProgram(gl, program, opt_errorCallback);
  return program;
};

/**
 * Loads shaders from source, creates a program, attaches the shaders and
 * links.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!WebGLShader} vertexShader The vertex shader.
 * @param {!WebGLShader} fragmentShader The fragment shader.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @return {!WebGLProgram} The created program.
 */
var createProgram = function(gl, vertexShader, fragmentShader, opt_errorCallback) {
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  linkProgram(gl, program, opt_errorCallback);
  return program;
};

/**
 * Loads shaders from source, creates a program, attaches the shaders and
 * links.
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} vertexShader The vertex shader source.
 * @param {string} fragmentShader The fragment shader source.
 * @param {function(string): void} opt_errorCallback callback for errors.
 * @param {boolean} opt_logShaders Whether to log shader source.
 * @return {!WebGLProgram} The created program.
 */
var loadProgram = function(
    gl, vertexShader, fragmentShader, opt_errorCallback, opt_logShaders) {
  var program;
  var vs = loadShader(
      gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback, opt_logShaders);
  var fs = loadShader(
      gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback, opt_logShaders);
  if (vs && fs) {
    program = createProgram(gl, vs, fs, opt_errorCallback)
  }
  if (vs) {
    gl.deleteShader(vs);
  }
  if (fs) {
    gl.deleteShader(fs);
  }
  return program;
};

/**
 * Loads shaders from source, creates a program, attaches the shaders and
 * links but expects error.
 *
 * GLSL 1.0.17 10.27 effectively says that compileShader can
 * always succeed as long as linkProgram fails so we can't
 * rely on compileShader failing. This function expects
 * one of the shader to fail OR linking to fail.
 *
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} vertexShaderScriptId The vertex shader.
 * @param {string} fragmentShaderScriptId The fragment shader.
 * @return {WebGLProgram} The created program.
 */
var loadProgramFromScriptExpectError = function(
    gl, vertexShaderScriptId, fragmentShaderScriptId) {
  var vertexShader = loadShaderFromScript(gl, vertexShaderScriptId);
  if (!vertexShader) {
    return null;
  }
  var fragmentShader = loadShaderFromScript(gl, fragmentShaderScriptId);
  if (!fragmentShader) {
    return null;
  }
  var linkSuccess = true;
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  linkSuccess = true;
  linkProgram(gl, program, function() {
      linkSuccess = false;
    });
  return linkSuccess ? program : null;
};


var getActiveMap = function(gl, program, typeInfo) {
  var numVariables = gl.getProgramParameter(program, gl[typeInfo.param]);
  var variables = {};
  for (var ii = 0; ii < numVariables; ++ii) {
    var info = gl[typeInfo.activeFn](program, ii);
    variables[info.name] = {
      name: info.name,
      size: info.size,
      type: info.type,
      location: gl[typeInfo.locFn](program, info.name)
    };
  }
  return variables;
};

/**
 * Returns a map of attrib names to info about those
 * attribs.
 *
 * eg:
 *    { "attrib1Name":
 *      {
 *        name: "attrib1Name",
 *        size: 1,
 *        type: gl.FLOAT_MAT2,
 *        location: 0
 *      },
 *      "attrib2Name[0]":
 *      {
 *         name: "attrib2Name[0]",
 *         size: 4,
 *         type: gl.FLOAT,
 *         location: 1
 *      },
 *    }
 *
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {WebGLProgram} The program to query for attribs.
 * @return the map.
 */
var getAttribMap = function(gl, program) {
  return getActiveMap(gl, program, {
      param: "ACTIVE_ATTRIBUTES",
      activeFn: "getActiveAttrib",
      locFn: "getAttribLocation"
  });
};

/**
 * Returns a map of uniform names to info about those uniforms.
 *
 * eg:
 *    { "uniform1Name":
 *      {
 *        name: "uniform1Name",
 *        size: 1,
 *        type: gl.FLOAT_MAT2,
 *        location: WebGLUniformLocation
 *      },
 *      "uniform2Name[0]":
 *      {
 *         name: "uniform2Name[0]",
 *         size: 4,
 *         type: gl.FLOAT,
 *         location: WebGLUniformLocation
 *      },
 *    }
 *
 * @param {!WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {WebGLProgram} The program to query for uniforms.
 * @return the map.
 */
var getUniformMap = function(gl, program) {
  return getActiveMap(gl, program, {
      param: "ACTIVE_UNIFORMS",
      activeFn: "getActiveUniform",
      locFn: "getUniformLocation"
  });
};

var basePath;
var getResourcePath = function() {
  if (!basePath) {
    var expectedBase = "js/webgl-test-utils.js";
    var scripts = document.getElementsByTagName('script');
    for (var script, i = 0; script = scripts[i]; i++) {
      var src = script.src;
      var l = src.length;
      if (src.substr(l - expectedBase.length) == expectedBase) {
        basePath = src.substr(0, l - expectedBase.length);
      }
    }
  }
  return basePath + "resources/";
};

var loadStandardVertexShader = function(gl) {
  return loadShaderFromFile(
      gl, getResourcePath() + "vertexShader.vert", gl.VERTEX_SHADER);
};
var loadStandardVertexShaderAsync = function(gl, callback) {
  loadShaderFromFileAsync(gl, getResourcePath() + "vertexShader.vert", gl.VERTEX_SHADER, undefined, undefined, undefined, callback);
};

var loadStandardFragmentShader = function(gl) {
  return loadShaderFromFile(
      gl, getResourcePath() + "fragmentShader.frag", gl.FRAGMENT_SHADER);
};
var loadStandardFragmentShaderAsync = function(gl, callback) {
  loadShaderFromFileAsync(gl, getResourcePath() + "fragmentShader.frag", gl.FRAGMENT_SHADER, undefined, undefined, undefined, callback);
};

var loadUniformBlockProgram = function(gl) {
  var program = gl.createProgram();
  gl.attachShader(program, loadUniformBlockVertexShader(gl));
  gl.attachShader(program, loadUniformBlockFragmentShader(gl));
  gl.bindAttribLocation(program, 0, "a_vertex");
  gl.bindAttribLocation(program, 1, "a_normal");
  linkProgram(gl, program);
  return program;
};

var loadUniformBlockVertexShader = function(gl) {
  return loadShaderFromFile(
      gl, getResourcePath() + "uniformBlockShader.vert", gl.VERTEX_SHADER);
};

var loadUniformBlockFragmentShader = function(gl) {
  return loadShaderFromFile(
      gl, getResourcePath() + "uniformBlockShader.frag", gl.FRAGMENT_SHADER);
};

/**
 * Loads an image asynchronously.
 * @param {string} url URL of image to load.
 * @param {!function(!Element): void} callback Function to call
 *     with loaded image.
 */
var loadImageAsync = function(url, callback) {
  var img = document.createElement('img');
  img.onload = function() {
    callback(img);
  };
  img.src = url;
};

/**
 * Loads an array of images.
 * @param {!Array.<string>} urls URLs of images to load.
 * @param {!function(!{string, img}): void} callback Callback
 *     that gets passed map of urls to img tags.
 */
var loadImagesAsync = function(urls, callback) {
  var count = 1;
  var images = { };
  function countDown() {
    --count;
    if (count == 0) {
      log("loadImagesAsync: all images loaded");
      callback(images);
    }
  }
  function imageLoaded(url) {
    return function(img) {
      images[url] = img;
      log("loadImagesAsync: loaded " + url);
      countDown();
    }
  }
  for (var ii = 0; ii < urls.length; ++ii) {
    ++count;
    loadImageAsync(urls[ii], imageLoaded(urls[ii]));
  }
  countDown();
};

/**
 * Returns a map of key=value values from url.
 * @return {!Object.<string, number>} map of keys to values.
 */
var getUrlArguments = function() {
  var args = {};
  try {
    var s = window.location.href;
    var q = s.indexOf("?");
    var e = s.indexOf("#");
    if (e < 0) {
      e = s.length;
    }
    var query = s.substring(q + 1, e);
    var pairs = query.split("&");
    for (var ii = 0; ii < pairs.length; ++ii) {
      var keyValue = pairs[ii].split("=");
      var key = keyValue[0];
      var value = decodeURIComponent(keyValue[1]);
      args[key] = value;
    }
  } catch (e) {
    throw "could not parse url";
  }
  return args;
};

/**
 * Makes an image from a src.
 * @param {string} src Image source URL.
 * @param {function()} onload Callback to call when the image has finised loading.
 * @param {function()} onerror Callback to call when an error occurs.
 * @return {!Image} The created image.
 */
var makeImage = function(src, onload, onerror) {
  var img = document.createElement('img');
  if (onload) {
    img.onload = onload;
  }
  if (onerror) {
    img.onerror = onerror;
  } else {
    img.onerror = function() {
      log("WARNING: creating image failed; src: " + this.src);
    };
  }
  if (src) {
    img.src = src;
  }
  return img;
}

/**
 * Makes an image element from a canvas.
 * @param {!HTMLCanvas} canvas Canvas to make image from.
 * @param {function()} onload Callback to call when the image has finised loading.
 * @param {string} imageFormat Image format to be passed to toDataUrl().
 * @return {!Image} The created image.
 */
var makeImageFromCanvas = function(canvas, onload, imageFormat) {
  return makeImage(canvas.toDataURL(imageFormat), onload);
};

/**
 * Makes a video element from a src.
 * @param {string} src Video source URL.
 * @param {function()} onerror Callback to call when an error occurs.
 * @return {!Video} The created video.
 */
var makeVideo = function(src, onerror) {
  var vid = document.createElement('video');
  if (onerror) {
    vid.onerror = onerror;
  } else {
    vid.onerror = function() {
      log("WARNING: creating video failed; src: " + this.src);
    };
  }
  if (src) {
    vid.src = src;
  }
  return vid;
}

/**
 * Inserts an image with a caption into 'element'.
 * @param {!HTMLElement} element Element to append image to.
 * @param {string} caption caption to associate with image.
 * @param {!Image} img image to insert.
 */
var insertImage = function(element, caption, img) {
  var div = document.createElement("div");
  var label = document.createElement("div");
  label.appendChild(document.createTextNode(caption));
  div.appendChild(label);
  div.appendChild(img);
  element.appendChild(div);
};

/**
 * Inserts a 'label' that when clicked expands to the pre formatted text
 * supplied by 'source'.
 * @param {!HTMLElement} element element to append label to.
 * @param {string} label label for anchor.
 * @param {string} source preformatted text to expand to.
 * @param {string} opt_url URL of source. If provided a link to the source file
 *     will also be added.
 */
var addShaderSource = function(element, label, source, opt_url) {
  var div = document.createElement("div");
  var s = document.createElement("pre");
  s.className = "shader-source";
  s.style.display = "none";
  var ol = document.createElement("ol");
  //s.appendChild(document.createTextNode(source));
  var lines = source.split("\n");
  for (var ii = 0; ii < lines.length; ++ii) {
    var line = lines[ii];
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(line));
    ol.appendChild(li);
  }
  s.appendChild(ol);
  var l = document.createElement("a");
  l.href = "show-shader-source";
  l.appendChild(document.createTextNode(label));
  l.addEventListener('click', function(event) {
      if (event.preventDefault) {
        event.preventDefault();
      }
      s.style.display = (s.style.display == 'none') ? 'block' : 'none';
      return false;
    }, false);
  div.appendChild(l);
  if (opt_url) {
    var u = document.createElement("a");
    u.href = opt_url;
    div.appendChild(document.createTextNode(" "));
    u.appendChild(document.createTextNode("(" + opt_url + ")"));
    div.appendChild(u);
  }
  div.appendChild(s);
  element.appendChild(div);
};

/**
 * Inserts labels that when clicked expand to show the original source of the
 * shader and also translated source of the shader, if that is available.
 * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {!HTMLElement} element element to append label to.
 * @param {string} label label for anchor.
 * @param {WebGLShader} shader Shader to show the sources for.
 * @param {string} shaderSource Original shader source.
 * @param {string} opt_url URL of source. If provided a link to the source file
 *     will also be added.
 */
var addShaderSources = function(
    gl, element, label, shader, shaderSource, opt_url) {
  addShaderSource(element, label, shaderSource, opt_url);

  var debugShaders = gl.getExtension('WEBGL_debug_shaders');
  if (debugShaders && shader) {
    var translatedSource = debugShaders.getTranslatedShaderSource(shader);
    if (translatedSource != '') {
      addShaderSource(element, label + ' translated for driver', translatedSource);
    }
  }
};

/**
 * Sends shader information to the server to be dumped into text files
 * when tests are run from within the test-runner harness.
 * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.
 * @param {string} url URL of current.
 * @param {string} passMsg Test description.
 * @param {object} vInfo Object containing vertex shader information.
 * @param {object} fInfo Object containing fragment shader information.
 */
var dumpShadersInfo = function(gl, url, passMsg, vInfo, fInfo) {
  var shaderInfo = {};
  shaderInfo.url = url;
  shaderInfo.testDescription = passMsg;
  shaderInfo.vLabel = vInfo.label;
  shaderInfo.vShouldCompile = vInfo.shaderSuccess;
  shaderInfo.vSource = vInfo.source;
  shaderInfo.fLabel = fInfo.label;
  shaderInfo.fShouldCompile = fInfo.shaderSuccess;
  shaderInfo.fSource = fInfo.source;
  shaderInfo.vTranslatedSource = null;
  shaderInfo.fTranslatedSource = null;
  var debugShaders = gl.getExtension('WEBGL_debug_shaders');
  if (debugShaders) {
    if (vInfo.shader)
      shaderInfo.vTranslatedSource = debugShaders.getTranslatedShaderSource(vInfo.shader);
    if (fInfo.shader)
      shaderInfo.fTranslatedSource = debugShaders.getTranslatedShaderSource(fInfo.shader);
  }

  var dumpShaderInfoRequest = new XMLHttpRequest();
  dumpShaderInfoRequest.open('POST', "/dumpShaderInfo", true);
  dumpShaderInfoRequest.setRequestHeader("Content-Type", "text/plain");
  dumpShaderInfoRequest.send(JSON.stringify(shaderInfo));
};

// Add your prefix here.
var browserPrefixes = [
  "",
  "MOZ_",
  "OP_",
  "WEBKIT_"
];

/**
 * Given an extension name like WEBGL_compressed_texture_s3tc
 * returns the name of the supported version extension, like
 * WEBKIT_WEBGL_compressed_teture_s3tc
 * @param {string} name Name of extension to look for.
 * @return {string} name of extension found or undefined if not
 *     found.
 */
var getSupportedExtensionWithKnownPrefixes = function(gl, name) {
  var supported = gl.getSupportedExtensions();
  for (var ii = 0; ii < browserPrefixes.length; ++ii) {
    var prefixedName = browserPrefixes[ii] + name;
    if (supported.indexOf(prefixedName) >= 0) {
      return prefixedName;
    }
  }
};

/**
 * Given an extension name like WEBGL_compressed_texture_s3tc
 * returns the supported version extension, like
 * WEBKIT_WEBGL_compressed_teture_s3tc
 * @param {string} name Name of extension to look for.
 * @return {WebGLExtension} The extension or undefined if not
 *     found.
 */
var getExtensionWithKnownPrefixes = function(gl, name) {
  for (var ii = 0; ii < browserPrefixes.length; ++ii) {
    var prefixedName = browserPrefixes[ii] + name;
    var ext = gl.getExtension(prefixedName);
    if (ext) {
      return ext;
    }
  }
};

/**
 * Returns possible prefixed versions of an extension's name.
 * @param {string} name Name of extension. May already include a prefix.
 * @return {Array.<string>} Variations of the extension name with known
 *     browser prefixes.
 */
var getExtensionPrefixedNames = function(name) {
  var unprefix = function(name) {
    for (var ii = 0; ii < browserPrefixes.length; ++ii) {
      if (browserPrefixes[ii].length > 0 &&
          name.substring(0, browserPrefixes[ii].length).toLowerCase() ===
          browserPrefixes[ii].toLowerCase()) {
        return name.substring(browserPrefixes[ii].length);
      }
    }
    return name;
  }

  var unprefixed = unprefix(name);

  var variations = [];
  for (var ii = 0; ii < browserPrefixes.length; ++ii) {
    variations.push(browserPrefixes[ii] + unprefixed);
  }

  return variations;
};

var replaceRE = /\$\((\w+)\)/g;

/**
 * Replaces strings with property values.
 * Given a string like "hello $(first) $(last)" and an object
 * like {first:"John", last:"Smith"} will return
 * "hello John Smith".
 * @param {string} str String to do replacements in.
 * @param {...} 1 or more objects containing properties.
 */
var replaceParams = function(str) {
  var args = arguments;
  return str.replace(replaceRE, function(str, p1, offset, s) {
    for (var ii = 1; ii < args.length; ++ii) {
      if (args[ii][p1] !== undefined) {
        return args[ii][p1];
      }
    }
    throw "unknown string param '" + p1 + "'";
  });
};

var upperCaseFirstLetter = function(str) {
  return str.substring(0, 1).toUpperCase() + str.substring(1);
};

/**
 * Gets a prefixed property. For example,
 *
 *     var fn = getPrefixedProperty(
 *        window,
 *        "requestAnimationFrame");
 *
 * Will return either:
 *    "window.requestAnimationFrame",
 *    "window.oRequestAnimationFrame",
 *    "window.msRequestAnimationFrame",
 *    "window.mozRequestAnimationFrame",
 *    "window.webKitRequestAnimationFrame",
 *    undefined
 *
 * the non-prefixed function is tried first.
 */
var propertyPrefixes = ["", "moz", "ms", "o", "webkit"];
var getPrefixedProperty = function(obj, propertyName) {
  for (var ii = 0; ii < propertyPrefixes.length; ++ii) {
    var prefix = propertyPrefixes[ii];
    var name = prefix + propertyName;
    log(name);
    var property = obj[name];
    if (property) {
      return property;
    }
    if (ii == 0) {
      propertyName = upperCaseFirstLetter(propertyName);
    }
  }
  return undefined;
};

var _requestAnimFrame;

/**
 * Provides requestAnimationFrame in a cross browser way.
 */
var requestAnimFrame = function(callback) {
  if (!_requestAnimFrame) {
    _requestAnimFrame = getPrefixedProperty(window, "requestAnimationFrame") ||
      function(callback, element) {
        return window.setTimeout(callback, 1000 / 70);
      };
  }
  _requestAnimFrame.call(window, callback);
};

var _cancelAnimFrame;

/**
 * Provides cancelAnimationFrame in a cross browser way.
 */
var cancelAnimFrame = function(request) {
  if (!_cancelAnimFrame) {
    _cancelAnimFrame = getPrefixedProperty(window, "cancelAnimationFrame") ||
      window.clearTimeout;
  }
  _cancelAnimFrame.call(window, request);
};

/**
 * Provides requestFullScreen in a cross browser way.
 */
var requestFullScreen = function(element) {
  var fn = getPrefixedProperty(element, "requestFullScreen");
  if (fn) {
    fn.call(element);
  }
};

/**
 * Provides cancelFullScreen in a cross browser way.
 */
var cancelFullScreen = function() {
  var fn = getPrefixedProperty(document, "cancelFullScreen");
  if (fn) {
    fn.call(document);
  }
};

var fullScreenStateName;
(function() {
  var fullScreenStateNames = [
    "isFullScreen",
    "fullScreen"
  ];
  for (var ii = 0; ii < fullScreenStateNames.length; ++ii) {
    var propertyName = fullScreenStateNames[ii];
    for (var jj = 0; jj < propertyPrefixes.length; ++jj) {
      var prefix = propertyPrefixes[jj];
      if (prefix.length) {
        propertyName = upperCaseFirstLetter(propertyName);
        fullScreenStateName = prefix + propertyName;
        if (document[fullScreenStateName] !== undefined) {
          return;
        }
      }
    }
    fullScreenStateName = undefined;
  }
}());

/**
 * @return {boolean} True if fullscreen mode is active.
 */
var getFullScreenState = function() {
  log("fullscreenstatename:" + fullScreenStateName);
  log(document[fullScreenStateName]);
  return document[fullScreenStateName];
};

/**
 * @param {!HTMLElement} element The element to go fullscreen.
 * @param {!function(boolean)} callback A function that will be called
 *        when entering/exiting fullscreen. It is passed true if
 *        entering fullscreen, false if exiting.
 */
var onFullScreenChange = function(element, callback) {
  propertyPrefixes.forEach(function(prefix) {
    var eventName = prefix + "fullscreenchange";
    log("addevent: " + eventName);
    document.addEventListener(eventName, function(event) {
      log("event: " + eventName);
      callback(getFullScreenState());
    });
  });
};

/**
 * @param {!string} buttonId The id of the button that will toggle fullscreen
 *        mode.
 * @param {!string} fullscreenId The id of the element to go fullscreen.
 * @param {!function(boolean)} callback A function that will be called
 *        when entering/exiting fullscreen. It is passed true if
 *        entering fullscreen, false if exiting.
 * @return {boolean} True if fullscreen mode is supported.
 */
var setupFullscreen = function(buttonId, fullscreenId, callback) {
  if (!fullScreenStateName) {
    return false;
  }

  var fullscreenElement = document.getElementById(fullscreenId);
  onFullScreenChange(fullscreenElement, callback);

  var toggleFullScreen = function(event) {
    if (getFullScreenState()) {
      cancelFullScreen(fullscreenElement);
    } else {
      requestFullScreen(fullscreenElement);
    }
    event.preventDefault();
    return false;
  };

  var buttonElement = document.getElementById(buttonId);
  buttonElement.addEventListener('click', toggleFullScreen);

  return true;
};

/**
 * Waits for the browser to composite the web page.
 * @param {function()} callback A function to call after compositing has taken
 *        place.
 */
var waitForComposite = function(callback) {
  var frames = 5;
  var countDown = function() {
    if (frames == 0) {
      // TODO(kbr): unify with js-test-pre.js and enable these with
      // verbose logging.
      // log("waitForComposite: callback");
      callback();
    } else {
      // log("waitForComposite: countdown(" + frames + ")");
      --frames;
      requestAnimFrame.call(window, countDown);
    }
  };
  countDown();
};

/**
 * Runs an array of functions, yielding to the browser between each step.
 * If you want to know when all the steps are finished add a last step.
 * @param {!Array.<function(): void>} steps Array of functions.
 */
var runSteps = function(steps) {
  if (!steps.length) {
    return;
  }

  // copy steps so they can't be modifed.
  var stepsToRun = steps.slice();
  var currentStep = 0;
  var runNextStep = function() {
    stepsToRun[currentStep++]();
    if (currentStep < stepsToRun.length) {
      setTimeout(runNextStep, 1);
    }
  };
  runNextStep();
};

/**
 * Starts playing a video and waits for it to be consumable.
 * @param {!HTMLVideoElement} video An HTML5 Video element.
 * @param {!function(!HTMLVideoElement): void} callback Function to call when
 *        video is ready.
 */
var startPlayingAndWaitForVideo = function(video, callback) {
  var gotPlaying = false;
  var gotTimeUpdate = false;

  var maybeCallCallback = function() {
    if (gotPlaying && gotTimeUpdate && callback) {
      callback(video);
      callback = undefined;
      video.removeEventListener('playing', playingListener, true);
      video.removeEventListener('timeupdate', timeupdateListener, true);
    }
  };

  var playingListener = function() {
    gotPlaying = true;
    maybeCallCallback();
  };

  var timeupdateListener = function() {
    // Checking to make sure the current time has advanced beyond
    // the start time seems to be a reliable heuristic that the
    // video element has data that can be consumed.
    if (video.currentTime > 0.0) {
      gotTimeUpdate = true;
      maybeCallCallback();
    }
  };

  video.addEventListener('playing', playingListener, true);
  video.addEventListener('timeupdate', timeupdateListener, true);
  video.loop = true;
  video.play();
};

var getHost = function(url) {
  url = url.replace("\\", "/");
  var pos = url.indexOf("://");
  if (pos >= 0) {
    url = url.substr(pos + 3);
  }
  var parts = url.split('/');
  return parts[0];
}

// This function returns the last 2 words of the domain of a URL
// This is probably not the correct check but it will do for now.
var getBaseDomain = function(host) {
  var parts = host.split(":");
  var hostname = parts[0];
  var port = parts[1] || "80";
  parts = hostname.split(".");
  if(parts.length < 2)
    return hostname + ":" + port;
  var tld = parts[parts.length-1];
  var domain = parts[parts.length-2];
  return domain + "." + tld + ":" + port;
}

var runningOnLocalhost = function() {
  return window.location.hostname.indexOf("localhost") != -1 ||
      window.location.hostname.indexOf("127.0.0.1") != -1;
}

var getLocalCrossOrigin = function() {
  var domain;
  if (window.location.host.indexOf("localhost") != -1) {
    domain = "127.0.0.1";
  } else {
    domain = "localhost";
  }

  var port = window.location.port || "80";
  return window.location.protocol + "//" + domain + ":" + port
}

var getRelativePath = function(path) {
  var relparts = window.location.pathname.split("/");
  relparts.pop(); // Pop off filename
  var pathparts = path.split("/");

  var i;
  for (i = 0; i < pathparts.length; ++i) {
    switch (pathparts[i]) {
      case "": break;
      case ".": break;
      case "..":
        relparts.pop();
        break;
      default:
        relparts.push(pathparts[i]);
        break;
    }
  }

  return relparts.join("/");
}

var setupImageForCrossOriginTest = function(img, imgUrl, localUrl, callback) {
  window.addEventListener("load", function() {
    if (typeof(img) == "string")
      img = document.querySelector(img);
    if (!img)
      img = new Image();

    img.addEventListener("load", callback, false);
    img.addEventListener("error", callback, false);

    if (runningOnLocalhost())
      img.src = getLocalCrossOrigin() + getRelativePath(localUrl);
    else
      img.src = getUrlOptions().imgUrl || imgUrl;
  }, false);
}

/**
 * Convert sRGB color to linear color.
 * @param {!Array.<number>} color The color to be converted.
 *        The array has 4 elements, for example [R, G, B, A].
 *        where each element is in the range 0 to 255.
 * @return {!Array.<number>} color The color to be converted.
 *        The array has 4 elements, for example [R, G, B, A].
 *        where each element is in the range 0 to 255.
 */
var sRGBToLinear = function(color) {
    return [sRGBChannelToLinear(color[0]),
            sRGBChannelToLinear(color[1]),
            sRGBChannelToLinear(color[2]),
            color[3]]
}

/**
 * Convert linear color to sRGB color.
 * @param {!Array.<number>} color The color to be converted.
 *        The array has 4 elements, for example [R, G, B, A].
 *        where each element is in the range 0 to 255.
 * @return {!Array.<number>} color The color to be converted.
 *        The array has 4 elements, for example [R, G, B, A].
 *        where each element is in the range 0 to 255.
 */
var linearToSRGB = function(color) {
    return [linearChannelToSRGB(color[0]),
            linearChannelToSRGB(color[1]),
            linearChannelToSRGB(color[2]),
            color[3]]
}

function sRGBChannelToLinear(value) {
    value = value / 255;
    if (value <= 0.04045)
        value = value / 12.92;
    else
        value = Math.pow((value + 0.055) / 1.055, 2.4);
    return Math.trunc(value * 255 + 0.5);
}

function linearChannelToSRGB(value) {
    value = value / 255;
    if (value <= 0.0) {
        value = 0.0;
    } else if (value < 0.0031308) {
        value = value * 12.92;
    } else if (value < 1) {
        value = Math.pow(value, 0.41666) * 1.055 - 0.055;
    } else {
        value = 1.0;
    }
    return Math.trunc(value * 255 + 0.5);
}

function comparePixels(cmp, ref, tolerance, diff) {
    if (cmp.length != ref.length) {
        testFailed("invalid pixel size.");
    }

    var count = 0;
    for (var i = 0; i < cmp.length; i++) {
        diff[i * 4] = 0;
        diff[i * 4 + 1] = 255;
        diff[i * 4 + 2] = 0;
        diff[i * 4 + 3] = 255;
        if (Math.abs(cmp[i * 4] - ref[i * 4]) > tolerance ||
            Math.abs(cmp[i * 4 + 1] - ref[i * 4 + 1]) > tolerance ||
            Math.abs(cmp[i * 4 + 2] - ref[i * 4 + 2]) > tolerance ||
            Math.abs(cmp[i * 4 + 3] - ref[i * 4 + 3]) > tolerance) {
            if (count < 10) {
                testFailed("Pixel " + i + ": expected (" +
                [ref[i * 4], ref[i * 4 + 1], ref[i * 4 + 2], ref[i * 4 + 3]] + "), got (" +
                [cmp[i * 4], cmp[i * 4 + 1], cmp[i * 4 + 2], cmp[i * 4 + 3]] + ")");
            }
            count++;
            diff[i * 4] = 255;
            diff[i * 4 + 1] = 0;
        }
    }

    return count;
}

function displayImageDiff(cmp, ref, diff, width, height) {
    var div = document.createElement("div");

    var cmpImg = createImageFromPixel(cmp, width, height);
    var refImg = createImageFromPixel(ref, width, height);
    var diffImg = createImageFromPixel(diff, width, height);
    wtu.insertImage(div, "Reference", refImg);
    wtu.insertImage(div, "Result", cmpImg);
    wtu.insertImage(div, "Difference", diffImg);

    var console = document.getElementById("console");
    console.appendChild(div);
}

function createImageFromPixel(buf, width, height) {
    var canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext("2d");
    var imgData = ctx.getImageData(0, 0, width, height);

    for (var i = 0; i < buf.length; i++)
        imgData.data[i] = buf[i];
    ctx.putImageData(imgData, 0, 0);
    var img = wtu.makeImageFromCanvas(canvas);
    return img;
}

var API = {
  addShaderSource: addShaderSource,
  addShaderSources: addShaderSources,
  cancelAnimFrame: cancelAnimFrame,
  create3DContext: create3DContext,
  GLErrorException: GLErrorException,
  create3DContextWithWrapperThatThrowsOnGLError: create3DContextWithWrapperThatThrowsOnGLError,
  checkAreaInAndOut: checkAreaInAndOut,
  checkCanvas: checkCanvas,
  checkCanvasRect: checkCanvasRect,
  checkCanvasRectColor: checkCanvasRectColor,
  checkCanvasRects: checkCanvasRects,
  checkFloatBuffer: checkFloatBuffer,
  checkTextureSize: checkTextureSize,
  clipToRange: clipToRange,
  createColoredTexture: createColoredTexture,
  createProgram: createProgram,
  clearAndDrawUnitQuad: clearAndDrawUnitQuad,
  clearAndDrawIndexedQuad: clearAndDrawIndexedQuad,
  comparePixels: comparePixels,
  displayImageDiff: displayImageDiff,
  drawUnitQuad: drawUnitQuad,
  drawIndexedQuad: drawIndexedQuad,
  drawUByteColorQuad: drawUByteColorQuad,
  drawFloatColorQuad: drawFloatColorQuad,
  dummySetProgramAndDrawNothing: dummySetProgramAndDrawNothing,
  dumpShadersInfo: dumpShadersInfo,
  endsWith: endsWith,
  failIfGLError: failIfGLError,
  fillTexture: fillTexture,
  getBytesPerComponent: getBytesPerComponent,
  getDefault3DContextVersion: getDefault3DContextVersion,
  getExtensionPrefixedNames: getExtensionPrefixedNames,
  getExtensionWithKnownPrefixes: getExtensionWithKnownPrefixes,
  getFileListAsync: getFileListAsync,
  getLastError: getLastError,
  getPrefixedProperty: getPrefixedProperty,
  getScript: getScript,
  getSupportedExtensionWithKnownPrefixes: getSupportedExtensionWithKnownPrefixes,
  getTypedArrayElementsPerPixel: getTypedArrayElementsPerPixel,
  getUrlArguments: getUrlArguments,
  getUrlOptions: getUrlOptions,
  getAttribMap: getAttribMap,
  getUniformMap: getUniformMap,
  glEnumToString: glEnumToString,
  glErrorShouldBe: glErrorShouldBe,
  glTypeToTypedArrayType: glTypeToTypedArrayType,
  hasAttributeCaseInsensitive: hasAttributeCaseInsensitive,
  insertImage: insertImage,
  loadImageAsync: loadImageAsync,
  loadImagesAsync: loadImagesAsync,
  loadProgram: loadProgram,
  loadProgramFromFile: loadProgramFromFile,
  loadProgramFromScript: loadProgramFromScript,
  loadProgramFromScriptExpectError: loadProgramFromScriptExpectError,
  loadShader: loadShader,
  loadShaderFromFile: loadShaderFromFile,
  loadShaderFromScript: loadShaderFromScript,
  loadStandardProgram: loadStandardProgram,
  loadStandardProgramAsync: loadStandardProgramAsync,
  loadStandardVertexShader: loadStandardVertexShader,
  loadStandardVertexShaderAsync: loadStandardVertexShaderAsync,
  loadStandardFragmentShader: loadStandardFragmentShader,
  loadStandardFragmentShaderAsync: loadStandardFragmentShaderAsync,
  loadUniformBlockProgram: loadUniformBlockProgram,
  loadUniformBlockVertexShader: loadUniformBlockVertexShader,
  loadUniformBlockFragmentShader: loadUniformBlockFragmentShader,
  loadTextFileAsync: loadTextFileAsync,
  loadTexture: loadTexture,
  log: log,
  loggingOff: loggingOff,
  makeCheckRect: makeCheckRect,
  makeImage: makeImage,
  makeImageFromCanvas: makeImageFromCanvas,
  makeVideo: makeVideo,
  error: error,
  shallowCopyObject: shallowCopyObject,
  setDefault3DContextVersion: setDefault3DContextVersion,
  setupColorQuad: setupColorQuad,
  setupProgram: setupProgram,
  setupTransformFeedbackProgram: setupTransformFeedbackProgram,
  setupQuad: setupQuad,
  setupQuadWithTexCoords: setupQuadWithTexCoords,
  setupIndexedQuad: setupIndexedQuad,
  setupIndexedQuadWithOptions: setupIndexedQuadWithOptions,
  setupSimpleColorProgram: setupSimpleColorProgram,
  setupSimpleTextureProgram: setupSimpleTextureProgram,
  setupSimpleCubeMapTextureProgram: setupSimpleCubeMapTextureProgram,
  setupSimpleVertexColorProgram: setupSimpleVertexColorProgram,
  setupNoTexCoordTextureProgram: setupNoTexCoordTextureProgram,
  setupTexturedQuad: setupTexturedQuad,
  setupTexturedQuadWithTexCoords: setupTexturedQuadWithTexCoords,
  setupTexturedQuadWithCubeMap: setupTexturedQuadWithCubeMap,
  setupUnitQuad: setupUnitQuad,
  setFloatDrawColor: setFloatDrawColor,
  setUByteDrawColor: setUByteDrawColor,
  startPlayingAndWaitForVideo: startPlayingAndWaitForVideo,
  startsWith: startsWith,
  shouldGenerateGLError: shouldGenerateGLError,
  readFile: readFile,
  readFileList: readFileList,
  replaceParams: replaceParams,
  requestAnimFrame: requestAnimFrame,
  runSteps: runSteps,
  waitForComposite: waitForComposite,

  // fullscreen api
  setupFullscreen: setupFullscreen,

  // sRGB converter api
  sRGBToLinear: sRGBToLinear,
  linearToSRGB: linearToSRGB,

  getHost: getHost,
  getBaseDomain: getBaseDomain,
  runningOnLocalhost: runningOnLocalhost,
  getLocalCrossOrigin: getLocalCrossOrigin,
  getRelativePath: getRelativePath,
  setupImageForCrossOriginTest: setupImageForCrossOriginTest,

  none: false
};

Object.defineProperties(API, {
  noTexCoordTextureVertexShader: { value: noTexCoordTextureVertexShader, writable: false },
  simpleTextureVertexShader: { value: simpleTextureVertexShader, writable: false },
  simpleColorFragmentShader: { value: simpleColorFragmentShader, writable: false },
  simpleColorFragmentShaderESSL300: { value: simpleColorFragmentShaderESSL300, writable: false },
  simpleVertexShader: { value: simpleVertexShader, writable: false },
  simpleTextureFragmentShader: { value: simpleTextureFragmentShader, writable: false },
  simpleCubeMapTextureFragmentShader: { value: simpleCubeMapTextureFragmentShader, writable: false },
  simpleVertexColorFragmentShader: { value: simpleVertexColorFragmentShader, writable: false },
  simpleVertexColorVertexShader: { value: simpleVertexColorVertexShader, writable: false }
});

return API;

}());
