/*-------------------------------------------------------------------------
 * 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 Buffer object wrapper.
 *//*--------------------------------------------------------------------*/

#include "gluObjectWrapper.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deArrayUtil.hpp"

#include <sstream>

namespace glu
{

ObjectWrapper::ObjectWrapper (const glw::Functions& gl, const ObjectTraits& traits)
	: m_gl		(gl)
	, m_traits	(traits)
	, m_object	(0)
{
	(gl.*traits.genFunc)(1, &m_object);

	if (m_object == 0)
	{
		const deUint32		err			= gl.getError();
		const char*			objectName	= traits.name;
		std::ostringstream	msg;

		msg << "Failed to create " << objectName << " object, got " << getErrorStr((int)err);

		if (err == GL_OUT_OF_MEMORY)
			throw OutOfMemoryError(msg.str());
		else
			throw Error((int)err, msg.str());
	}
}

ObjectWrapper::ObjectWrapper (const glw::Functions& gl, const ObjectTraits& traits, deUint32 object)
	: m_gl		(gl)
	, m_traits	(traits)
	, m_object	(object)
{
	DE_ASSERT(object != 0);
}

ObjectWrapper::~ObjectWrapper (void)
{
	(m_gl.*m_traits.deleteFunc)(1, &m_object);
}

static const ObjectTraits s_objectTraits[OBJECTTYPE_LAST] =
{
	{ "texture",			&glw::Functions::genTextures, 			&glw::Functions::deleteTextures				},
	{ "buffer",				&glw::Functions::genBuffers, 			&glw::Functions::deleteBuffers				},
	{ "renderbuffer",		&glw::Functions::genRenderbuffers, 		&glw::Functions::deleteRenderbuffers		},
	{ "framebuffer",		&glw::Functions::genFramebuffers, 		&glw::Functions::deleteFramebuffers			},
	{ "transform feedback",	&glw::Functions::genTransformFeedbacks,	&glw::Functions::deleteTransformFeedbacks	},
	{ "vertex array",		&glw::Functions::genVertexArrays, 		&glw::Functions::deleteVertexArrays			},
	{ "query",				&glw::Functions::genQueries, 			&glw::Functions::deleteQueries				},
	{ "sampler",			&glw::Functions::genSamplers, 			&glw::Functions::deleteSamplers				},
};

const ObjectTraits& objectTraits (ObjectType type)
{
	return de::getSizedArrayElement<OBJECTTYPE_LAST>(s_objectTraits, type);
}

ObjectVector::ObjectVector (const glw::Functions& gl, const ObjectTraits& traits, size_t numObjects)
	: m_gl		(gl)
	, m_traits	(traits)
{
	if (numObjects > 0)
		resize(numObjects);
}

ObjectVector::~ObjectVector (void)
{
	clear();
}

void ObjectVector::resize (size_t newSize)
{
	const size_t oldSize = m_objects.size();

	if (newSize == 0)
	{
		clear(); // Avoid size_t (unsigned) overflow issues in delete path.
	}
	if (oldSize < newSize)
	{
		m_objects.resize(newSize, 0);
		(m_gl.*m_traits.genFunc)(glw::GLsizei(newSize - oldSize), &m_objects[oldSize]);
	}
	else if (oldSize > newSize)
	{
		(m_gl.*m_traits.deleteFunc)(glw::GLsizei(oldSize - newSize), &m_objects[newSize]);
		m_objects.resize(newSize);
	}
}

void ObjectVector::clear (void)
{
	(m_gl.*m_traits.deleteFunc)(glw::GLsizei(m_objects.size()), &m_objects.front());
	m_objects.clear();
}

} // glu
