/*-------------------------------------------------------------------------
 * 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
