/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * 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 OpenGL ES rendering context.
 *//*--------------------------------------------------------------------*/

#include "gluRenderContext.hpp"
#include "gluDefs.hpp"
#include "gluRenderConfig.hpp"
#include "gluFboRenderContext.hpp"
#include "gluPlatform.hpp"
#include "gluStrUtil.hpp"
#include "glwInitFunctions.hpp"
#include "glwEnums.hpp"
#include "tcuPlatform.hpp"
#include "tcuCommandLine.hpp"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"

namespace glu
{

// RenderContext

glw::GenericFuncType RenderContext::getProcAddress (const char*) const
{
	return (glw::GenericFuncType)DE_NULL;
}

void RenderContext::makeCurrent (void)
{
	TCU_THROW(InternalError, "RenderContext::makeCurrent() is not implemented");
}

// Utilities

inline bool versionGreaterOrEqual (ApiType a, ApiType b)
{
	return a.getMajorVersion() > b.getMajorVersion() ||
		   (a.getMajorVersion() == b.getMajorVersion() && a.getMinorVersion() >= b.getMinorVersion());
}

bool contextSupports (ContextType ctxType, ApiType requiredApiType)
{
	// \todo [2014-10-06 pyry] Check exact forward-compatible restrictions.
	const bool forwardCompatible = (ctxType.getFlags() & CONTEXT_FORWARD_COMPATIBLE) != 0;

	if (isContextTypeES(ctxType))
	{
		DE_ASSERT(!forwardCompatible);
		return requiredApiType.getProfile() == PROFILE_ES &&
			   versionGreaterOrEqual(ctxType.getAPI(), requiredApiType);
	}
	else if (isContextTypeGLCore(ctxType))
	{
		if (forwardCompatible)
			return ctxType.getAPI() == requiredApiType;
		else
			return requiredApiType.getProfile() == PROFILE_CORE &&
				   versionGreaterOrEqual(ctxType.getAPI(), requiredApiType);
	}
	else if (isContextTypeGLCompatibility(ctxType))
	{
		DE_ASSERT(!forwardCompatible);
		return (requiredApiType.getProfile() == PROFILE_CORE || requiredApiType.getProfile() == PROFILE_COMPATIBILITY) &&
			   versionGreaterOrEqual(ctxType.getAPI(), requiredApiType);
	}
	else
	{
		DE_ASSERT(false);
		return false;
	}
}

static ContextFlags parseContextFlags (const std::string& flagsStr)
{
	const std::vector<std::string>	flagNames	= de::splitString(flagsStr, ',');
	ContextFlags					flags		= ContextFlags(0);
	static const struct
	{
		const char*		name;
		ContextFlags	flag;
	} s_flagMap[] =
	{
		{ "debug",		CONTEXT_DEBUG	},
		{ "robust",		CONTEXT_ROBUST	}
	};

	for (std::vector<std::string>::const_iterator flagIter = flagNames.begin(); flagIter != flagNames.end(); ++flagIter)
	{
		int ndx;
		for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_flagMap); ndx++)
		{
			if (*flagIter == s_flagMap[ndx].name)
			{
				flags = flags | s_flagMap[ndx].flag;
				break;
			}
		}

		if (ndx == DE_LENGTH_OF_ARRAY(s_flagMap))
		{
			tcu::print("ERROR: Unrecognized GL context flag '%s'\n", flagIter->c_str());
			tcu::print("Supported GL context flags:\n");

			for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_flagMap); ndx++)
				tcu::print("  %s\n", s_flagMap[ndx].name);

			throw tcu::NotSupportedError((std::string("Unknown GL context flag '") + *flagIter + "'").c_str(), DE_NULL, __FILE__, __LINE__);
		}
	}

	return flags;
}

RenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext)
{
	const ContextFactoryRegistry&	registry		= platform.getGLPlatform().getContextFactoryRegistry();
	const char*						factoryName		= cmdLine.getGLContextType();
	const ContextFactory*			factory			= DE_NULL;

	if (registry.empty())
		throw tcu::NotSupportedError("OpenGL is not supported", DE_NULL, __FILE__, __LINE__);

	if (factoryName)
	{
		factory = registry.getFactoryByName(factoryName);

		if (!factory)
		{
			tcu::print("ERROR: Unknown or unsupported GL context type '%s'\n", factoryName);
			tcu::print("Supported GL context types:\n");

			for (int factoryNdx = 0; factoryNdx < (int)registry.getFactoryCount(); factoryNdx++)
			{
				const ContextFactory* curFactory = registry.getFactoryByIndex(factoryNdx);
				tcu::print("  %s: %s\n", curFactory->getName(), curFactory->getDescription());
			}

			throw tcu::NotSupportedError((std::string("Unknown GL context type '") + factoryName + "'").c_str(), DE_NULL, __FILE__, __LINE__);
		}
	}
	else
		factory = registry.getDefaultFactory();

	if (cmdLine.getSurfaceType() == tcu::SURFACETYPE_FBO)
	{
		if (sharedContext)
			TCU_FAIL("Shared context not implemented for  FBO surface type");
		return new FboRenderContext(*factory, config, cmdLine);
	}
	else
		return factory->createContext(config, cmdLine, sharedContext);
}

RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType)
{
	RenderConfig	config;
	ContextFlags	ctxFlags	= ContextFlags(0);

	if (cmdLine.getGLContextFlags())
		ctxFlags = parseContextFlags(cmdLine.getGLContextFlags());

	config.type = glu::ContextType(apiType, ctxFlags);
	parseRenderConfig(&config, cmdLine);

	return createRenderContext(platform, cmdLine, config);
}

static std::vector<std::string> getExtensions (const glw::Functions& gl, ApiType apiType)
{
	using std::vector;
	using std::string;

	if (apiType.getProfile() == PROFILE_ES && apiType.getMajorVersion() == 2)
	{
		TCU_CHECK(gl.getString);

		const char*	extStr	= (const char*)gl.getString(GL_EXTENSIONS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetString(GL_EXTENSIONS)");

		if (extStr)
			return de::splitString(extStr);
		else
			throw tcu::TestError("glGetString(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__);
	}
	else
	{
		int				numExtensions	= 0;
		vector<string>	extensions;

		TCU_CHECK(gl.getIntegerv && gl.getStringi);

		gl.getIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_NUM_EXTENSIONS)");

		if (numExtensions > 0)
		{
			extensions.resize(numExtensions);

			for (int ndx = 0; ndx < numExtensions; ndx++)
			{
				const char* const ext = (const char*)gl.getStringi(GL_EXTENSIONS, ndx);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetStringi(GL_EXTENSIONS)");

				if (ext)
					extensions[ndx] = ext;
				else
					throw tcu::TestError("glGetStringi(GL_EXTENSIONS) returned null pointer", DE_NULL, __FILE__, __LINE__);
			}

		}

		return extensions;
	}
}

bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension)
{
	std::vector<std::string> extensions(getExtensions(gl, apiType));

	return de::contains(extensions.begin(), extensions.end(), extension);
}

void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType)
{
	static const struct
	{
		ApiType		apiType;
		void		(*initFunc)		(glw::Functions* gl, const glw::FunctionLoader* loader);
	} s_initFuncs[] =
	{
		{ ApiType::es(2,0),		glw::initES20		},
		{ ApiType::es(3,0),		glw::initES30		},
		{ ApiType::es(3,1),		glw::initES31		},
		{ ApiType::es(3,2),		glw::initES32		},
		{ ApiType::core(3,0),	glw::initGL30Core	},
		{ ApiType::core(3,1),	glw::initGL31Core	},
		{ ApiType::core(3,2),	glw::initGL32Core	},
		{ ApiType::core(3,3),	glw::initGL33Core	},
		{ ApiType::core(4,0),	glw::initGL40Core	},
		{ ApiType::core(4,1),	glw::initGL41Core	},
		{ ApiType::core(4,2),	glw::initGL42Core	},
		{ ApiType::core(4,3),	glw::initGL43Core	},
		{ ApiType::core(4,4),	glw::initGL44Core	},
		{ ApiType::core(4,5),	glw::initGL45Core	},
		{ ApiType::core(4,6),	glw::initGL46Core	},
		// TODO: initialise actual compat functions rather than using core as a dummy
		{ ApiType::compatibility(3,2),	glw::initGL32Core	},
		{ ApiType::compatibility(3,3),	glw::initGL33Core	},
		{ ApiType::compatibility(4,0),	glw::initGL40Core	},
		{ ApiType::compatibility(4,1),	glw::initGL41Core	},
		{ ApiType::compatibility(4,2),	glw::initGL42Core	},
		{ ApiType::compatibility(4,3),	glw::initGL43Core	},
		{ ApiType::compatibility(4,4),	glw::initGL44Core	},
		{ ApiType::compatibility(4,5),	glw::initGL45Core	},
		{ ApiType::compatibility(4,6),	glw::initGL46Core	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_initFuncs); ndx++)
	{
		if (s_initFuncs[ndx].apiType == apiType)
		{
			s_initFuncs[ndx].initFunc(dst, loader);
			return;
		}
	}

	throw tcu::InternalError(std::string("Don't know how to load functions for ") + de::toString(apiType));
}

