/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL 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 EGL API Library.
 *//*--------------------------------------------------------------------*/

#include "eglwLibrary.hpp"
#include "tcuFunctionLibrary.hpp"
#include "deDynamicLibrary.hpp"

#if !defined(DEQP_EGL_RUNTIME_LOAD)
#	include <EGL/egl.h>
#endif

namespace eglw
{

FuncPtrLibrary::FuncPtrLibrary (void)
{
}

FuncPtrLibrary::~FuncPtrLibrary (void)
{
}

#include "eglwFuncPtrLibraryImpl.inl"

namespace
{

tcu::FunctionLibrary* createStaticLibrary (void)
{
#if !defined(DEQP_EGL_RUNTIME_LOAD)
	static tcu::StaticFunctionLibrary::Entry s_staticEntries[] =
	{
#	if defined(EGL_VERSION_1_5)
#		include "eglwStaticLibrary15.inl"
#	elif defined(EGL_VERSION_1_4)
#		include "eglwStaticLibrary14.inl"
#	endif
	};
	return new tcu::StaticFunctionLibrary(s_staticEntries, DE_LENGTH_OF_ARRAY(s_staticEntries));
#else
	return new tcu::StaticFunctionLibrary(DE_NULL, 0);
#endif
}

class CoreLoader : public FunctionLoader
{
public:
	CoreLoader (const de::DynamicLibrary* dynLib)
		: m_staticLib		(createStaticLibrary())
		, m_dynLib			(dynLib)
		, m_getProcAddress	(DE_NULL)
	{
		// Try to obtain eglGetProcAddress
		m_getProcAddress = (eglGetProcAddressFunc)m_staticLib->getFunction("eglGetProcAddress");

		if (!m_getProcAddress && m_dynLib)
			m_getProcAddress = (eglGetProcAddressFunc)m_dynLib->getFunction("eglGetProcAddress");
	}

	~CoreLoader (void)
	{
		delete m_staticLib;
	}

	GenericFuncType get (const char* name) const
	{
		GenericFuncType res = (GenericFuncType)DE_NULL;

		res = (GenericFuncType)m_staticLib->getFunction(name);

		if (!res && m_dynLib)
			res = (GenericFuncType)m_dynLib->getFunction(name);

		if (!res && m_getProcAddress)
			res = (GenericFuncType)m_getProcAddress(name);

		return res;
	}

protected:
	tcu::FunctionLibrary* const		m_staticLib;
	const de::DynamicLibrary*		m_dynLib;
	eglGetProcAddressFunc			m_getProcAddress;
};

class ExtLoader : public FunctionLoader
{
public:
	ExtLoader (const eglGetProcAddressFunc getProcAddress)
		: m_getProcAddress(getProcAddress)
	{
	}

	GenericFuncType get (const char* name) const
	{
		return (GenericFuncType)m_getProcAddress(name);
	}

protected:
	const eglGetProcAddressFunc			m_getProcAddress;
};

} // anonymous

DefaultLibrary::DefaultLibrary (const char* dynamicLibraryName)
	: m_dynLib(DE_NULL)
{
	if (dynamicLibraryName)
		m_dynLib = new de::DynamicLibrary(dynamicLibraryName);

	{
		const CoreLoader loader(m_dynLib);
		initCore(&m_egl, &loader);
	}

	if (m_egl.getProcAddress)
	{
		const ExtLoader loader(m_egl.getProcAddress);
		initExtensions(&m_egl, &loader);
	}
}

DefaultLibrary::~DefaultLibrary (void)
{
	delete m_dynLib;
}

const char* DefaultLibrary::getLibraryFileName (void)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	return "libEGL.so";
#elif (DE_OS == DE_OS_WIN32)
	return "libEGL.dll";
#else
	return DE_NULL;
#endif
}

} // eglw
