/*-------------------------------------------------------------------------
 * 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 3plus wrapper context.
 *//*--------------------------------------------------------------------*/

#include "gluES3PlusWrapperContext.hpp"
#include "gluRenderContext.hpp"
#include "gluRenderConfig.hpp"
#include "glwInitFunctions.hpp"
#include "glwFunctionLoader.hpp"
#include "gluContextFactory.hpp"
#include "gluContextInfo.hpp"
#include "gluShaderUtil.hpp"
#include "deThreadLocal.hpp"
#include "deSTLUtil.hpp"
#include "deUniquePtr.hpp"
#include "glwEnums.hpp"

#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>

namespace glu
{

namespace es3plus
{

using std::vector;
using std::string;

class Context
{
public:
								Context			(const glu::RenderContext& ctx);
								~Context		(void);

	void						addExtension	(const char* name);

	const glw::Functions&		gl;			//!< GL 4.3 core context functions.

	// Wrapper state.
	string						vendor;
	string						version;
	string						renderer;
	string						shadingLanguageVersion;
	string						extensions;
	vector<string>				extensionList;
	bool						primitiveRestartEnabled;

	deUint32					defaultVAO;
	bool						defaultVAOBound;

	const glu::GLSLVersion		nativeGLSLVersion;
};

Context::Context (const glu::RenderContext& ctx)
	: gl						(ctx.getFunctions())
	, vendor					("drawElements")
	, version					("OpenGL ES 3.2")
	, renderer					((const char*)gl.getString(GL_RENDERER))
	, shadingLanguageVersion	("OpenGL ES GLSL ES 3.2")
	, primitiveRestartEnabled	(false)
	, defaultVAO				(0)
	, defaultVAOBound			(false)
	, nativeGLSLVersion			(glu::getContextTypeGLSLVersion(ctx.getType()))
{
	const de::UniquePtr<glu::ContextInfo> ctxInfo(glu::ContextInfo::create(ctx));

	gl.genVertexArrays(1, &defaultVAO);
	if (gl.getError() != GL_NO_ERROR || defaultVAO == 0)
		throw tcu::InternalError("Failed to allocate VAO for emulation");

	gl.bindVertexArray(defaultVAO);
	if (gl.getError() != GL_NO_ERROR)
		throw tcu::InternalError("Failed to bind default VAO");
	defaultVAOBound = true;

	gl.enable(GL_PROGRAM_POINT_SIZE);
	gl.getError(); // supress potential errors, feature is not critical

	gl.enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
	gl.getError(); // suppress

	// Extensions
	addExtension("GL_OES_texture_stencil8");
	addExtension("GL_OES_sample_shading");
	addExtension("GL_OES_sample_variables");
	addExtension("GL_OES_shader_multisample_interpolation");
	addExtension("GL_OES_shader_image_atomic");
	addExtension("GL_OES_texture_storage_multisample_2d_array");

	// Enable only if base ctx supports these or compatible GL_NV_blend_equation_advanced ext
	if (ctxInfo->isExtensionSupported("GL_NV_blend_equation_advanced") ||
		ctxInfo->isExtensionSupported("GL_KHR_blend_equation_advanced"))
	{
		addExtension("GL_KHR_blend_equation_advanced");
	}
	if (ctxInfo->isExtensionSupported("GL_NV_blend_equation_advanced_coherent") ||
		ctxInfo->isExtensionSupported("GL_KHR_blend_equation_advanced_coherent"))
	{
		addExtension("GL_KHR_blend_equation_advanced_coherent");
	}

	addExtension("GL_EXT_shader_io_blocks");
	addExtension("GL_EXT_geometry_shader");
	addExtension("GL_EXT_geometry_point_size");
	addExtension("GL_EXT_tessellation_shader");
	addExtension("GL_EXT_tessellation_point_size");
	addExtension("GL_EXT_gpu_shader5");
	addExtension("GL_KHR_debug");
	addExtension("GL_EXT_texture_cube_map_array");
	addExtension("GL_EXT_shader_implicit_conversions");
	addExtension("GL_EXT_primitive_bounding_box");
	addExtension("GL_EXT_texture_sRGB_decode");
	addExtension("GL_EXT_texture_border_clamp");
	addExtension("GL_EXT_texture_buffer");
	addExtension("GL_EXT_draw_buffers_indexed");
}

Context::~Context (void)
{
	if (defaultVAO)
		gl.deleteVertexArrays(1, &defaultVAO);
}

void Context::addExtension (const char* name)
{
	if (!extensions.empty())
		extensions += " ";
	extensions += name;

	extensionList.push_back(name);
}

static de::ThreadLocal tls_context;

void setCurrentContext (Context* context)
{
	tls_context.set(context);
}

inline Context* getCurrentContext (void)
{
	return (Context*)tls_context.get();
}

static GLW_APICALL void GLW_APIENTRY getIntegerv (deUint32 pname, deInt32* params)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (pname == GL_NUM_EXTENSIONS && params)
			*params = (deInt32)context->extensionList.size();
		else
			context->gl.getIntegerv(pname, params);
	}
}

