#ifndef _GLCSHADERRENDERCASE_HPP
#define _GLCSHADERRENDERCASE_HPP
/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 Google Inc.
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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 Shader execute test.
 */ /*-------------------------------------------------------------------*/

#include "glcTestCase.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "tcuDefs.hpp"
#include "tcuMatrix.hpp"
#include "tcuSurface.hpp"
#include "tcuTexture.hpp"
#include "tcuVector.hpp"

#include <sstream>
#include <string>

namespace glu
{
class RenderContext;
class Texture2D;
class TextureCube;
class Texture2DArray;
class Texture3D;
} // glu

namespace deqp
{

// LineStream

class LineStream
{
public:
	LineStream(int indent = 0)
	{
		m_indent = indent;
	}
	~LineStream(void)
	{
	}

	const char* str(void) const
	{
		m_string = m_stream.str();
		return m_string.c_str();
	}
	LineStream& operator<<(const char* line)
	{
		for (int i = 0; i < m_indent; i++)
		{
			m_stream << "\t";
		}
		m_stream << line << "\n";
		return *this;
	}

private:
	int					m_indent;
	std::ostringstream  m_stream;
	mutable std::string m_string;
};

class QuadGrid;

// TextureBinding

class TextureBinding
{
public:
	enum Type
	{
		TYPE_NONE = 0,
		TYPE_2D,
		TYPE_CUBE_MAP,
		TYPE_2D_ARRAY,
		TYPE_3D,

		TYPE_LAST
	};

	TextureBinding(const glu::Texture2D* tex2D, const tcu::Sampler& sampler);
	TextureBinding(const glu::TextureCube* texCube, const tcu::Sampler& sampler);
	TextureBinding(const glu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler);
	TextureBinding(const glu::Texture3D* tex3D, const tcu::Sampler& sampler);
	TextureBinding(void);

	void setSampler(const tcu::Sampler& sampler);
	void setTexture(const glu::Texture2D* tex2D);
	void setTexture(const glu::TextureCube* texCube);
	void setTexture(const glu::Texture2DArray* tex2DArray);
	void setTexture(const glu::Texture3D* tex3D);

	Type getType(void) const
	{
		return m_type;
	}
	const tcu::Sampler& getSampler(void) const
	{
		return m_sampler;
	}
	const glu::Texture2D* get2D(void) const
	{
		DE_ASSERT(getType() == TYPE_2D);
		return m_binding.tex2D;
	}
	const glu::TextureCube* getCube(void) const
	{
		DE_ASSERT(getType() == TYPE_CUBE_MAP);
		return m_binding.texCube;
	}
	const glu::Texture2DArray* get2DArray(void) const
	{
		DE_ASSERT(getType() == TYPE_2D_ARRAY);
		return m_binding.tex2DArray;
	}
	const glu::Texture3D* get3D(void) const
	{
		DE_ASSERT(getType() == TYPE_3D);
		return m_binding.tex3D;
	}

private:
	Type		 m_type;
	tcu::Sampler m_sampler;
	union {
		const glu::Texture2D*	  tex2D;
		const glu::TextureCube*	texCube;
		const glu::Texture2DArray* tex2DArray;
		const glu::Texture3D*	  tex3D;
	} m_binding;
};

// ShaderEvalContext.

class ShaderEvalContext
{
public:
	// Limits.
	enum
	{
		MAX_USER_ATTRIBS = 4,
		MAX_TEXTURES	 = 4,
	};

	struct ShaderSampler
	{
		tcu::Sampler			   sampler;
		const tcu::Texture2D*	  tex2D;
		const tcu::TextureCube*	texCube;
		const tcu::Texture2DArray* tex2DArray;
		const tcu::Texture3D*	  tex3D;

		inline ShaderSampler(void) : tex2D(DE_NULL), texCube(DE_NULL), tex2DArray(DE_NULL), tex3D(DE_NULL)
		{
		}
	};

	ShaderEvalContext(const QuadGrid& quadGrid);
	~ShaderEvalContext(void);