void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType)
{
	std::vector<std::string> extensions = getExtensions(*dst, apiType);

	if (!extensions.empty())
	{
		std::vector<const char*> extStr(extensions.size());

		for (size_t ndx = 0; ndx < extensions.size(); ndx++)
			extStr[ndx] = extensions[ndx].c_str();

		initExtensionFunctions(dst, loader, apiType, (int)extStr.size(), &extStr[0]);
	}
}

void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions)
{
	if (apiType.getProfile() == PROFILE_ES)
		glw::initExtensionsES(dst, loader, numExtensions, extensions);
	else
		glw::initExtensionsGL(dst, loader, numExtensions, extensions);
}

void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType)
{
	initCoreFunctions(dst, loader, apiType);
	initExtensionFunctions(dst, loader, apiType);
}

const char* getApiTypeDescription (ApiType type)
{
	if (type == glu::ApiType::es(2, 0))			return "OpenGL ES 2";
	else if (type == glu::ApiType::es(3, 0))	return "OpenGL ES 3";
	else if (type == glu::ApiType::es(3, 1))	return "OpenGL ES 3.1";
	else if (type == glu::ApiType::es(3, 2))	return "OpenGL ES 3.2";
	else if (type == glu::ApiType::core(3, 0))	return "OpenGL 3.0 core";
	else if (type == glu::ApiType::core(3, 1))	return "OpenGL 3.1 core";
	else if (type == glu::ApiType::core(3, 2))	return "OpenGL 3.2 core";
	else if (type == glu::ApiType::core(3, 3))	return "OpenGL 3.3 core";
	else if (type == glu::ApiType::core(4, 0))	return "OpenGL 4.0 core";
	else if (type == glu::ApiType::core(4, 1))	return "OpenGL 4.1 core";
	else if (type == glu::ApiType::core(4, 2))	return "OpenGL 4.2 core";
	else if (type == glu::ApiType::core(4, 3))	return "OpenGL 4.3 core";
	else if (type == glu::ApiType::core(4, 4))	return "OpenGL 4.4 core";
	else if (type == glu::ApiType::core(4, 5))	return "OpenGL 4.5 core";
	else if (type == glu::ApiType::core(4, 6))	return "OpenGL 4.6 core";
	else if (type == glu::ApiType::compatibility(3, 2))	return "OpenGL 3.2 compatibility";
	else if (type == glu::ApiType::compatibility(3, 3))	return "OpenGL 3.3 compatibility";
	else if (type == glu::ApiType::compatibility(4, 0))	return "OpenGL 4.0 compatibility";
	else if (type == glu::ApiType::compatibility(4, 1))	return "OpenGL 4.1 compatibility";
	else if (type == glu::ApiType::compatibility(4, 2))	return "OpenGL 4.2 compatibility";
	else if (type == glu::ApiType::compatibility(4, 3))	return "OpenGL 4.3 compatibility";
	else if (type == glu::ApiType::compatibility(4, 4))	return "OpenGL 4.4 compatibility";
	else if (type == glu::ApiType::compatibility(4, 5))	return "OpenGL 4.5 compatibility";
	else if (type == glu::ApiType::compatibility(4, 6))	return "OpenGL 4.6 compatibility";
	else										return DE_NULL;
}

} // glu
