#pragma once

#ifndef __gxopengl_wglext_h__
	#define __gxopengl_wglext_h__

#include "../foundation.h"
#include "gltypes.h"
#include "wglcore.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ## WGL_ARB_buffer_region ## */
GX_API  HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
GX_API  VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
GX_API  BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
GX_API  BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);

/* ## WGL_ARB_extensions_string ## */
GX_API  const char * WINAPI wglGetExtensionsStringARB (HDC hdc);

/* ## WGL_ARB_pixel_format ## */
GX_API  BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
GX_API  BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
GX_API  BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);

/* ## WGL_ARB_make_current_read ## */
GX_API  BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
GX_API  HDC WINAPI wglGetCurrentReadDCARB (void);

/* ## WGL_ARB_pbuffer ## */
GX_API  HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
GX_API  HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
GX_API  int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
GX_API  BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
GX_API  BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);

/* ## WGL_ARB_render_texture ## */
GX_API  BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
GX_API  BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
GX_API  BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);

/* ## WGL_ARB_create_context ## */
GX_API  HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);

/* ## WGL_EXT_display_color_table ## */
GX_API  GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
GX_API  GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
GX_API  GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
GX_API  VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);

/* ## WGL_EXT_extensions_string ## */
GX_API  const char * WINAPI wglGetExtensionsStringEXT (void);

/* ## WGL_EXT_make_current_read ## */
GX_API  BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
GX_API  HDC WINAPI wglGetCurrentReadDCEXT (void);

/* ## WGL_EXT_pbuffer ## */
GX_API  HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
GX_API  HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
GX_API  int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
GX_API  BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
GX_API  BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);

/* ## WGL_EXT_pixel_format ## */
GX_API  BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
GX_API  BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
GX_API  BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);

/* ## WGL_EXT_swap_control ## */
GX_API  BOOL WINAPI wglSwapIntervalEXT (int interval);
GX_API  int WINAPI wglGetSwapIntervalEXT (void);

/* ## WGL_NV_vertex_array_range ## */
GX_API  void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
GX_API  void WINAPI wglFreeMemoryNV (void *pointer);

/* ## WGL_OML_sync_control ## */
GX_API  BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
GX_API  BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
GX_API  INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
GX_API  INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
GX_API  BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
GX_API  BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);

/* ## WGL_I3D_digital_video_control ## */
GX_API  BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
GX_API  BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);

/* ## WGL_I3D_gamma ## */
GX_API  BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
GX_API  BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
GX_API  BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
GX_API  BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);

/* ## WGL_I3D_genlock ## */
GX_API  BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
GX_API  BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
GX_API  BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
GX_API  BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
GX_API  BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
GX_API  BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
GX_API  BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
GX_API  BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
GX_API  BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
GX_API  BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
GX_API  BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
GX_API  BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);

/* ## WGL_I3D_image_buffer ## */
GX_API  LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
GX_API  BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
GX_API  BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
GX_API  BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);

/* ## WGL_I3D_swap_frame_lock ## */
GX_API  BOOL WINAPI wglEnableFrameLockI3D (void);
GX_API  BOOL WINAPI wglDisableFrameLockI3D (void);
GX_API  BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
GX_API  BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);

/* ## WGL_I3D_swap_frame_usage ## */
GX_API  BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
GX_API  BOOL WINAPI wglBeginFrameTrackingI3D (void);
GX_API  BOOL WINAPI wglEndFrameTrackingI3D (void);
GX_API  BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);

/* ## WGL_3DL_stereo_control ## */
GX_API  BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);

/* ## WGL_NV_present_video ## */
GX_API  int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
GX_API  BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
GX_API  BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);

/* ## WGL_NV_video_output ## */
GX_API  BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
GX_API  BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
GX_API  BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
GX_API  BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
GX_API  BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
GX_API  BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);

/* ## WGL_NV_swap_group ## */
GX_API  BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
GX_API  BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
GX_API  BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
GX_API  BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
GX_API  BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
GX_API  BOOL WINAPI wglResetFrameCountNV (HDC hDC);