	void reset(float sx, float sy);

	// Inputs.
	tcu::Vec4 coords;
	tcu::Vec4 unitCoords;
	tcu::Vec4 constCoords;

	tcu::Vec4	 in[MAX_USER_ATTRIBS];
	ShaderSampler textures[MAX_TEXTURES];

	// Output.
	tcu::Vec4 color;
	bool	  isDiscarded;

	// Functions.
	inline void discard(void)
	{
		isDiscarded = true;
	}
	tcu::Vec4 texture2D(int unitNdx, const tcu::Vec2& coords);

private:
	const QuadGrid& quadGrid;
};

// ShaderEvalFunc.

typedef void (*ShaderEvalFunc)(ShaderEvalContext& c);

inline void evalCoordsPassthroughX(ShaderEvalContext& c)
{
	c.color.x() = c.coords.x();
}
inline void evalCoordsPassthroughXY(ShaderEvalContext& c)
{
	c.color.xy() = c.coords.swizzle(0, 1);
}
inline void evalCoordsPassthroughXYZ(ShaderEvalContext& c)
{
	c.color.xyz() = c.coords.swizzle(0, 1, 2);
}
inline void evalCoordsPassthrough(ShaderEvalContext& c)
{
	c.color = c.coords;
}
inline void evalCoordsSwizzleWZYX(ShaderEvalContext& c)
{
	c.color = c.coords.swizzle(3, 2, 1, 0);
}

// ShaderEvaluator
// Either inherit a class with overridden evaluate() or just pass in an evalFunc.

class ShaderEvaluator
{
public:
	ShaderEvaluator(void);
	ShaderEvaluator(ShaderEvalFunc evalFunc);
	virtual ~ShaderEvaluator(void);

	virtual void evaluate(ShaderEvalContext& ctx);

private:
	ShaderEvaluator(const ShaderEvaluator&);			// not allowed!
	ShaderEvaluator& operator=(const ShaderEvaluator&); // not allowed!

	ShaderEvalFunc m_evalFunc;
};

// ShaderRenderCase.

class ShaderRenderCase : public tcu::TestCase
{
public:
	ShaderRenderCase(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo,
					 const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc);
	ShaderRenderCase(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo,
					 const char* name, const char* description, bool isVertexCase, ShaderEvaluator& evaluator);
	virtual ~ShaderRenderCase(void);

	void init(void);
	void deinit(void);

	IterateResult iterate(void);

protected:
	virtual void setup(deUint32 programID);
	virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords);

	tcu::IVec2 getViewportSize(void) const;

private:
	ShaderRenderCase(const ShaderRenderCase&);			  // not allowed!
	ShaderRenderCase& operator=(const ShaderRenderCase&); // not allowed!

	void setupDefaultInputs(int programID);

	void render(tcu::Surface& result, int programID, const QuadGrid& quadGrid);
	void computeVertexReference(tcu::Surface& result, const QuadGrid& quadGrid);
	void computeFragmentReference(tcu::Surface& result, const QuadGrid& quadGrid);
	bool compareImages(const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold);

protected:
	glu::RenderContext&		m_renderCtx;
	const glu::ContextInfo& m_ctxInfo;

	bool			 m_isVertexCase;
	ShaderEvaluator  m_defaultEvaluator;
	ShaderEvaluator& m_evaluator;
	std::string		 m_vertShaderSource;
	std::string		 m_fragShaderSource;
	tcu::Vec4		 m_clearColor;

	std::vector<tcu::Mat4>		m_userAttribTransforms;
	std::vector<TextureBinding> m_textures;

	glu::ShaderProgram* m_program;
};

// Helpers.
// \todo [2012-04-10 pyry] Move these to separate utility?

const char* getIntUniformName(int number);
const char* getFloatUniformName(int number);
const char* getFloatFractionUniformName(int number);

void setupDefaultUniforms(const glu::RenderContext& context, deUint32 programID);

} // deqp

#endif // _GLCSHADERRENDERCASE_HPP
