/*-------------------------------------------------------------------------
 * 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 Prerequisite tests.
 *//*--------------------------------------------------------------------*/

#include "es2fPrerequisiteTests.hpp"
#include "deRandom.h"
#include "tcuRGBA.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStateReset.hpp"

#include "glw.h"

using tcu::RGBA;
using tcu::Surface;
using tcu::TestLog;

namespace deqp
{
namespace gles2
{
namespace Functional
{

class StateResetCase : public TestCase
{
public:
										StateResetCase	(Context& context);
	virtual								~StateResetCase	(void);
	virtual TestCase::IterateResult		iterate			(void);
};

StateResetCase::StateResetCase (Context& context)
	: TestCase(context, "state_reset", "State Reset Test")
{
}

StateResetCase::~StateResetCase (void)
{
}

TestCase::IterateResult StateResetCase::iterate (void)
{
	try
	{
		glu::resetState(m_context.getRenderContext(), m_context.getContextInfo());
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	catch (const tcu::TestError& e)
	{
		m_testCtx.getLog() << e;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}

	return TestCase::STOP;
}

class ClearColorCase : public TestCase
{
public:
										ClearColorCase		(Context& context);
	virtual								~ClearColorCase		(void);
	virtual TestCase::IterateResult		iterate				(void);

private:
	RGBA		m_clearColor;
	int			m_numIters;
	int			m_curIter;
};

ClearColorCase::ClearColorCase (Context& context)
	: TestCase		(context, "clear_color", "glClearColor test")
	, m_numIters	(10)
	, m_curIter		(0)
{
}

ClearColorCase::~ClearColorCase (void)
{
}

TestCase::IterateResult ClearColorCase::iterate (void)
{
	int r = 0;
	int g = 0;
	int b = 0;
	int a = 255;

	switch (m_curIter)
	{
		case 0:
			// Black, skip
			break;
		case 1:
			r = 255;
			g = 255;
			b = 255;
			break;
		case 2:
			r = 255;
			break;
		case 3:
			g = 255;
			break;
		case 4:
			b = 255;
			break;
		default:
			deRandom rnd;
			deRandom_init(&rnd, deInt32Hash(m_curIter));
			r = (int)(deRandom_getUint32(&rnd) & 0xFF);
			g = (int)(deRandom_getUint32(&rnd) & 0xFF);
			b = (int)(deRandom_getUint32(&rnd) & 0xFF);
			a = (int)(deRandom_getUint32(&rnd) & 0xFF);
			break;

	};

	glClearColor(float(r)/255.0f, float(g)/255.0f, float(b)/255.0f, float(a)/255.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	GLU_CHECK_MSG("CLES2 ClearColor failed.");

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return (++m_curIter < m_numIters) ? CONTINUE : STOP;
}

class ReadPixelsCase : public TestCase
{
public:
										ReadPixelsCase		(Context& context);
	virtual								~ReadPixelsCase		(void);
	virtual TestCase::IterateResult		iterate				(void);

private:
	int m_numIters;
	int m_curIter;
};

ReadPixelsCase::ReadPixelsCase (Context& context)
	: TestCase(context, "read_pixels", "Read pixels test")
	, m_numIters(20)
	, m_curIter(0)
{
}

ReadPixelsCase::~ReadPixelsCase (void)
{
}

TestCase::IterateResult ReadPixelsCase::iterate (void)
{
	const tcu::RenderTarget&	renderTarget	= m_context.getRenderTarget();
	tcu::PixelFormat			pixelFormat		= renderTarget.getPixelFormat();
	int							targetWidth		= renderTarget.getWidth();
	int							targetHeight	= renderTarget.getHeight();
	int							x				= 0;
	int							y				= 0;
	int							imageWidth		= 0;
	int							imageHeight		= 0;

	deRandom rnd;
	deRandom_init(&rnd, deInt32Hash(m_curIter));

	switch (m_curIter)
	{
		case 0:
			// Fullscreen
			x = 0;
			y = 0;
			imageWidth  = targetWidth;
			imageHeight = targetHeight;
			break;
		case 1:
			// Upper left corner
			x = 0;
			y = 0;
			imageWidth = targetWidth / 2;
			imageHeight = targetHeight / 2;
			break;
		case 2:
			// Lower right corner
			x = targetWidth / 2;
			y = targetHeight / 2;
			imageWidth = targetWidth - x;
			imageHeight = targetHeight - y;
			break;
		default:
			x = deRandom_getUint32(&rnd) % (targetWidth - 1);
			y = deRandom_getUint32(&rnd) % (targetHeight - 1);
			imageWidth = 1 + (deRandom_getUint32(&rnd) % (targetWidth - x - 1));
			imageHeight = 1 + (deRandom_getUint32(&rnd) % (targetHeight - y - 1));
			break;
	}

	Surface	resImage(imageWidth, imageHeight);
	Surface	refImage(imageWidth, imageHeight);
	Surface	diffImage(imageWidth, imageHeight);

	int r = (int)(deRandom_getUint32(&rnd) & 0xFF);
	int g = (int)(deRandom_getUint32(&rnd) & 0xFF);
	int b = (int)(deRandom_getUint32(&rnd) & 0xFF);

	tcu::clear(refImage.getAccess(), tcu::IVec4(r, g, b, 255));
	glClearColor(float(r)/255.0f, float(g)/255.0f, float(b)/255.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	glu::readPixels(m_context.getRenderContext(), x, y, resImage.getAccess());
	GLU_CHECK_MSG("glReadPixels() failed.");

	RGBA colorThreshold = pixelFormat.getColorThreshold();
	RGBA matchColor(0, 255, 0, 255);
	RGBA diffColor(255, 0, 0, 255);
	bool isImageOk = true;

	for (int j = 0; j < imageHeight; j++)
	{
		for (int i = 0; i < imageWidth; i++)
		{
			RGBA		resRGBA		= resImage.getPixel(i, j);
			RGBA		refRGBA		= refImage.getPixel(i, j);
			bool		isPixelOk	= compareThreshold(refRGBA, resRGBA, colorThreshold);
			diffImage.setPixel(i, j, isPixelOk ? matchColor : diffColor);

			isImageOk = isImageOk && isPixelOk;
		}
	}

	if (isImageOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		TestLog& log = m_testCtx.getLog();
		log << TestLog::ImageSet("Result", "Resulting framebuffer")
			<< TestLog::Image("Result",		"Resulting framebuffer",	resImage)
			<< TestLog::Image("Reference",	"Reference image",			refImage)
			<< TestLog::Image("DiffMask",	"Failing pixels",			diffImage)
			<< TestLog::EndImageSet;
	}

	return (++m_curIter < m_numIters) ? CONTINUE : STOP;
}

PrerequisiteTests::PrerequisiteTests (Context& context)
	: TestCaseGroup(context, "prerequisite", "Prerequisite Test Cases")
{
}

PrerequisiteTests::~PrerequisiteTests (void)
{
}

void PrerequisiteTests::init (void)
{
	addChild(new StateResetCase(m_context));
	addChild(new ClearColorCase(m_context));
	addChild(new ReadPixelsCase(m_context));
}

} // Functional
} // gles
} // deqp
