#ifndef __TnMapGlLoader__
#define __TnMapGlLoader__


/* See:
 *
 *  http://spaces.telenav.com:8080/display/eng/Platform+Heirarchy
 *  
 */


#if defined(TN_PLATFORM_IOS)
#include <RenderInterface/GLES/TnGl_iPhone.h>
#endif

#if defined(TN_PLATFORM_WINCE)
/* includes platforms 
 * TN_PLATFORM_WOLVERINE
 * TN_PLATFORM_WOLVERINE2
 * TN_PLATFORM_WINCE_ZEPHYR
 */
#include <RenderInterface/GLES/TnGl_WinCE.h>
#endif

#if defined(TN_PLATFORM_QNX)
#include <RenderInterface/GLES/TnGl_QNX.h>
#endif
#if defined(TN_PLATFORM_OSX)
#include <RenderInterface/GLES/TnGl_Mac.h>
#endif

#if defined(TN_PLATFORM_WINDOWS)
#include <RenderInterface/GLES/TnGl_Windows.h>
#endif


#if defined(TN_PLATFORM_LINUX_IMX51) || defined(TN_PLATFORM_LINUX_IMX6) || defined(TN_PLATFORM_LINUX_IMX_DELPHI)
#include <RenderInterface/GLES/TnGl_Linux_iMX.h>
#elif defined(TN_PLATFORM_ANDROID)
#include <RenderInterface/GLES/TnGl_Android.h>
#elif defined(TN_PLATFORM_LINUX)
#include <RenderInterface/GLES/TnGl_Linux.h>
#endif


//vendor specific things
#ifdef TN_GL_SHADER_BINARY_EXT
    #if !defined(TN_PLATFORM_WINDOWS) && !defined(TN_PLATFORM_WINCE)
    #define __stdcall   // here, other platforms may fail, so default loading binary shader to be false
    #endif
typedef void (__stdcall * PFNGLPROGRAMBINARY) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
typedef void (__stdcall * PFNGLGETPROGRAMBINARY) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
#endif  // TN_GL_SHADER_BINARY_EXT

#ifndef GL_PROGRAM_BINARY_LENGTH
#define GL_PROGRAM_BINARY_LENGTH                                0x8741
#endif // GL_PROGRAM_BINARY_LENGTH



#ifdef __cplusplus
bool TnGlInitOpenGL(void* (*pGetProAddrFunc)(const char *));
bool TnGlIsValid();

