/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture State Query tests.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureStateQueryTests.hpp"
#include "es2fApiCase.hpp"
#include "glsStateQueryUtil.hpp"
#include "gluRenderContext.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "deRandom.hpp"
#include "deMath.h"

using namespace glw; // GLint and other GL types
using namespace deqp::gls;
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;


namespace deqp
{
namespace gles2
{
namespace Functional
{
namespace TextureParamVerifiers
{

// TexParamVerifier

class TexParamVerifier : protected glu::CallLogWrapper
{
public:
						TexParamVerifier	(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
	virtual				~TexParamVerifier	(); // make GCC happy

	const char*			getTestNamePostfix	(void) const;

	virtual void		verifyInteger		(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)	= DE_NULL;
	virtual void		verifyFloat			(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)	= DE_NULL;
private:
	const char*	const	m_testNamePostfix;
};

TexParamVerifier::TexParamVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
	: glu::CallLogWrapper	(gl, log)
	, m_testNamePostfix		(testNamePostfix)
{
	enableLogging(true);
}
TexParamVerifier::~TexParamVerifier ()
{
}

const char* TexParamVerifier::getTestNamePostfix (void) const
{
	return m_testNamePostfix;
}

class GetTexParameterIVerifier : public TexParamVerifier
{
public:
			GetTexParameterIVerifier	(const glw::Functions& gl, tcu::TestLog& log);

	void	verifyInteger				(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
	void	verifyFloat					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference);
};

GetTexParameterIVerifier::GetTexParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: TexParamVerifier(gl, log, "_gettexparameteri")
{
}

void GetTexParameterIVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetTexParameteriv(target, name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
	}
}

void GetTexParameterIVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
	const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);

	StateQueryMemoryWriteGuard<GLint> state;
	glGetTexParameteriv(target, name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state < expectedGLStateMin || state > expectedGLStateMax)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << expectedGLStateMin << ", " << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
	}
}

class GetTexParameterFVerifier : public TexParamVerifier
{
public:
			GetTexParameterFVerifier	(const glw::Functions& gl, tcu::TestLog& log);

	void	verifyInteger				(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
	void	verifyFloat					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference);
};

GetTexParameterFVerifier::GetTexParameterFVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: TexParamVerifier(gl, log, "_gettexparameterf")
{
}

void GetTexParameterFVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
{
	DE_ASSERT(reference == GLint(GLfloat(reference))); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests

	using tcu::TestLog;

	const GLfloat referenceAsFloat = GLfloat(reference);

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetTexParameterfv(target, name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state != referenceAsFloat)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << referenceAsFloat << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetTexParameterFVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetTexParameterfv(target, name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

} // TextureParamVerifiers

namespace
{

using namespace TextureParamVerifiers;

// Tests

class TextureCase : public ApiCase
{
public:
	TextureCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
		: ApiCase			(context, name, description)
		, m_textureTarget	(textureTarget)
		, m_verifier		(verifier)
	{
	}

	virtual void testTexture (void) = DE_NULL;

	void test (void)
	{
		GLuint textureId = 0;
		glGenTextures(1, &textureId);
		glBindTexture(m_textureTarget, textureId);
		expectError(GL_NO_ERROR);

		testTexture();

		glDeleteTextures(1, &textureId);
		expectError(GL_NO_ERROR);
	}

protected:
	GLenum				m_textureTarget;
	TexParamVerifier*	m_verifier;
};

class TextureWrapCase : public TextureCase
{
public:
	TextureWrapCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget, GLenum valueName)
		: TextureCase	(context, verifier, name, description, textureTarget)
		, m_valueName	(valueName)
	{
	}

	void testTexture (void)
	{
		const GLenum wrapValues[] = {GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT};

		m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, GL_REPEAT);
		expectError(GL_NO_ERROR);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
		{
			glTexParameteri(m_textureTarget, m_valueName, wrapValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
			expectError(GL_NO_ERROR);
		}

		//check unit conversions with float

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
		{
			glTexParameterf(m_textureTarget, m_valueName, (GLfloat)wrapValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
			expectError(GL_NO_ERROR);
		}
	}

private:
	GLenum	m_valueName;
};

class TextureMagFilterCase : public TextureCase
{
public:
	TextureMagFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
		: TextureCase(context, verifier, name, description, textureTarget)
	{
	}

	void testTexture (void)
	{
		const GLenum magValues[] = {GL_NEAREST, GL_LINEAR};

		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		expectError(GL_NO_ERROR);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
		{
			glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
			expectError(GL_NO_ERROR);
		}

		//check unit conversions with float

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
		{
			glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, (GLfloat)magValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
			expectError(GL_NO_ERROR);
		}
	}
};

class TextureMinFilterCase : public TextureCase
{
public:
	TextureMinFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
		: TextureCase(context, verifier, name, description, textureTarget)
	{
	}

	void testTexture (void)
	{
		const GLenum minValues[] = {GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR};

		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
		expectError(GL_NO_ERROR);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
		{
			glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
			expectError(GL_NO_ERROR);
		}

		//check unit conversions with float

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
		{
			glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, (GLfloat)minValues[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
			expectError(GL_NO_ERROR);
		}
	}
};

} // anonymous

#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
	{																							\
		TexParamVerifier* verifier = VERIFIERS[_verifierNdx];									\
		CODE_BLOCK;																				\
	}

TextureStateQueryTests::TextureStateQueryTests (Context& context)
	: TestCaseGroup		(context, "texture", "Texture State Query tests")
	, m_verifierInt		(DE_NULL)
	, m_verifierFloat	(DE_NULL)
{
}

TextureStateQueryTests::~TextureStateQueryTests (void)
{
	deinit();
}

void TextureStateQueryTests::init (void)
{
	using namespace TextureParamVerifiers;

	DE_ASSERT(m_verifierInt == DE_NULL);
	DE_ASSERT(m_verifierFloat == DE_NULL);

	m_verifierInt		= new GetTexParameterIVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierFloat		= new GetTexParameterFVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());

	TexParamVerifier* verifiers[] = {m_verifierInt, m_verifierFloat};

	const struct
	{
		const char*	name;
		GLenum		textureTarget;
	} textureTargets[] =
	{
		{ "texture_2d",			GL_TEXTURE_2D},
		{ "texture_cube_map",	GL_TEXTURE_CUBE_MAP}
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureTargets); ++ndx)
	{
		FOR_EACH_VERIFIER(verifiers, addChild(new TextureWrapCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_wrap_s"			+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_WRAP_S",		textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_S)));
		FOR_EACH_VERIFIER(verifiers, addChild(new TextureWrapCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_wrap_t"			+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_WRAP_T",		textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_T)));

		FOR_EACH_VERIFIER(verifiers, addChild(new TextureMagFilterCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_mag_filter"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MAG_FILTER",	textureTargets[ndx].textureTarget)));
		FOR_EACH_VERIFIER(verifiers, addChild(new TextureMinFilterCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_min_filter"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MIN_FILTER",	textureTargets[ndx].textureTarget)));
	}
}

void TextureStateQueryTests::deinit (void)
{
	if (m_verifierInt)
	{
		delete m_verifierInt;
		m_verifierInt = NULL;
	}
	if (m_verifierFloat)
	{
		delete m_verifierFloat;
		m_verifierFloat = NULL;
	}

	this->TestCaseGroup::deinit();
}

} // Functional
} // gles2
} // deqp
