#ifndef _GLSLIFETIMETESTS_HPP
#define _GLSLIFETIMETESTS_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 object lifetime tests.
 *//*--------------------------------------------------------------------*/

#include "deRandom.hpp"
#include "deUniquePtr.hpp"
#include "tcuSurface.hpp"
#include "tcuTestCase.hpp"
#include "tcuTestContext.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluRenderContext.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"

#include <vector>

namespace deqp
{
namespace gls
{
namespace LifetimeTests
{
namespace details
{

using std::vector;
using de::MovePtr;
using de::Random;
using tcu::Surface;
using tcu::TestCaseGroup;
using tcu::TestContext;
using tcu::TestLog;
using glu::CallLogWrapper;
using glu::RenderContext;
using namespace glw;

typedef void		(CallLogWrapper::*BindFunc)		(GLenum target, GLuint name);
typedef void		(CallLogWrapper::*GenFunc)		(GLsizei n, GLuint* names);
typedef void		(CallLogWrapper::*DeleteFunc)	(GLsizei n, const GLuint* names);
typedef GLboolean	(CallLogWrapper::*ExistsFunc)	(GLuint name);

class Context
{
public:
							Context				(const RenderContext& renderCtx,
												 TestContext& testCtx)
								: m_renderCtx	(renderCtx)
								, m_testCtx		(testCtx) {}
	const RenderContext&	getRenderContext	(void) const { return m_renderCtx; }
	TestContext&			getTestContext		(void) const { return m_testCtx; }
	const Functions&		gl					(void) const { return m_renderCtx.getFunctions(); }
	TestLog&				log					(void) const { return m_testCtx.getLog(); }

private:
	const RenderContext&	m_renderCtx;
	TestContext&			m_testCtx;
};

class ContextWrapper : public CallLogWrapper
{
public:
	const Context&			getContext			(void) const { return m_ctx; }
	const RenderContext&	getRenderContext	(void) const { return m_ctx.getRenderContext(); }
	TestContext&			getTestContext		(void) const { return m_ctx.getTestContext(); }
	const Functions&		gl					(void) const { return m_ctx.gl(); }
	TestLog&				log					(void) const { return m_ctx.log(); }
	void					enableLogging		(bool enable)
	{
		CallLogWrapper::enableLogging(enable);
	}

protected:
							ContextWrapper				(const Context& ctx);
	const Context			m_ctx;
};

class Binder : public ContextWrapper
{
public:
	virtual				~Binder			(void) {}
	virtual void		bind			(GLuint name) = 0;
	virtual GLuint		getBinding		(void) = 0;
	virtual bool		genRequired		(void) const { return true; }

protected:
						Binder			(const Context& ctx) : ContextWrapper(ctx) {}
};

class SimpleBinder : public Binder
{
public:
						SimpleBinder	(const Context& ctx,
										 BindFunc bindFunc,
										 GLenum bindTarget,
										 GLenum bindingParam,
										 bool genRequired_ = false)
							: Binder			(ctx)
							, m_bindFunc		(bindFunc)
							, m_bindTarget		(bindTarget)
							, m_bindingParam	(bindingParam)
							, m_genRequired		(genRequired_) {}

	void				bind			(GLuint name);
	GLuint				getBinding		(void);
	bool				genRequired		(void) const { return m_genRequired; }

private:
	const BindFunc		m_bindFunc;
	const GLenum		m_bindTarget;
	const GLenum		m_bindingParam;
	const bool			m_genRequired;
};

class Type : public ContextWrapper
{
public:
	virtual					~Type			(void) {}
	virtual GLuint			gen				(void) = 0;
	virtual void			release			(GLuint name) = 0;
	virtual bool			exists			(GLuint name) = 0;
	virtual bool			isDeleteFlagged	(GLuint name) { DE_UNREF(name); return false; }
	virtual Binder*			binder			(void) const { return DE_NULL; }
	virtual const char*		getName			(void) const = 0;
	virtual bool			nameLingers		(void) const { return false; }
	virtual bool			genCreates		(void) const { return false; }

protected:
							Type			(const Context& ctx) : ContextWrapper(ctx) {}
};

class SimpleType : public Type
{
public:
				SimpleType	(const Context& ctx, const char* name,
							 GenFunc genFunc, DeleteFunc deleteFunc, ExistsFunc existsFunc,
							 Binder* binder_ = DE_NULL, bool genCreates_ = false)
						: Type			(ctx)
						, m_getName		(name)
						, m_genFunc		(genFunc)
						, m_deleteFunc	(deleteFunc)
						, m_existsFunc	(existsFunc)
						, m_binder		(binder_)
						, m_genCreates	(genCreates_) {}