static GLW_APICALL const glw::GLubyte* GLW_APIENTRY getString (deUint32 name)
{
	Context* context = getCurrentContext();

	if (context)
	{
		switch (name)
		{
			case GL_VENDOR:						return (const glw::GLubyte*)context->vendor.c_str();
			case GL_VERSION:					return (const glw::GLubyte*)context->version.c_str();
			case GL_RENDERER:					return (const glw::GLubyte*)context->renderer.c_str();
			case GL_SHADING_LANGUAGE_VERSION:	return (const glw::GLubyte*)context->shadingLanguageVersion.c_str();
			case GL_EXTENSIONS:					return (const glw::GLubyte*)context->extensions.c_str();
			default:							return context->gl.getString(name);
		}
	}
	else
		return DE_NULL;
}

static GLW_APICALL const glw::GLubyte* GLW_APIENTRY getStringi (deUint32 name, deUint32 index)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (name == GL_EXTENSIONS)
		{
			if ((size_t)index < context->extensionList.size())
				return (const glw::GLubyte*)context->extensionList[index].c_str();
			else
				return context->gl.getStringi(name, ~0u);
		}
		else
			return context->gl.getStringi(name, index);
	}
	else
		return DE_NULL;
}

static GLW_APICALL void GLW_APIENTRY enable (deUint32 cap)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX)
		{
			context->primitiveRestartEnabled = true;
			// \todo [2013-09-30 pyry] Call to glPrimitiveRestartIndex() is required prior to all draw calls!
		}
		else
			context->gl.enable(cap);
	}
}

static GLW_APICALL void GLW_APIENTRY disable (deUint32 cap)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX)
			context->primitiveRestartEnabled = false;
		else
			context->gl.disable(cap);
	}
}

static GLW_APICALL void GLW_APIENTRY bindVertexArray (deUint32 array)
{
	Context* context = getCurrentContext();

	if (context)
	{
		context->gl.bindVertexArray(array == 0 ? context->defaultVAO : array);
		context->defaultVAOBound = (array == 0);
	}
}

static GLW_APICALL void GLW_APIENTRY hint (deUint32 target, deUint32 mode)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (target != GL_GENERATE_MIPMAP_HINT)
			context->gl.hint(target, mode);
		// \todo [2013-09-30 pyry] Verify mode.
	}
}

