<!--

/*
** 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.
*/

-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL getTexParameter test</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="example" width="4" height="4" style="width: 40px; height: 30px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description();
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example");

// NOTE: We explicitly do this in a funky order
// to hopefully find subtle bugs.

var targets = [
  'TEXTURE_2D',
  'TEXTURE_2D',
  'TEXTURE_CUBE_MAP',
  'TEXTURE_CUBE_MAP'
];
// Create textures on different active textures.
for (var ii = 0; ii < targets.length; ++ii) {
  var target = targets[ii];
  var tex = gl.createTexture();
  gl.activeTexture(gl.TEXTURE0 + ii);
  gl.bindTexture(gl[target], tex);
}

wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");

var states = [
  { state:'TEXTURE_WRAP_S',     default: 'REPEAT',                value1: 'CLAMP_TO_EDGE',        value2: 'REPEAT'        },
  { state:'TEXTURE_WRAP_T',     default: 'REPEAT',                value1: 'CLAMP_TO_EDGE',        value2: 'REPEAT'        },
  { state:'TEXTURE_MAG_FILTER', default: 'LINEAR',                value1: 'NEAREST',              value2: 'LINEAR'        },
  { state:'TEXTURE_MIN_FILTER', default: 'NEAREST_MIPMAP_LINEAR', value1: 'LINEAR_MIPMAP_LINEAR', value2: 'NEAREST'       }
];

function applyStates(fn) {
  for (var ss = 0; ss < states.length; ++ss) {
    var stateInfo = states[ss];
    for (var ii = 0; ii < targets.length; ++ii) {
          var target = targets[ii];
      gl.activeTexture(gl.TEXTURE0 + ii);
      fn(target, stateInfo);
    }
  }
}

// test the default state.
applyStates(function(target, stateInfo) {
  var a = 'gl.getTexParameter(gl["' + target + '"], gl["' + stateInfo.state + '"])';
  var b = 'gl["' + stateInfo.default + '"]';
  shouldBe(a, b);
});

// test new state
applyStates(function(target, stateInfo) {
  gl.texParameteri(gl[target], gl[stateInfo.state], gl[stateInfo.value1]);
});

applyStates(function(target, stateInfo) {
  var a = 'gl.getTexParameter(gl["' + target + '"], gl["' + stateInfo.state + '"])';
  var b = 'gl["' + stateInfo.value1 + '"]';
  shouldBe(a, b);
});

// test different states on each target.
function getStateValue(count, stateInfo) {
  return (count % 2) ? stateInfo.value2 : stateInfo.value1;
}

applyStates(function() {
  var count = 0;
  return function(target, stateInfo) {
    gl.texParameteri(gl[target], gl[stateInfo.state], gl[getStateValue(count, stateInfo)]);
    ++count;
  }
}());

applyStates(function() {
  var count = 0;
  return function(target, stateInfo) {
    var a = 'gl.getTexParameter(gl["' + target + '"], gl["' + stateInfo.state + '"])';
    var b = 'gl["' + getStateValue(count, stateInfo) + '"]';
    shouldBe(a, b);
    ++count;
  };
}());

wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");

var successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>

</body>
</html>