	GLuint			gen 		(void);
	void			release		(GLuint name)		{ (this->*m_deleteFunc)(1, &name); }
	bool			exists		(GLuint name)		{ return (this->*m_existsFunc)(name) != GL_FALSE; }
	Binder*			binder		(void) const		{ return m_binder; }
	const char*		getName		(void) const		{ return m_getName; }
	bool			nameLingers	(void) const		{ return false; }
	bool			genCreates	(void) const		{ return m_genCreates; }

private:
	const char* const	m_getName;
	const GenFunc		m_genFunc;
	const DeleteFunc	m_deleteFunc;
	const ExistsFunc	m_existsFunc;
	Binder* const		m_binder;
	const bool			m_genCreates;
};

class ProgramType : public Type
{
public:
					ProgramType		(const Context& ctx) : Type(ctx) {}
	bool			nameLingers		(void) const	{ return true; }
	bool			genCreates		(void) const	{ return true; }
	const char*		getName			(void) const	{ return "program"; }
	GLuint			gen				(void)			{ return glCreateProgram(); }
	void			release			(GLuint name)	{ glDeleteProgram(name); }
	bool			exists			(GLuint name)	{ return glIsProgram(name) != GL_FALSE; }
	bool			isDeleteFlagged	(GLuint name);
};

class ShaderType : public Type
{
public:
					ShaderType		(const Context& ctx) : Type(ctx) {}
	bool			nameLingers		(void) const { return true; }
	bool			genCreates		(void) const { return true; }
	const char*		getName			(void) const { return "shader"; }
	GLuint			gen				(void) { return glCreateShader(GL_FRAGMENT_SHADER); }
	void			release			(GLuint name) { glDeleteShader(name); }
	bool			exists			(GLuint name) { return glIsShader(name) != GL_FALSE; }
	bool			isDeleteFlagged	(GLuint name);
};

class Attacher : public ContextWrapper
{
public:
	virtual void		initAttachment			(GLuint seed, GLuint attachment) = 0;
	virtual void		attach					(GLuint element, GLuint container) = 0;
	virtual void		detach					(GLuint element, GLuint container) = 0;
	virtual GLuint		getAttachment			(GLuint container) = 0;
	virtual bool		canAttachDeleted		(void) const { return true; }

	Type&				getElementType			(void) const { return m_elementType; }
	Type&				getContainerType		(void) const { return m_containerType; }
	virtual				~Attacher				(void) {}

protected:
						Attacher				(const Context& ctx,
												 Type& elementType, Type& containerType)
							: ContextWrapper	(ctx)
							, m_elementType		(elementType)
							, m_containerType	(containerType) {}

private:
	Type&				m_elementType;
	Type&				m_containerType;
};

class InputAttacher : public ContextWrapper
{
public:
	Attacher&			getAttacher				(void) const { return m_attacher; }
	virtual void		drawContainer			(GLuint container, Surface& dst) = 0;
protected:
						InputAttacher			(Attacher& attacher)
							: ContextWrapper	(attacher.getContext())
							, m_attacher		(attacher) {}
	Attacher&			m_attacher;
};

class OutputAttacher : public ContextWrapper
{
public:
	Attacher&			getAttacher				(void) const { return m_attacher; }
	virtual void		setupContainer			(GLuint seed, GLuint container) = 0;
	virtual void		drawAttachment			(GLuint attachment, Surface& dst) = 0;
protected:
						OutputAttacher			(Attacher& attacher)
							: ContextWrapper	(attacher.getContext())
							, m_attacher		(attacher) {}
	Attacher&			m_attacher;
};

class Types : public ContextWrapper
{
public:
									Types				(const Context& ctx)
										: ContextWrapper(ctx) {}
	virtual Type&					getProgramType		(void) = 0;
	const vector<Type*>&			getTypes			(void) { return m_types; }
	const vector<Attacher*>&		getAttachers		(void) { return m_attachers; }
	const vector<InputAttacher*>&	getInputAttachers	(void) { return m_inAttachers; }
	const vector<OutputAttacher*>&	getOutputAttachers	(void) { return m_outAttachers; }
	virtual							~Types				(void) {}

protected:
	vector<Type*>					m_types;
	vector<Attacher*>				m_attachers;
	vector<InputAttacher*>			m_inAttachers;
	vector<OutputAttacher*>			m_outAttachers;
};

class FboAttacher : public Attacher
{
public:
	void			initAttachment		(GLuint seed, GLuint element);

protected:
					FboAttacher			(const Context& ctx,
										 Type& elementType, Type& containerType)
						: Attacher 		(ctx, elementType, containerType) {}
	virtual void	initStorage			(void) = 0;
};

class FboInputAttacher : public InputAttacher
{
public:
			FboInputAttacher		(FboAttacher& attacher)
				: InputAttacher 	(attacher) {}
	void	drawContainer			(GLuint container, Surface& dst);
};

class FboOutputAttacher : public OutputAttacher
{
public:
			FboOutputAttacher			(FboAttacher& attacher)
				: OutputAttacher 		(attacher) {}
	void	setupContainer				(GLuint seed, GLuint container);
	void	drawAttachment				(GLuint attachment, Surface& dst);
};

class TextureFboAttacher : public FboAttacher
{
public:
			TextureFboAttacher	(const Context& ctx, Type& elementType, Type& containerType)
				: FboAttacher	(ctx, elementType, containerType) {}

