#ifndef _GLUCONTEXTINFO_HPP
#define _GLUCONTEXTINFO_HPP
/*-------------------------------------------------------------------------
 * 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 Context Info Class.
 *//*--------------------------------------------------------------------*/

#include "gluDefs.hpp"

#include <vector>
#include <string>
#include <set>

namespace glu
{

class RenderContext;

template <typename T, class ComputeValue>
class CachedValue
{
public:
	CachedValue (ComputeValue compute = ComputeValue(), const T& defaultValue = T())
		: m_compute		(compute)
		, m_value		(defaultValue)
		, m_isComputed	(false)
	{
	}

	const T& getValue (const RenderContext& context) const
	{
		if (!m_isComputed)
		{
			m_value			= m_compute(context);
			m_isComputed	= true;
		}
		return m_value;
	}

private:
	ComputeValue	m_compute;
	mutable T		m_value;
	mutable bool	m_isComputed;
};

class GetExtensions
{
public:
	std::vector<std::string> operator() (const RenderContext& context) const;
};

class GetCompressedTextureFormats
{
public:
	std::set<int> operator() (const RenderContext& context) const;
};

typedef CachedValue<std::vector<std::string>, GetExtensions>	ExtensionList;
typedef CachedValue<std::set<int>, GetCompressedTextureFormats>	CompressedTextureFormats;

/*--------------------------------------------------------------------*//*!
 * \brief Context information & limit query.
 *//*--------------------------------------------------------------------*/
class ContextInfo
{
public:
	virtual										~ContextInfo						(void);

	virtual int									getInt								(int param) const;
	virtual bool								getBool								(int param) const;
	virtual const char*							getString							(int param) const;

	virtual bool								isVertexUniformLoopSupported		(void) const { return true; }
	virtual bool								isVertexDynamicLoopSupported		(void) const { return true; }
	virtual bool								isFragmentHighPrecisionSupported	(void) const { return true; }
	virtual bool								isFragmentUniformLoopSupported		(void) const { return true; }
	virtual bool								isFragmentDynamicLoopSupported		(void) const { return true; }

	virtual bool								isCompressedTextureFormatSupported	(int format) const;

	const std::vector<std::string>&				getExtensions						(void) const { return m_extensions.getValue(m_context); }
	bool										isExtensionSupported				(const char* extName) const;

	static ContextInfo*							create								(const RenderContext& context);

protected:
												ContextInfo							(const RenderContext& context);

	const RenderContext&						m_context;

private:
												ContextInfo							(const ContextInfo& other);
	ContextInfo&								operator=							(const ContextInfo& other);

	ExtensionList								m_extensions;
	CompressedTextureFormats					m_compressedTextureFormats;
};

} // glu

#endif // _GLUCONTEXTINFO_HPP