/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2015 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 Boolean State Query tests.
 *//*--------------------------------------------------------------------*/

#include "es31fBooleanStateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluCallLogWrapper.hpp"
#include "tcuRenderTarget.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using namespace gls::StateQueryUtil;

static const char* getVerifierSuffix (QueryType type)
{
	switch (type)
	{
		case QUERY_ISENABLED:	return "isenabled";
		case QUERY_BOOLEAN:		return "getboolean";
		case QUERY_INTEGER:		return "getinteger";
		case QUERY_INTEGER64:	return "getinteger64";
		case QUERY_FLOAT:		return "getfloat";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

class IsEnabledStateTestCase : public TestCase, private glu::CallLogWrapper
{
public:
	IsEnabledStateTestCase (Context& context, QueryType verifier, const char* name, const char* description, glw::GLenum targetName, bool initial, glu::ApiType minimumContextVersion)
		: TestCase				(context, name, description)
		, glu::CallLogWrapper	(context.getRenderContext().getFunctions(), context.getTestContext().getLog())
		, m_targetName			(targetName)
		, m_initial				(initial)
		, m_verifier			(verifier)
		, m_minimumVersion		(minimumContextVersion)
	{
	}

	IterateResult iterate (void)
	{
		if (!contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
			TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(m_context.getRenderContext().getType(), m_minimumVersion), "This test requires a higher context version.");

		tcu::ResultCollector result(m_testCtx.getLog(), " // ERROR: ");
		enableLogging(true);

		// check inital value
		verifyStateBoolean(result, *this, m_targetName, m_initial, m_verifier);

		// check toggle

		GLU_CHECK_CALL(glEnable(m_targetName));

		verifyStateBoolean(result, *this, m_targetName, true, m_verifier);

		GLU_CHECK_CALL(glDisable(m_targetName));

		verifyStateBoolean(result, *this, m_targetName, false, m_verifier);

		result.setTestContextResult(m_testCtx);
		return STOP;
	}

private:
	const glw::GLenum		m_targetName;
	const bool				m_initial;
	const QueryType			m_verifier;
	const glu::ApiType		m_minimumVersion;
};

} // anonymous

BooleanStateQueryTests::BooleanStateQueryTests (Context& context)
	: TestCaseGroup(context, "boolean", "Boolean State Query tests")
{
}

BooleanStateQueryTests::~BooleanStateQueryTests (void)
{
}

void BooleanStateQueryTests::init (void)
{
	const bool isDebugContext = (m_context.getRenderContext().getType().getFlags() & glu::CONTEXT_DEBUG) != 0;

	static const QueryType isEnabledVerifiers[] =
	{
		QUERY_ISENABLED,
		QUERY_BOOLEAN,
		QUERY_INTEGER,
		QUERY_INTEGER64,
		QUERY_FLOAT
	};

#define FOR_EACH_VERIFIER(VERIFIERS, X) \
	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); ++verifierNdx)	\
	{																						\
		const char* verifierSuffix = getVerifierSuffix((VERIFIERS)[verifierNdx]);			\
		const QueryType verifier = (VERIFIERS)[verifierNdx];								\
		this->addChild(X);																	\
	}

	struct StateBoolean
	{
		const char*		name;
		const char*		description;
		glw::GLenum		targetName;
		bool			value;
		glu::ApiType	minimumContext;
	};

	{
		const StateBoolean isEnableds[] =
		{
			{ "sample_mask",				"SAMPLE_MASK",				GL_SAMPLE_MASK,					false,			glu::ApiType::es(3, 1)},
			{ "sample_shading",				"SAMPLE_SHADING",			GL_SAMPLE_SHADING,				false,			glu::ApiType::es(3, 2)},
			{ "debug_output",				"DEBUG_OUTPUT",				GL_DEBUG_OUTPUT,				isDebugContext,	glu::ApiType::es(3, 2)},
			{ "debug_output_synchronous",	"DEBUG_OUTPUT_SYNCHRONOUS",	GL_DEBUG_OUTPUT_SYNCHRONOUS,	false,			glu::ApiType::es(3, 2)},
		};

		for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(isEnableds); testNdx++)
		{
			FOR_EACH_VERIFIER(isEnabledVerifiers, new IsEnabledStateTestCase(m_context, verifier, (std::string(isEnableds[testNdx].name) + "_" + verifierSuffix).c_str(), isEnableds[testNdx].description, isEnableds[testNdx].targetName, isEnableds[testNdx].value, isEnableds[testNdx].minimumContext));
		}
	}

#undef FOR_EACH_VERIFIER
}

} // Functional
} // gles31
} // deqp