	void	initStorage			(void);
	void	attach				(GLuint element, GLuint container);
	void	detach				(GLuint element, GLuint container);
	GLuint	getAttachment		(GLuint container);
};

class RboFboAttacher : public FboAttacher
{
public:
			RboFboAttacher		(const Context& ctx, Type& elementType, Type& containerType)
				: FboAttacher	(ctx, elementType, containerType) {}

	void	initStorage			(void);
	void	attach				(GLuint element, GLuint container);
	void	detach				(GLuint element, GLuint container);
	GLuint	getAttachment		(GLuint container);
};

class ShaderProgramAttacher : public Attacher
{
public:
			ShaderProgramAttacher	(const Context& ctx,
									 Type& elementType, Type& containerType)
				: Attacher			(ctx, elementType, containerType) {}

	void	initAttachment		(GLuint seed, GLuint element);
	void	attach				(GLuint element, GLuint container);
	void	detach				(GLuint element, GLuint container);
	GLuint	getAttachment		(GLuint container);
};

class ShaderProgramInputAttacher : public InputAttacher
{
public:
			ShaderProgramInputAttacher	(Attacher& attacher)
				: InputAttacher			(attacher) {}

	void	drawContainer				(GLuint container, Surface& dst);
};

class ES2Types : public Types
{
public:
								ES2Types		(const Context& ctx);
	Type&						getProgramType	(void) { return m_programType; }

protected:
	SimpleBinder				m_bufferBind;
	SimpleType					m_bufferType;
	SimpleBinder				m_textureBind;
	SimpleType					m_textureType;
	SimpleBinder				m_rboBind;
	SimpleType					m_rboType;
	SimpleBinder				m_fboBind;
	SimpleType					m_fboType;
	ShaderType					m_shaderType;
	ProgramType					m_programType;
	TextureFboAttacher			m_texFboAtt;
	FboInputAttacher			m_texFboInAtt;
	FboOutputAttacher			m_texFboOutAtt;
	RboFboAttacher				m_rboFboAtt;
	FboInputAttacher			m_rboFboInAtt;
	FboOutputAttacher			m_rboFboOutAtt;
	ShaderProgramAttacher		m_shaderAtt;
	ShaderProgramInputAttacher	m_shaderInAtt;
};

MovePtr<TestCaseGroup>	createGroup		(TestContext& testCtx, Type& type);
void					addTestCases	(TestCaseGroup& group, Types& types);

struct Rectangle
{
			Rectangle	(GLint x_, GLint y_, GLint width_, GLint height_)
				: x			(x_)
				, y			(y_)
				, width		(width_)
				, height	(height_) {}
	GLint	x;
	GLint	y;
	GLint	width;
	GLint	height;
};

Rectangle	randomViewport	(const RenderContext& ctx, GLint maxWidth, GLint maxHeight,
							 Random& rnd);
void		setViewport		(const RenderContext& renderCtx, const Rectangle& rect);
void		readRectangle	(const RenderContext& renderCtx, const Rectangle& rect,
							 Surface& dst);

} // details

using details::BindFunc;
using details::GenFunc;
using details::DeleteFunc;
using details::ExistsFunc;

using details::Context;
using details::Binder;
using details::SimpleBinder;
using details::Type;
using details::SimpleType;
using details::Attacher;
using details::InputAttacher;
using details::OutputAttacher;
using details::Types;
using details::ES2Types;

using details::createGroup;
using details::addTestCases;

using details::Rectangle;
using details::randomViewport;
using details::setViewport;
using details::readRectangle;

} // LifetimeTests
} // gls
} // deqp

#endif // _GLSLIFETIMETESTS_HPP
