/*-------------------------------------------------------------------------
 * 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 rendering configuration.
 *//*--------------------------------------------------------------------*/

#include "gluRenderConfig.hpp"
#include "tcuCommandLine.hpp"
#include "deString.h"

namespace glu
{

void parseConfigBitsFromName (RenderConfig* config, const char* renderCfgName)
{
	const char*	cfgName	= renderCfgName;

	DE_ASSERT(config->redBits		== RenderConfig::DONT_CARE	&&
			  config->greenBits		== RenderConfig::DONT_CARE	&&
			  config->blueBits		== RenderConfig::DONT_CARE	&&
			  config->alphaBits		== RenderConfig::DONT_CARE	&&
			  config->depthBits		== RenderConfig::DONT_CARE	&&
			  config->stencilBits	== RenderConfig::DONT_CARE	&&
			  config->numSamples	== RenderConfig::DONT_CARE);

	static const struct
	{
		const char*	name;
		int			redBits;
		int			greenBits;
		int			blueBits;
		int			alphaBits;
	} colorCfgs[] =
	{
		{ "rgb888",		8, 8, 8, 0 },
		{ "rgba8888",	8, 8, 8, 8 },
		{ "rgb565",		5, 6, 5, 0 },
		{ "rgba4444",	4, 4, 4, 4 },
		{ "rgba5551",	5, 5, 5, 1 }
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorCfgs); ndx++)
	{
		if (deStringBeginsWith(cfgName, colorCfgs[ndx].name))
		{
			config->redBits		= colorCfgs[ndx].redBits;
			config->greenBits	= colorCfgs[ndx].greenBits;
			config->blueBits	= colorCfgs[ndx].blueBits;
			config->alphaBits	= colorCfgs[ndx].alphaBits;

			cfgName	+= strlen(colorCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char*	name;
		int			depthSize;
	} depthCfgs[] =
	{
		{ "d0",		0 },
		{ "d16",	16 },
		{ "d24",	24 },
		{ "d32",	32 }
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthCfgs); ndx++)
	{
		if (deStringBeginsWith(cfgName, depthCfgs[ndx].name))
		{
			config->depthBits = depthCfgs[ndx].depthSize;

			cfgName += strlen(depthCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char*	name;
		int			stencilSize;
	} stencilCfgs[] =
	{
		{ "s0",		 0 },
		{ "s8",		 8 },
		{ "s16",	16 },
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilCfgs); ndx++)
	{
		if (deStringBeginsWith(cfgName, stencilCfgs[ndx].name))
		{
			config->stencilBits = stencilCfgs[ndx].stencilSize;

			cfgName += strlen(stencilCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char*	name;
		int			numSamples;
	} multiSampleCfgs[] =
	{
		{ "ms0",	 0 },
		{ "ms16",	16 },
		{ "ms1",	 1 },
		{ "ms2",	 2 },
		{ "ms4",	 4 },
		{ "ms8",	 8 }
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(multiSampleCfgs); ndx++)
	{
		if (deStringBeginsWith(cfgName, multiSampleCfgs[ndx].name))
		{
			config->numSamples = multiSampleCfgs[ndx].numSamples;

			cfgName += strlen(multiSampleCfgs[ndx].name);
			break;
		}
	}

	if (cfgName[0] != 0)
		throw tcu::InternalError(std::string("Invalid GL configuration: '") + renderCfgName + "'");
}

void parseRenderConfig (RenderConfig* config, const tcu::CommandLine& cmdLine)
{
	switch (cmdLine.getSurfaceType())
	{
		case tcu::SURFACETYPE_WINDOW:				config->surfaceType		= RenderConfig::SURFACETYPE_WINDOW;				break;
		case tcu::SURFACETYPE_OFFSCREEN_NATIVE:		config->surfaceType		= RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;	break;
		case tcu::SURFACETYPE_OFFSCREEN_GENERIC:	config->surfaceType		= RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC;	break;
		case tcu::SURFACETYPE_FBO:					config->surfaceType		= RenderConfig::SURFACETYPE_DONT_CARE;			break;
		case tcu::SURFACETYPE_LAST:					config->surfaceType		= RenderConfig::SURFACETYPE_DONT_CARE;			break;
		default:
			throw tcu::InternalError("Unsupported surface type");
	}

	config->windowVisibility = parseWindowVisibility(cmdLine);

	if (cmdLine.getSurfaceWidth() > 0)
		config->width = cmdLine.getSurfaceWidth();

	if (cmdLine.getSurfaceHeight() > 0)
		config->height = cmdLine.getSurfaceHeight();

	if (cmdLine.getGLConfigName() != DE_NULL)
		parseConfigBitsFromName(config, cmdLine.getGLConfigName());

	if (cmdLine.getGLConfigId() >= 0)
		config->id = cmdLine.getGLConfigId();
}

RenderConfig::Visibility parseWindowVisibility (const tcu::CommandLine& cmdLine)
{
	switch (cmdLine.getVisibility())
	{
		case tcu::WINDOWVISIBILITY_HIDDEN:		return RenderConfig::VISIBILITY_HIDDEN;
		case tcu::WINDOWVISIBILITY_WINDOWED:	return RenderConfig::VISIBILITY_VISIBLE;
		case tcu::WINDOWVISIBILITY_FULLSCREEN:	return RenderConfig::VISIBILITY_FULLSCREEN;
		default:
			throw tcu::InternalError("Unsupported window visibility");
	}
}

} // glu