extern "C"
{
#endif

	//OpenGL 1.2 Extensions
#ifdef TN_GL_VERSION_1_2
	extern PFNGLBLENDCOLORPROC					glBlendColor;
	extern PFNGLBLENDEQUATIONPROC				glBlendEquation;
	extern PFNGLDRAWRANGEELEMENTSPROC			glDrawRangeElements;
	extern PFNGLTEXIMAGE3DPROC					glTexImage3D;
	extern PFNGLTEXSUBIMAGE3DPROC				glTexSubImage3D;
	extern PFNGLCOPYTEXSUBIMAGE3DPROC			glCopyTexSubImage3D;
#endif
	//OpenGL 1.3 Extensions
#ifdef TN_GL_VERSION_1_3
	extern PFNGLACTIVETEXTUREPROC				glActiveTexture;
	extern PFNGLSAMPLECOVERAGEPROC				glSampleCoverage;
	extern PFNGLCOMPRESSEDTEXIMAGE3DPROC		glCompressedTexImage3D;
	extern PFNGLCOMPRESSEDTEXIMAGE2DPROC		glCompressedTexImage2D;
	extern PFNGLCOMPRESSEDTEXIMAGE1DPROC		glCompressedTexImage1D;
	extern PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC		glCompressedTexSubImage3D;
	extern PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC		glCompressedTexSubImage2D;
	extern PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC		glCompressedTexSubImage1D;
	extern PFNGLGETCOMPRESSEDTEXIMAGEPROC		glGetCompressedTexImage;
#endif
	//OpenGL 1.4 Extensions
#ifdef TN_GL_VERSION_1_4
	extern PFNGLBLENDFUNCSEPARATEPROC			glBlendFuncSeparate;
	extern PFNGLMULTIDRAWARRAYSPROC				glMultiDrawArrays;
	extern PFNGLMULTIDRAWELEMENTSPROC			glMultiDrawElements;
	extern PFNGLPOINTPARAMETERFPROC				glPointParameterf;
	extern PFNGLPOINTPARAMETERFVPROC			glPointParameterfv;
	extern PFNGLPOINTPARAMETERIPROC				glPointParameteri;
	extern PFNGLPOINTPARAMETERIVPROC			glPointParameteriv;
#endif
	//OpenGL 1.5 Extensions
#ifdef TN_GL_VERSION_1_5
	extern PFNGLGENQUERIESPROC					glGenQueries;
	extern PFNGLDELETEQUERIESPROC				glDeleteQueries;
	extern PFNGLISQUERYPROC						glIsQuery;
	extern PFNGLBEGINQUERYPROC					glBeginQuery;
	extern PFNGLENDQUERYPROC					glEndQuery;
	extern PFNGLGETQUERYIVPROC					glGetQueryiv;
	extern PFNGLGETQUERYOBJECTIVPROC			glGetQueryObjectiv;
	extern PFNGLGETQUERYOBJECTUIVPROC			glGetQueryObjectuiv;
	extern PFNGLBINDBUFFERPROC					glBindBuffer;
	extern PFNGLDELETEBUFFERSPROC				glDeleteBuffers;
	extern PFNGLGENBUFFERSPROC					glGenBuffers;
	extern PFNGLISBUFFERPROC					glIsBuffer;
	extern PFNGLBUFFERDATAPROC					glBufferData;
	extern PFNGLBUFFERSUBDATAPROC				glBufferSubData;
	extern PFNGLGETBUFFERSUBDATAPROC			glGetBufferSubData;
	extern PFNGLMAPBUFFERPROC					glMapBuffer;
	extern PFNGLUNMAPBUFFERPROC					glUnmapBuffer;
	extern PFNGLGETBUFFERPARAMETERIVPROC		glGetBufferParameteriv;
	extern PFNGLGETBUFFERPOINTERVPROC			glGetBufferPointerv;
#endif
	//OpenGL 2.0 Extensions
#ifdef TN_GL_VERSION_2_0
	extern PFNGLBLENDEQUATIONSEPARATEPROC		glBlendEquationSeparate;
	extern PFNGLDRAWBUFFERSPROC					glDrawBuffers;
	extern PFNGLSTENCILOPSEPARATEPROC			glStencilOpSeparate;
	extern PFNGLSTENCILFUNCSEPARATEPROC			glStencilFuncSeparate;
	extern PFNGLSTENCILMASKSEPARATEPROC			glStencilMaskSeparate;
	extern PFNGLATTACHSHADERPROC				glAttachShader;
	extern PFNGLBINDATTRIBLOCATIONPROC			glBindAttribLocation;
	extern PFNGLCOMPILESHADERPROC				glCompileShader;
	extern PFNGLCREATEPROGRAMPROC				glCreateProgram;
	extern PFNGLCREATESHADERPROC				glCreateShader;
	extern PFNGLDELETEPROGRAMPROC				glDeleteProgram;
	extern PFNGLDELETESHADERPROC				glDeleteShader;
	extern PFNGLDETACHSHADERPROC				glDetachShader;
	extern PFNGLDISABLEVERTEXATTRIBARRAYPROC	glDisableVertexAttribArray;
	extern PFNGLENABLEVERTEXATTRIBARRAYPROC		glEnableVertexAttribArray;
	extern PFNGLGETACTIVEATTRIBPROC				glGetActiveAttrib;
	extern PFNGLGETACTIVEUNIFORMPROC			glGetActiveUniform;
	extern PFNGLGETATTACHEDSHADERSPROC			glGetAttachedShaders;
	extern PFNGLGETATTRIBLOCATIONPROC			glGetAttribLocation;
	extern PFNGLGETPROGRAMIVPROC				glGetProgramiv;
	extern PFNGLGETPROGRAMINFOLOGPROC			glGetProgramInfoLog;
	extern PFNGLGETSHADERIVPROC					glGetShaderiv;
	extern PFNGLGETSHADERINFOLOGPROC			glGetShaderInfoLog;
	extern PFNGLGETSHADERSOURCEPROC				glGetShaderSource;
	extern PFNGLGETUNIFORMLOCATIONPROC			glGetUniformLocation;
	extern PFNGLGETUNIFORMFVPROC				glGetUniformfv;
	extern PFNGLGETUNIFORMIVPROC				glGetUniformiv;
	extern PFNGLGETVERTEXATTRIBDVPROC			glGetVertexAttribdv;
	extern PFNGLGETVERTEXATTRIBFVPROC			glGetVertexAttribfv;
	extern PFNGLGETVERTEXATTRIBIVPROC			glGetVertexAttribiv;
	extern PFNGLGETVERTEXATTRIBPOINTERVPROC		glGetVertexAttribPointerv;
	extern PFNGLISPROGRAMPROC					glIsProgram;
	extern PFNGLISSHADERPROC					glIsShader;
	extern PFNGLLINKPROGRAMPROC					glLinkProgram;
	extern PFNGLSHADERSOURCEPROC				glShaderSource;
	extern PFNGLUSEPROGRAMPROC					glUseProgram;
	extern PFNGLUNIFORM1FPROC					glUniform1f;
	extern PFNGLUNIFORM2FPROC					glUniform2f;
	extern PFNGLUNIFORM3FPROC					glUniform3f;
	extern PFNGLUNIFORM4FPROC 					glUniform4f;
	extern PFNGLUNIFORM1IPROC					glUniform1i;
	extern PFNGLUNIFORM2IPROC 					glUniform2i;
	extern PFNGLUNIFORM3IPROC 					glUniform3i;
	extern PFNGLUNIFORM4IPROC 					glUniform4i;
	extern PFNGLUNIFORM1FVPROC					glUniform1fv;
	extern PFNGLUNIFORM2FVPROC					glUniform2fv;
	extern PFNGLUNIFORM3FVPROC					glUniform3fv;
	extern PFNGLUNIFORM4FVPROC					glUniform4fv;
	extern PFNGLUNIFORM1IVPROC					glUniform1iv;
	extern PFNGLUNIFORM2IVPROC					glUniform2iv;
	extern PFNGLUNIFORM3IVPROC					glUniform3iv;
	extern PFNGLUNIFORM4IVPROC					glUniform4iv;
	extern PFNGLUNIFORMMATRIX2FVPROC			glUniformMatrix2fv;
	extern PFNGLUNIFORMMATRIX3FVPROC			glUniformMatrix3fv;
	extern PFNGLUNIFORMMATRIX4FVPROC			glUniformMatrix4fv;
	extern PFNGLVALIDATEPROGRAMPROC				glValidateProgram;
	extern PFNGLVERTEXATTRIB1DPROC				glVertexAttrib1d;
	extern PFNGLVERTEXATTRIB1DVPROC				glVertexAttrib1dv;
	extern PFNGLVERTEXATTRIB1FPROC				glVertexAttrib1f;
	extern PFNGLVERTEXATTRIB1FVPROC				glVertexAttrib1fv;
	extern PFNGLVERTEXATTRIB1SPROC				glVertexAttrib1s;
	extern PFNGLVERTEXATTRIB1SVPROC				glVertexAttrib1sv;
	extern PFNGLVERTEXATTRIB2DPROC				glVertexAttrib2d;
	extern PFNGLVERTEXATTRIB2DVPROC				glVertexAttrib2dv;
	extern PFNGLVERTEXATTRIB2FPROC				glVertexAttrib2f;
	extern PFNGLVERTEXATTRIB2FVPROC				glVertexAttrib2fv;
	extern PFNGLVERTEXATTRIB2SPROC				glVertexAttrib2s;
	extern PFNGLVERTEXATTRIB2SVPROC				glVertexAttrib2sv;
	extern PFNGLVERTEXATTRIB3DPROC				glVertexAttrib3d;
	extern PFNGLVERTEXATTRIB3DVPROC				glVertexAttrib3dv;
	extern PFNGLVERTEXATTRIB3FPROC				glVertexAttrib3f;
	extern PFNGLVERTEXATTRIB3FVPROC				glVertexAttrib3fv;
	extern PFNGLVERTEXATTRIB3SPROC				glVertexAttrib3s;
	extern PFNGLVERTEXATTRIB3SVPROC				glVertexAttrib3sv;
	extern PFNGLVERTEXATTRIB4NBVPROC			glVertexAttrib4Nbv;
	extern PFNGLVERTEXATTRIB4NIVPROC			glVertexAttrib4Niv;
	extern PFNGLVERTEXATTRIB4NSVPROC			glVertexAttrib4Nsv;
	extern PFNGLVERTEXATTRIB4NUBPROC			glVertexAttrib4Nub;
	extern PFNGLVERTEXATTRIB4NUBVPROC			glVertexAttrib4Nubv;
	extern PFNGLVERTEXATTRIB4NUIVPROC			glVertexAttrib4Nuiv;
	extern PFNGLVERTEXATTRIB4NUSVPROC			glVertexAttrib4Nusv;
	extern PFNGLVERTEXATTRIB4BVPROC				glVertexAttrib4bv;
	extern PFNGLVERTEXATTRIB4DPROC				glVertexAttrib4d;
	extern PFNGLVERTEXATTRIB4DVPROC				glVertexAttrib4dv;
	extern PFNGLVERTEXATTRIB4FPROC				glVertexAttrib4f;
	extern PFNGLVERTEXATTRIB4FVPROC				glVertexAttrib4fv;
	extern PFNGLVERTEXATTRIB4IVPROC				glVertexAttrib4iv;
	extern PFNGLVERTEXATTRIB4SPROC				glVertexAttrib4s;
	extern PFNGLVERTEXATTRIB4SVPROC				glVertexAttrib4sv;
	extern PFNGLVERTEXATTRIB4UBVPROC			glVertexAttrib4ubv;
	extern PFNGLVERTEXATTRIB4UIVPROC			glVertexAttrib4uiv;
	extern PFNGLVERTEXATTRIB4USVPROC			glVertexAttrib4usv;
	extern PFNGLVERTEXATTRIBPOINTERPROC			glVertexAttribPointer;

	//Frame buffer and render buffer functions
    extern PFNGLGENFRAMEBUFFERSPROC						glGenFramebuffers;
    extern PFNGLDELETEFRAMEBUFFERSPROC					glDeleteFramebuffers;
    extern PFNGLBINDFRAMEBUFFERPROC						glBindFramebuffer;
    extern PFNGLCHECKFRAMEBUFFERSTATUSPROC				glCheckFramebufferStatus;
    extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC	glGetFramebufferAttachmentParameteriv;
    extern PFNGLFRAMEBUFFERTEXTURE2DPROC				glFramebufferTexture2D;
    extern PFNGLFRAMEBUFFERRENDERBUFFERPROC				glFramebufferRenderbuffer;
    extern PFNGLGENRENDERBUFFERSPROC					glGenRenderbuffers;       
    extern PFNGLDELETERENDERBUFFERSPROC					glDeleteRenderbuffers;    
    extern PFNGLBINDRENDERBUFFERPROC					glBindRenderbuffer;       
    extern PFNGLRENDERBUFFERSTORAGEPROC					glRenderbufferStorage;
    extern PFNGLGETRENDERBUFFERPARAMETERIVPROC			glGetRenderbufferParameteriv;
    extern PFNGLISRENDERBUFFERPROC						glIsRenderbuffer;

#endif

#ifdef TN_GL_EXT_PROTOTYPES
	extern PFNGLGENERATEMIPMAPPROC				glGenerateMipmap;
#endif

#if defined(TN_PLATFORM_QNXXX)
	extern PFNGLBINDBUFFEROESPROC				glBindBuffer;
	extern PFNGLDELETEBUFFERSOESPROC			glDeleteBuffers;
	extern PFNGLGENBUFFERSOESPROC				glGenBuffers;
	extern PFNGLISBUFFEROESPROC                 glIsBuffer;
	extern PFNGLBUFFERDATAOESPROC				glBufferData;
	extern PFNGLBUFFERSUBDATAOESPROC			glBufferSubData;
	extern PFNGLGETBUFFERSUBDATAOESPROC			glGetBufferSubData;
	extern PFNGLMAPBUFFEROESPROC				glMapBuffer;
	extern PFNGLUNMAPBUFFEROESPROC				glUnmapBuffer;
	extern PFNGLGETBUFFERPARAMETERIVOESPROC		glGetBufferParameteriv;
	extern PFNGLGETBUFFERPOINTERVOESPROC		glGetBufferPointerv;
#endif

#ifdef TN_GL_SHADER_BINARY_EXT
    extern PFNGLPROGRAMBINARY                   glProgramBinary;
    extern PFNGLGETPROGRAMBINARY                glGetProgramBinary;
#endif

// http://www.khronos.org/registry/gles/extensions/IMG/IMG_texture_compression_pvrtc.txt
#define    TN_GL_COMPRESSED_RGB_PVRTC_4BPPV1                   0x8C00
#define    TN_GL_COMPRESSED_RGB_PVRTC_2BPPV1                   0x8C01
#define    TN_GL_COMPRESSED_RGBA_PVRTC_4BPPV1                  0x8C02
#define    TN_GL_COMPRESSED_RGBA_PVRTC_2BPPV1                  0x8C03

// http://www.khronos.org/registry/gles/extensions/NV/GL_NV_texture_compression_s3tc.txt
// http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
#define    TN_GL_COMPRESSED_RGB_S3TC_DXT1                     0x83F0
#define    TN_GL_COMPRESSED_RGBA_S3TC_DXT1                    0x83F1
#define    TN_GL_COMPRESSED_RGBA_S3TC_DXT3                    0x83F2
#define    TN_GL_COMPRESSED_RGBA_S3TC_DXT5                    0x83F3
    
#ifdef __cplusplus
}
#endif

#endif
