#ifndef _GLSFBOCOMPLETENESSTESTS_HPP
#define _GLSFBOCOMPLETENESSTESTS_HPP

/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) 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 Common parts for ES2/3 framebuffer completeness tests.
 *//*--------------------------------------------------------------------*/

#include "tcuTestCase.hpp"
#include "gluRenderContext.hpp"
#include "glsFboUtil.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "tcuTestCase.hpp"
#include "tcuTestLog.hpp"

namespace deqp
{
namespace gls
{
namespace fboc
{

namespace details
{

using glu::RenderContext;
using tcu::TestCase;
using tcu::TestContext;
typedef TestCase::IterateResult IterateResult;
using tcu::TestCaseGroup;
using tcu::TestLog;
using std::string;

using namespace glw;
using namespace deqp::gls::FboUtil;
using namespace deqp::gls::FboUtil::config;

class Context
{
public:
							Context					(TestContext& testCtx,
													 RenderContext& renderCtx,
													 CheckerFactory& factory);
	RenderContext&			getRenderContext		(void) const { return m_renderCtx; }
	TestContext&			getTestContext			(void) const { return m_testCtx; }
	const FboVerifier&		getVerifier				(void) const { return m_verifier; }
	const FormatDB&			getMinFormats			(void) const { return m_minFormats; }
	const FormatDB&			getCtxFormats			(void) const { return m_ctxFormats; }
	bool					haveMultiColorAtts		(void) const { return m_haveMultiColorAtts; }
	void					setHaveMulticolorAtts	(bool have) { m_haveMultiColorAtts = have; }
	void					addFormats				(FormatEntries fmtRange);
	void					addExtFormats			(FormatExtEntries extRange);
	TestCaseGroup*			createRenderableTests	(void);
	TestCaseGroup*			createAttachmentTests	(void);
	TestCaseGroup*			createSizeTests			(void);
private:
	TestContext&			m_testCtx;
	RenderContext&			m_renderCtx;
	FormatDB				m_minFormats;
	FormatDB				m_ctxFormats;
	FormatDB				m_maxFormats;
	FboVerifier				m_verifier;
	bool					m_haveMultiColorAtts;
};

class TestBase : public TestCase
{
public:
	Context&				getContext			(void) const { return m_ctx; }

protected:

							TestBase			(Context& ctx,
												 const string& name, const string& desc)
								: TestCase		(ctx.getTestContext(),
												 name.c_str(), desc.c_str())
								, m_ctx			(ctx) {}
	void					fail				(const char* msg);
	void					qualityWarning		(const char* msg);
	void					pass				(void);
	void					checkFbo			(FboBuilder& builder);
	ImageFormat				getDefaultFormat	(GLenum attPoint, GLenum bufType) const;

	IterateResult			iterate				(void);

	virtual IterateResult	build				(FboBuilder& builder);

	void					attachTargetToNew	(GLenum target, GLenum bufType,
												 ImageFormat format,
												 GLsizei width, GLsizei height,
												 FboBuilder& builder);
	Context&				m_ctx;
};

	// Utilities for building
Image* 				makeImage			(GLenum bufType, ImageFormat format,
										 GLsizei width, GLsizei height, FboBuilder& builder);
Attachment*			makeAttachment		(GLenum bufType, ImageFormat format,
										 GLsizei width, GLsizei height, FboBuilder& builder);

template <typename P>
class ParamTest : public TestBase
{
public:
	typedef P	Params;
				ParamTest		(Context& ctx, const Params& params)
					: TestBase	(ctx, Params::getName(params), Params::getDescription(params))
					, m_params	(params) {}

protected:
	Params		m_params;
};

// Shorthand utility
const glw::Functions& gl (const TestBase& test);

} // details

using details::Context;
using details::TestBase;
using details::ParamTest;
using details::gl;

} // fboc
} // gls
} // deqp

#endif // _GLSFBOCOMPLETENESSTESTS_HPP
