/** Generate texture and set filtering parameters.
 *
 *  @param gl              OpenGL functions wrapper
 *  @param target          Texture target
 *  @param internalFormat  Texture internal format
 */
void TextureFilterAnisotropicDrawingTestCase::generateTexture(const glw::Functions& gl, GLenum target)
{
	gl.genTextures(1, &m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures");
	gl.bindTexture(target, m_texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");

	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
}
/** Verify if texParameter*, getTexParameter* queries for GL_TEXTURE_MAX_ANISOTROPY_EXT pname works as expected.
 *
 *  @param gl   OpenGL functions wrapper
 *
 *  @return Returns true if queries test passed, false otherwise.
 */
bool TextureFilterAnisotropicQueriesTestCase::verifyTexParameters(const glw::Functions& gl)
{
	GLint iValue;
	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	// Verify initial integer value which should be equal to 1
	if (iValue != 1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "GetTexParameteriv failed. Expected value: 1, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	GLfloat fValue;
	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	// Verify initial float value which should be equal to 1.0f
	if (fValue != 1.0f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "GetTexParameterfv failed. Expected value: 1.0, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom integer value and verify it
	iValue = 2;
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri");

	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	if (iValue != 2)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameteri failed. Expected value: 2, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom float value and verify it
	fValue = 1.5f;
	gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterf");

	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	if (fValue != 1.5f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameterf failed. Expected value: 1.5, Queried value: " << fValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom integer value and verify it
	iValue = 1;
	gl.texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteriv");

	gl.getTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &iValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv");

	if (iValue != 1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameteriv failed. Expected value: 1, Queried value: " << iValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set custom float value and verify it
	fValue = 2.0f;
	gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "texParameterfv");

	gl.getTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameterfv");

	if (fValue != 2.0f)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
						   << "texParameterfv failed. Expected value: 2.0, Queried value: " << fValue
						   << tcu::TestLog::EndMessage;
		return false;
	}

	// Set texture filter anisotropic to 0.9f and check if INVALID_VALUE error is generated
	fValue = 0.9f;
	gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &fValue);
	GLint error = gl.getError();
	if (error != GL_INVALID_VALUE)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "texParameterfv failed for values less then 1.0f. Expected INVALID_VALUE error. Generated error: "
			<< glu::getErrorName(error) << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}