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