static void translateShaderSource (deUint32 shaderType, std::ostream& dst, const std::string& src, const std::vector<std::string>& filteredExtensions, GLSLVersion version)
{
	bool				foundVersion		= false;
	std::istringstream	istr				(src);
	std::string			line;
	int					srcLineNdx			= 1;
	bool				preprocessorSection	= true;

	while (std::getline(istr, line, '\n'))
	{
		if (preprocessorSection && !line.empty() && line[0] != '#')
		{
			preprocessorSection = false;

			// ARB_separate_shader_objects requires gl_PerVertex to be explicitly declared
			if (shaderType == GL_VERTEX_SHADER)
			{
				dst << "out gl_PerVertex {\n"
					<< "    vec4 gl_Position;\n"
					<< "    float gl_PointSize;\n"
					<< "    float gl_ClipDistance[];\n"
					<< "};\n"
					<< "#line " << (srcLineNdx + 1) << "\n";
			}
			else if (shaderType == GL_TESS_CONTROL_SHADER)
			{
				dst << "#extension GL_ARB_tessellation_shader : enable\n"
					<< "in gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "} gl_in[gl_MaxPatchVertices];\n"
					<< "out gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "} gl_out[];\n"
					<< "#line " << (srcLineNdx + 1) << "\n";
			}
			else if (shaderType == GL_TESS_EVALUATION_SHADER)
			{
				dst << "#extension GL_ARB_tessellation_shader : enable\n"
					<< "in gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "} gl_in[gl_MaxPatchVertices];\n"
					<< "out gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "};\n"
					<< "#line " << (srcLineNdx + 1) << "\n";
			}
			else if (shaderType == GL_GEOMETRY_SHADER)
			{
				dst << "in gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "} gl_in[];\n"
					<< "out gl_PerVertex {\n"
					<< "	highp vec4 gl_Position;\n"
					<< "	highp float gl_PointSize;\n"
					<< "};\n"
					<< "#line " << (srcLineNdx + 1) << "\n";
			}

			// GL_EXT_primitive_bounding_box tessellation no-op fallback
			if (shaderType == GL_TESS_CONTROL_SHADER)
			{
				dst << "#define gl_BoundingBoxEXT _dummy_unused_output_for_primitive_bbox\n"
					<< "patch out vec4 _dummy_unused_output_for_primitive_bbox[2];\n"
					<< "#line " << (srcLineNdx + 1) << "\n";
			}
		}

		if (line == "#version 310 es" || line == "#version 320 es")
		{
			foundVersion = true;
			dst << glu::getGLSLVersionDeclaration(version) << "\n";
		}
		else if (line == "#version 300 es")
		{
			foundVersion = true;
			dst << "#version 330\n";
		}
		else if (line.substr(0, 10) == "precision ")
		{
			const size_t	precPos		= 10;
			const size_t	precEndPos	= line.find(' ', precPos);
			const size_t	endPos		= line.find(';');

			if (precEndPos != std::string::npos && endPos != std::string::npos && endPos > precEndPos+1)
			{
				const size_t		typePos		= precEndPos+1;
				const std::string	precision	= line.substr(precPos, precEndPos-precPos);
				const std::string	type		= line.substr(typePos, endPos-typePos);
				const bool			precOk		= precision == "lowp" || precision == "mediump" || precision == "highp";

				if (precOk &&
					(type == "image2D" || type == "uimage2D" || type == "iimage2D" ||
					 type == "imageCube" || type == "uimageCube" || type == "iimageCube" ||
					 type == "image3D" || type == "iimage3D" || type == "uimage3D" ||
					 type == "image2DArray" || type == "iimage2DArray" || type == "uimage2DArray" ||
					 type == "imageCubeArray" || type == "iimageCubeArray" || type == "uimageCubeArray"))
					dst << "// "; // Filter out statement
			}

			dst << line << "\n";
		}
		else if (line.substr(0, 11) == "#extension ")
		{
			const size_t	extNamePos		= 11;
			const size_t	extNameEndPos	= line.find_first_of(" :", extNamePos);
			const size_t	behaviorPos		= line.find_first_not_of(" :", extNameEndPos);

			if (extNameEndPos != std::string::npos && behaviorPos != std::string::npos)
			{
				const std::string	extName				= line.substr(extNamePos, extNameEndPos-extNamePos);
				const std::string	behavior			= line.substr(behaviorPos);
				const bool			filteredExtension	= de::contains(filteredExtensions.begin(), filteredExtensions.end(), extName);
				const bool			validBehavior		= behavior == "require" || behavior == "enable" || behavior == "warn" || behavior == "disable";

				if (filteredExtension && validBehavior)
					dst << "// "; // Filter out extension
			}
			dst << line << "\n";
		}
		else if (line.substr(0, 21) == "layout(blend_support_")
			dst << "// " << line << "\n";
		else
			dst << line << "\n";

		srcLineNdx += 1;
	}

	DE_ASSERT(foundVersion);
	DE_UNREF(foundVersion);
}