/* ## WGL_NV_gpu_affinity ## */
GX_API  BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
GX_API  BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
GX_API  HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
GX_API  BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
GX_API  BOOL WINAPI wglDeleteDCNV (HDC hdc);

/* ## WGL_AMD_gpu_association ## */
GX_API  UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
GX_API  INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
GX_API  UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
GX_API  HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
GX_API  HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
GX_API  BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
GX_API  BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
GX_API  HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
GX_API  VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);

/* ## WGL_NV_video_capture ## */
GX_API  BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
GX_API  UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
GX_API  BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
GX_API  BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
GX_API  BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);

/* ## WGL_NV_copy_image ## */
GX_API  BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);

/* ## WGL_NV_DX_interop ## */
GX_API  BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
GX_API  HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
GX_API  BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
GX_API  HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
GX_API  BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
GX_API  BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
GX_API  BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
GX_API  BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);

#ifdef __cplusplus
}
#endif

namespace Gx
{
	extern GX_API bool hasWGL_ARB_buffer_region;
	extern GX_API bool hasWGL_ARB_multisample;
	extern GX_API bool hasWGL_ARB_extensions_string;
	extern GX_API bool hasWGL_ARB_pixel_format;
	extern GX_API bool hasWGL_ARB_make_current_read;
	extern GX_API bool hasWGL_ARB_pbuffer;
	extern GX_API bool hasWGL_ARB_render_texture;
	extern GX_API bool hasWGL_ARB_pixel_format_float;
	extern GX_API bool hasWGL_ARB_framebuffer_sRGB;
	extern GX_API bool hasWGL_ARB_create_context;
	extern GX_API bool hasWGL_ARB_create_context_profile;
	extern GX_API bool hasWGL_ARB_create_context_robustness;
	extern GX_API bool hasWGL_EXT_display_color_table;
	extern GX_API bool hasWGL_EXT_extensions_string;
	extern GX_API bool hasWGL_EXT_make_current_read;
	extern GX_API bool hasWGL_EXT_pbuffer;
	extern GX_API bool hasWGL_EXT_pixel_format;
	extern GX_API bool hasWGL_EXT_swap_control;
	extern GX_API bool hasWGL_EXT_depth_float;
	extern GX_API bool hasWGL_NV_vertex_array_range;
	extern GX_API bool hasWGL_3DFX_multisample;
	extern GX_API bool hasWGL_EXT_multisample;
	extern GX_API bool hasWGL_OML_sync_control;
	extern GX_API bool hasWGL_I3D_digital_video_control;
	extern GX_API bool hasWGL_I3D_gamma;
	extern GX_API bool hasWGL_I3D_genlock;
	extern GX_API bool hasWGL_I3D_image_buffer;
	extern GX_API bool hasWGL_I3D_swap_frame_lock;
	extern GX_API bool hasWGL_I3D_swap_frame_usage;
	extern GX_API bool hasWGL_ATI_pixel_format_float;
	extern GX_API bool hasWGL_NV_float_buffer;
	extern GX_API bool hasWGL_3DL_stereo_control;
	extern GX_API bool hasWGL_EXT_pixel_format_packed_float;
	extern GX_API bool hasWGL_EXT_framebuffer_sRGB;
	extern GX_API bool hasWGL_NV_present_video;
	extern GX_API bool hasWGL_NV_video_output;
	extern GX_API bool hasWGL_NV_swap_group;
	extern GX_API bool hasWGL_NV_gpu_affinity;
	extern GX_API bool hasWGL_AMD_gpu_association;
	extern GX_API bool hasWGL_NV_video_capture;
	extern GX_API bool hasWGL_NV_copy_image;
	extern GX_API bool hasWGL_NV_multisample_coverage;
	extern GX_API bool hasWGL_NV_DX_interop;
	extern GX_API bool hasWGL_NV_DX_interop2;
	extern GX_API bool hasWGL_EXT_swap_control_tear;

	GX_API bool hasWGLExtension(const char* extensionName);

	GX_API void loadWGLFuntions();
}

#endif /* __gxopengl_wglext_h__ */