/*-------------------------------------------------------------------------
 * 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 "gluES3PlusWrapperContext.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 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)
		return new FboRenderContext(*factory, config, cmdLine);
	else
		return factory->createContext(config, cmdLine);
}

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	},
	};

	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										return DE_NULL;
}

} // glu