static std::string translateShaderSources (deUint32 shaderType, deInt32 count, const char* const* strings, const int* length, const std::vector<std::string>& filteredExtensions, GLSLVersion version)
{
	std::ostringstream	srcIn;
	std::ostringstream	srcOut;

	for (int ndx = 0; ndx < count; ndx++)
	{
		const int len = length && length[ndx] >= 0 ? length[ndx] : (int)strlen(strings[ndx]);
		srcIn << std::string(strings[ndx], strings[ndx] + len);
	}

	translateShaderSource(shaderType, srcOut, srcIn.str(), filteredExtensions, version);

	return srcOut.str();
}

static GLW_APICALL void GLW_APIENTRY shaderSource (deUint32 shader, deInt32 count, const char* const* strings, const int* length)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (count > 0 && strings)
		{
			deInt32				shaderType = GL_NONE;
			context->gl.getShaderiv(shader, GL_SHADER_TYPE, &shaderType);
			{
				const std::string	translatedSrc	= translateShaderSources(shaderType, count, strings, length, context->extensionList, context->nativeGLSLVersion);
				const char*			srcPtr			= translatedSrc.c_str();
				context->gl.shaderSource(shader, 1, &srcPtr, DE_NULL);
			}
		}
		else
			context->gl.shaderSource(shader, count, strings, length);
	}
}

static GLW_APICALL void GLW_APIENTRY bindFramebuffer (deUint32 target, deUint32 framebuffer)
{
	Context* context = getCurrentContext();

	if (context)
	{
		context->gl.bindFramebuffer(target, framebuffer);

		// Emulate ES behavior where sRGB conversion is only controlled by color buffer format.
		if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER)
			((framebuffer != 0) ? context->gl.enable : context->gl.disable)(GL_FRAMEBUFFER_SRGB);
	}
}

static GLW_APICALL void GLW_APIENTRY blendBarrierKHR (void)
{
	Context* context = getCurrentContext();

	if (context)
	{
		// \todo [2014-03-18 pyry] Use BlendBarrierNV() if supported
		context->gl.finish();
	}
}

static GLW_APICALL deUint32 GLW_APIENTRY createShaderProgramv (deUint32 type, deInt32 count, const char* const* strings)
{
	Context* context = getCurrentContext();

	if (context)
	{
		if (count > 0 && strings)
		{
			const std::string	translatedSrc	= translateShaderSources(type, count, strings, DE_NULL, context->extensionList, context->nativeGLSLVersion);
			const char*			srcPtr			= translatedSrc.c_str();
			return context->gl.createShaderProgramv(type, 1, &srcPtr);
		}
		else
			return context->gl.createShaderProgramv(type, count, strings);
	}
	return 0;
}

static GLW_APICALL void GLW_APIENTRY dummyPrimitiveBoundingBox (float minX, float minY, float minZ, float minW, float maxX, float maxY, float maxZ, float maxW)
{
	// dummy no-op. No-op is a valid implementation. States queries are not emulated.
	DE_UNREF(minX);
	DE_UNREF(minY);
	DE_UNREF(minZ);
	DE_UNREF(minW);
	DE_UNREF(maxX);
	DE_UNREF(maxY);
	DE_UNREF(maxZ);
	DE_UNREF(maxW);
}

static void initFunctions (glw::Functions* dst, const glw::Functions& src)
{
	// Functions directly passed to GL context.
#include "gluES3PlusWrapperFuncs.inl"

	// Wrapped functions.
	dst->bindVertexArray		= bindVertexArray;
	dst->disable				= disable;
	dst->enable					= enable;
	dst->getIntegerv			= getIntegerv;
	dst->getString				= getString;
	dst->getStringi				= getStringi;
	dst->hint					= hint;
	dst->shaderSource			= shaderSource;
	dst->createShaderProgramv	= createShaderProgramv;
	dst->bindFramebuffer		= bindFramebuffer;

	// Extension functions
	{
		using std::map;

		class ExtFuncLoader : public glw::FunctionLoader
		{
		public:
			ExtFuncLoader (const map<string, glw::GenericFuncType>& extFuncs)
				: m_extFuncs(extFuncs)
			{
			}

			glw::GenericFuncType get (const char* name) const
			{
				map<string, glw::GenericFuncType>::const_iterator pos = m_extFuncs.find(name);
				return pos != m_extFuncs.end() ? pos->second : DE_NULL;
			}

		private:
			const map<string, glw::GenericFuncType>& m_extFuncs;
		};

		map<string, glw::GenericFuncType>	extFuncMap;
		const ExtFuncLoader					extFuncLoader	(extFuncMap);

		// OES_sample_shading
		extFuncMap["glMinSampleShadingOES"]			= (glw::GenericFuncType)src.minSampleShading;

		// OES_texture_storage_multisample_2d_array
		extFuncMap["glTexStorage3DMultisampleOES"]	= (glw::GenericFuncType)src.texStorage3DMultisample;

		// KHR_blend_equation_advanced
		extFuncMap["glBlendBarrierKHR"]				= (glw::GenericFuncType)blendBarrierKHR;

		// EXT_tessellation_shader
		extFuncMap["glPatchParameteriEXT"]			= (glw::GenericFuncType)src.patchParameteri;

		// EXT_geometry_shader
		extFuncMap["glFramebufferTextureEXT"]		= (glw::GenericFuncType)src.framebufferTexture;

		// KHR_debug
		extFuncMap["glDebugMessageControlKHR"]		= (glw::GenericFuncType)src.debugMessageControl;
		extFuncMap["glDebugMessageInsertKHR"]		= (glw::GenericFuncType)src.debugMessageInsert;
		extFuncMap["glDebugMessageCallbackKHR"]		= (glw::GenericFuncType)src.debugMessageCallback;
		extFuncMap["glGetDebugMessageLogKHR"]		= (glw::GenericFuncType)src.getDebugMessageLog;
		extFuncMap["glGetPointervKHR"]				= (glw::GenericFuncType)src.getPointerv;
		extFuncMap["glPushDebugGroupKHR"]			= (glw::GenericFuncType)src.pushDebugGroup;
		extFuncMap["glPopDebugGroupKHR"]			= (glw::GenericFuncType)src.popDebugGroup;
		extFuncMap["glObjectLabelKHR"]				= (glw::GenericFuncType)src.objectLabel;
		extFuncMap["glGetObjectLabelKHR"]			= (glw::GenericFuncType)src.getObjectLabel;
		extFuncMap["glObjectPtrLabelKHR"]			= (glw::GenericFuncType)src.objectPtrLabel;
		extFuncMap["glGetObjectPtrLabelKHR"]		= (glw::GenericFuncType)src.getObjectPtrLabel;

		// GL_EXT_primitive_bounding_box (dummy no-op)
		extFuncMap["glPrimitiveBoundingBoxEXT"]		= (glw::GenericFuncType)dummyPrimitiveBoundingBox;

		// GL_EXT_texture_border_clamp
		extFuncMap["glTexParameterIivEXT"]			= (glw::GenericFuncType)src.texParameterIiv;
		extFuncMap["glTexParameterIuivEXT"]			= (glw::GenericFuncType)src.texParameterIuiv;
		extFuncMap["glGetTexParameterIivEXT"]		= (glw::GenericFuncType)src.getTexParameterIiv;
		extFuncMap["glGetTexParameterIuivEXT"]		= (glw::GenericFuncType)src.getTexParameterIuiv;
		extFuncMap["glSamplerParameterIivEXT"]		= (glw::GenericFuncType)src.samplerParameterIiv;
		extFuncMap["glSamplerParameterIuivEXT"]		= (glw::GenericFuncType)src.samplerParameterIuiv;
		extFuncMap["glGetSamplerParameterIivEXT"]	= (glw::GenericFuncType)src.getSamplerParameterIiv;
		extFuncMap["glGetSamplerParameterIuivEXT"]	= (glw::GenericFuncType)src.getSamplerParameterIuiv;

		// GL_EXT_texture_buffer
		extFuncMap["glTexBufferEXT"]				= (glw::GenericFuncType)src.texBuffer;
		extFuncMap["glTexBufferRangeEXT"]			= (glw::GenericFuncType)src.texBufferRange;

		// GL_EXT_draw_buffers_indexed
		extFuncMap["glEnableiEXT"]					= (glw::GenericFuncType)src.enablei;
		extFuncMap["glDisableiEXT"]					= (glw::GenericFuncType)src.disablei;
		extFuncMap["glBlendEquationiEXT"]			= (glw::GenericFuncType)src.blendEquationi;
		extFuncMap["glBlendEquationSeparateiEXT"]	= (glw::GenericFuncType)src.blendEquationSeparatei;
		extFuncMap["glBlendFunciEXT"]				= (glw::GenericFuncType)src.blendFunci;
		extFuncMap["glBlendFuncSeparateiEXT"]		= (glw::GenericFuncType)src.blendFuncSeparatei;
		extFuncMap["glColorMaskiEXT"]				= (glw::GenericFuncType)src.colorMaski;
		extFuncMap["glIsEnablediEXT"]				= (glw::GenericFuncType)src.isEnabledi;

		{
			int	numExts	= 0;
			dst->getIntegerv(GL_NUM_EXTENSIONS, &numExts);

			if (numExts > 0)
			{
				vector<const char*> extStr(numExts);

				for (int ndx = 0; ndx < numExts; ndx++)
					extStr[ndx] = (const char*)dst->getStringi(GL_EXTENSIONS, ndx);

				glw::initExtensionsES(dst, &extFuncLoader, (int)extStr.size(), &extStr[0]);
			}
		}
	}
}

} // es3plus

ES3PlusWrapperContext::ES3PlusWrapperContext (const ContextFactory& factory, const RenderConfig& config, const tcu::CommandLine& cmdLine)
	: m_context		(DE_NULL)
	, m_wrapperCtx	(DE_NULL)
{
	// Flags that are valid for both core & es context. Currently only excludes CONTEXT_FORWARD_COMPATIBLE
	const ContextFlags validContextFlags = CONTEXT_ROBUST | CONTEXT_DEBUG;

	static const ContextType wrappableNativeTypes[] =
	{
		ContextType(ApiType::core(4,4), config.type.getFlags() & validContextFlags),	// !< higher in the list, preferred
		ContextType(ApiType::core(4,3), config.type.getFlags() & validContextFlags),
	};

	if (config.type.getAPI() != ApiType::es(3,2))
		throw tcu::NotSupportedError("Unsupported context type (ES3.2 wrapper supports only ES3.2)");

	// try to create any wrappable context

	for (int nativeCtxNdx = 0; nativeCtxNdx < DE_LENGTH_OF_ARRAY(wrappableNativeTypes); ++nativeCtxNdx)
	{
		glu::ContextType nativeContext = wrappableNativeTypes[nativeCtxNdx];

		try
		{
			glu::RenderConfig nativeConfig = config;
			nativeConfig.type = nativeContext;

			m_context		= factory.createContext(nativeConfig, cmdLine);
			m_wrapperCtx	= new es3plus::Context(*m_context);

			es3plus::setCurrentContext(m_wrapperCtx);
			es3plus::initFunctions(&m_functions, m_context->getFunctions());
			break;
		}
		catch (...)
		{
			es3plus::setCurrentContext(DE_NULL);

			delete m_wrapperCtx;
			delete m_context;

			m_wrapperCtx = DE_NULL;
			m_context = DE_NULL;

			// throw only if all tries failed (that is, this was the last potential target)
			if (nativeCtxNdx + 1 == DE_LENGTH_OF_ARRAY(wrappableNativeTypes))
				throw;
			else
				continue;
		}
	}
}

ES3PlusWrapperContext::~ES3PlusWrapperContext (void)
{
	delete m_wrapperCtx;
	delete m_context;
}

ContextType ES3PlusWrapperContext::getType (void) const
{
	return ContextType(ApiType::es(3,2), m_context->getType().getFlags());
}

} // glu
