/*
* Copyright (C) 2011 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.
*/
#include "EglOsApi.h"
#include <windows.h>
#include <wingdi.h>
#include <GL/wglext.h>

#define IS_TRUE(a) \
        if(a != true) return false;




struct DisplayInfo{
    DisplayInfo():dc(NULL),hwnd(NULL),isPixelFormatSet(false){};
    DisplayInfo(HDC hdc,HWND wnd):isPixelFormatSet(false){dc = hdc; hwnd = wnd;};
    HDC  dc;
    HWND hwnd;
    bool isPixelFormatSet;
};

class WinDisplay{
public:
     typedef enum {
                      DEFAULT_DISPLAY = 0
                  };
     WinDisplay():m_current(DEFAULT_DISPLAY){};
     DisplayInfo& getInfo(int configurationIndex){ return m_map[configurationIndex];}
     HDC  getCurrentDC(){return m_map[m_current].dc;}
     void setDefault(const DisplayInfo& info){m_map[DEFAULT_DISPLAY] = info; m_current = DEFAULT_DISPLAY;}
     void setCurrent(int configurationIndex,const DisplayInfo& info);
     bool isCurrentPixelFormatSet(){ return m_map[m_current].isPixelFormatSet;}
     void currentPixelFormatWasSet(){m_map[m_current].isPixelFormatSet = true;}
     bool needToSetCurrent(int configurationIndex);
     void releaseAll();
private:
    std::map<int,DisplayInfo> m_map;
    int                       m_current;
};

void WinDisplay::releaseAll(){
    for(std::map<int,DisplayInfo>::iterator it = m_map.begin(); it != m_map.end();it++){
       DestroyWindow((*it).second.hwnd);
       DeleteDC((*it).second.dc);
    }
}

bool WinDisplay::needToSetCurrent(int configurationIndex){
    return m_map.find(configurationIndex) == m_map.end();
}

void WinDisplay::setCurrent(int configurationIndex,const DisplayInfo& info){
    m_map[configurationIndex] = info;
    m_current = configurationIndex;
}
namespace EglOS{

struct WglExtProcs{
    PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB;
    PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
    PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB;
    PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB;
    PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB;
    PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB;
    PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB;
    PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
};

static WglExtProcs* s_wglExtProcs = NULL;

PROC wglGetExtentionsProcAddress(HDC hdc,const char *extension_name,const char* proc_name)
{
    // this is pointer to function which returns pointer to string with list of all wgl extensions
    PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = NULL;

    // determine pointer to wglGetExtensionsStringEXT function
    _wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
    if(!_wglGetExtensionsStringARB){
        fprintf(stderr,"could not get wglGetExtensionsStringARB\n");
        return NULL;
    }

    if (!_wglGetExtensionsStringARB || strstr(_wglGetExtensionsStringARB(hdc), extension_name) == NULL)
    {
        fprintf(stderr,"extension %s was not found\n",extension_name);
        // string was not found
        return NULL;
    }

    // extension is supported
    return wglGetProcAddress(proc_name);
}

LRESULT CALLBACK dummyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

HWND createDummyWindow(){

    WNDCLASSEX wcx;
    wcx.cbSize = sizeof(wcx);                       // size of structure
    wcx.style =  CS_OWNDC |CS_HREDRAW |CS_VREDRAW;  // redraw if size changes
    wcx.lpfnWndProc = dummyWndProc;                 // points to window procedure
    wcx.cbClsExtra = 0;                             // no extra class memory
    wcx.cbWndExtra = sizeof(void*);                 // save extra window memory, to store VasWindow instance
    wcx.hInstance = NULL;                           // handle to instance
    wcx.hIcon = NULL;                               // predefined app. icon
    wcx.hCursor = NULL;
    wcx.hbrBackground = NULL;                       // no background brush
    wcx.lpszMenuName =  NULL;                       // name of menu resource
    wcx.lpszClassName = "DummyWin";                 // name of window class
    wcx.hIconSm = (HICON) NULL;                     // small class icon

    ATOM winClass = RegisterClassEx(&wcx);
    HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                               "DummyWin",
                               "Dummy",
                               WS_POPUP,
                               0,
                               0,
                               1,
                               1,
                               NULL,
                               NULL,
                               0,0);
    return hwnd;
}

EGLNativeDisplayType getDefaultDisplay() {
    WinDisplay* dpy = new WinDisplay();

    HWND hwnd = createDummyWindow();
    HDC  hdc  =  GetDC(hwnd);
    dpy->setDefault(DisplayInfo(hdc,hwnd));
    return static_cast<EGLNativeDisplayType>(dpy);
}


void initPtrToWglFunctions(){

    HWND hwnd = createDummyWindow();
    HDC dpy =  GetDC(hwnd);
    if(!hwnd || !dpy){
        fprintf(stderr,"error while getting DC\n");
        return;
    }
    EGLNativeContextType ctx = NULL;
    PIXELFORMATDESCRIPTOR pfd = {
                                  sizeof(PIXELFORMATDESCRIPTOR),  //  size of this pfd
                                  1,                     // version number
                                  PFD_DRAW_TO_WINDOW |   // support window
                                  PFD_SUPPORT_OPENGL |   // support OpenGL
                                  PFD_DOUBLEBUFFER,      // double buffered
                                  PFD_TYPE_RGBA,         // RGBA type
                                  24,                    // 24-bit color depth
                                  0, 0, 0, 0, 0, 0,      // color bits ignored
                                  0,                     // no alpha buffer
                                  0,                     // shift bit ignored
                                  0,                     // no accumulation buffer
                                  0, 0, 0, 0,            // accum bits ignored
                                  32,                    // 32-bit z-buffer
                                  0,                     // no stencil buffer
                                  0,                     // no auxiliary buffer
                                  PFD_MAIN_PLANE,        // main layer
                                  0,                     // reserved
                                  0, 0, 0                // layer masks ignored
                                 };

    int  iPixelFormat,err;
    iPixelFormat = ChoosePixelFormat(dpy, &pfd);
    if(iPixelFormat < 0){
        fprintf(stderr,"error while choosing pixel format\n");
        return;
    }
    if(!SetPixelFormat(dpy,iPixelFormat,&pfd)){

        int err = GetLastError();
        fprintf(stderr,"error while setting pixel format 0x%x\n",err);
        return;
    }


    ctx = wglCreateContext(dpy);
    if(!ctx){
        err =  GetLastError();
        printf("error while creating dummy context %d\n",err);
    }
    if(!wglMakeCurrent(dpy,ctx)){
        err =  GetLastError();
        printf("error while making dummy context current %d\n",err);
    }

    if(!s_wglExtProcs){
        s_wglExtProcs = new WglExtProcs();
        s_wglExtProcs->wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pixel_format","wglGetPixelFormatAttribivARB");
        s_wglExtProcs->wglChoosePixelFormatARB      = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pixel_format","wglChoosePixelFormatARB");
        s_wglExtProcs->wglCreatePbufferARB          = (PFNWGLCREATEPBUFFERARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglCreatePbufferARB");
        s_wglExtProcs->wglReleasePbufferDCARB       = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglReleasePbufferDCARB");
        s_wglExtProcs->wglDestroyPbufferARB         = (PFNWGLDESTROYPBUFFERARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglDestroyPbufferARB");
        s_wglExtProcs->wglGetPbufferDCARB           = (PFNWGLGETPBUFFERDCARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_pbuffer","wglGetPbufferDCARB");
        s_wglExtProcs->wglMakeContextCurrentARB     = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetExtentionsProcAddress(dpy,"WGL_ARB_make_current_read","wglMakeContextCurrentARB");
        s_wglExtProcs->wglSwapIntervalEXT           = (PFNWGLSWAPINTERVALEXTPROC)wglGetExtentionsProcAddress(dpy,"WGL_EXT_swap_control","wglSwapIntervalEXT");
    }

   wglMakeCurrent(dpy,NULL);
   DestroyWindow(hwnd);
   DeleteDC(dpy);
}

bool releaseDisplay(EGLNativeDisplayType dpy) {
    dpy->releaseAll();
    return true;
}



EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,EGLNativePixelFormatType* frmt,int index){

    EGLint  red,green,blue,alpha,depth,stencil;
    EGLint  supportedSurfaces,visualType,visualId;
    EGLint  transparentType,samples;
    EGLint  tRed,tGreen,tBlue;
    EGLint  pMaxWidth,pMaxHeight,pMaxPixels;
    EGLint  configId,level;
    EGLint  window,bitmap,pbuffer,transparent;
    HDC dpy = display->getCurrentDC();

    if(frmt->iPixelType != PFD_TYPE_RGBA) return NULL; // other formats are not supported yet
    if(!((frmt->dwFlags & PFD_SUPPORT_OPENGL) && (frmt->dwFlags & PFD_DOUBLEBUFFER))) return NULL; //pixel format does not supports opengl or double buffer

    int attribs [] = {
                          WGL_DRAW_TO_WINDOW_ARB,
                          WGL_DRAW_TO_BITMAP_ARB,
                          WGL_DRAW_TO_PBUFFER_ARB,
                          WGL_TRANSPARENT_ARB,
                          WGL_TRANSPARENT_RED_VALUE_ARB,
                          WGL_TRANSPARENT_GREEN_VALUE_ARB,
                          WGL_TRANSPARENT_BLUE_VALUE_ARB
                     };

    supportedSurfaces = 0;
    if(!s_wglExtProcs->wglGetPixelFormatAttribivARB) return NULL;

    IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[0],&window));
    IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[1],&bitmap));
    IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[2],&pbuffer));
    if(window)  supportedSurfaces |= EGL_WINDOW_BIT;
    if(bitmap)  supportedSurfaces |= EGL_PIXMAP_BIT;
    if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT;

    if(!supportedSurfaces) return NULL;

    //default values
    visualId                  = 0;
    visualType                = EGL_NONE;
    EGLenum caveat            = EGL_NONE;
    EGLBoolean renderable     = EGL_FALSE;
    pMaxWidth                 = PBUFFER_MAX_WIDTH;
    pMaxHeight                = PBUFFER_MAX_HEIGHT;
    pMaxPixels                = PBUFFER_MAX_PIXELS;
    samples                   = 0 ;
    level                     = 0 ;

    IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[3],&transparent));
    if(transparent) {
        transparentType = EGL_TRANSPARENT_RGB;
        IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[4],&tRed));
        IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[5],&tGreen));
        IS_TRUE(s_wglExtProcs->wglGetPixelFormatAttribivARB(dpy,index,0,1,&attribs[6],&tBlue));
    } else {
        transparentType = EGL_NONE;
    }

    red     = frmt->cRedBits;
    green   = frmt->cGreenBits;
    blue    = frmt->cBlueBits;
    alpha   = frmt->cAlphaBits;
    depth   = frmt->cDepthBits;
    stencil = frmt->cStencilBits;
    return new EglConfig(red,green,blue,alpha,caveat,(EGLint)index,depth,level,pMaxWidth,pMaxHeight,pMaxPixels,renderable,renderableType,
                         visualId,visualType,samples,stencil,supportedSurfaces,transparentType,tRed,tGreen,tBlue,*frmt);
}


void queryConfigs(EGLNativeDisplayType display,int renderableType,ConfigsList& listOut) {
    PIXELFORMATDESCRIPTOR  pfd;
    int  iPixelFormat = 1;
    HDC dpy = display->getCurrentDC();


    //quering num of formats
    int nFormats = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);

    //inserting rest of formats
    for(iPixelFormat;iPixelFormat < nFormats; iPixelFormat++) {
         DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
         EglConfig* pConfig = pixelFormatToConfig(display,renderableType,&pfd,iPixelFormat);
         if(pConfig) listOut.push_back(pConfig);
    }

}


bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win) {
    return IsWindow(win);
}

bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativePixmapType pix) {
    BITMAP bm;
    return GetObject(pix, sizeof(BITMAP), (LPSTR)&bm);
}

static bool setPixelFormat(HDC dc,EglConfig* cfg) {
    EGLint red,green,blue,alpha,depth,stencil;
    bool   gotAttribs = cfg->getConfAttrib(EGL_RED_SIZE,&red)     &&
                        cfg->getConfAttrib(EGL_GREEN_SIZE,&green) &&
                        cfg->getConfAttrib(EGL_BLUE_SIZE,&blue)   &&
                        cfg->getConfAttrib(EGL_ALPHA_SIZE,&alpha) &&
                        cfg->getConfAttrib(EGL_DEPTH_SIZE,&depth) &&
                        cfg->getConfAttrib(EGL_STENCIL_SIZE,&stencil) ;

     if(!gotAttribs) return false;
     int wglPixelFormatAttribs[] = {
                                    WGL_SUPPORT_OPENGL_ARB       ,TRUE,
                                    WGL_DRAW_TO_PBUFFER_ARB      ,TRUE,
                                    WGL_DRAW_TO_WINDOW_ARB       ,TRUE,
                                    WGL_COLOR_BITS_ARB           ,red+green+blue,
                                    WGL_RED_BITS_ARB             ,red,
                                    WGL_GREEN_BITS_ARB           ,green,
                                    WGL_BLUE_BITS_ARB            ,blue,
                                    WGL_ALPHA_BITS_ARB           ,alpha,
                                    WGL_STENCIL_BITS_ARB         ,stencil,
                                    WGL_DEPTH_BITS_ARB           ,depth,
                                    WGL_DOUBLE_BUFFER_ARB        ,TRUE,
                                    0
                                   };
    int iPixelFormat;
    unsigned int numpf;
    if(!s_wglExtProcs->wglChoosePixelFormatARB || !s_wglExtProcs->wglChoosePixelFormatARB(dc,wglPixelFormatAttribs, NULL, 1, &iPixelFormat, &numpf)) {
        return false;
    }
   EGLNativePixelFormatType frmt = cfg->nativeConfig();
   //int iPixelFormat = ChoosePixelFormat(dc,&frmt);
   if(!iPixelFormat) return false;
   return SetPixelFormat(dc,iPixelFormat,&frmt);
}


bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height) {
   RECT r;
   if(!GetClientRect(win,&r)) return false;
   *width  = r.right  - r.left;
   *height = r.bottom - r.top;
   HDC dc = GetDC(win);
   bool ret = setPixelFormat(dc,cfg);
   DeleteDC(dc);
   return ret;
}

bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height){

    BITMAP bm;
    if(!GetObject(pix, sizeof(BITMAP), (LPSTR)&bm)) return false;

    *width  = bm.bmWidth;
    *height = bm.bmHeight;

    return true;
}

EGLNativePbufferType createPbuffer(EGLNativeDisplayType display,EglConfig* cfg,EglPbufferSurface* pbSurface) {

  //converting configuration into WGL pixel Format
   EGLint red,green,blue,alpha,depth,stencil;
   bool   gotAttribs = cfg->getConfAttrib(EGL_RED_SIZE,&red)     &&
                       cfg->getConfAttrib(EGL_GREEN_SIZE,&green) &&
                       cfg->getConfAttrib(EGL_BLUE_SIZE,&blue)   &&
                       cfg->getConfAttrib(EGL_ALPHA_SIZE,&alpha) &&
                       cfg->getConfAttrib(EGL_DEPTH_SIZE,&depth) &&
                       cfg->getConfAttrib(EGL_STENCIL_SIZE,&stencil) ;

 if(!gotAttribs) return false;
 int wglPixelFormatAttribs[] = {
                                WGL_SUPPORT_OPENGL_ARB       ,TRUE,
                                WGL_DRAW_TO_PBUFFER_ARB      ,TRUE,
                                WGL_BIND_TO_TEXTURE_RGBA_ARB ,TRUE,
                                WGL_COLOR_BITS_ARB           ,red+green+blue,
                                WGL_RED_BITS_ARB             ,red,
                                WGL_GREEN_BITS_ARB           ,green,
                                WGL_BLUE_BITS_ARB            ,blue,
                                WGL_ALPHA_BITS_ARB           ,alpha,
                                WGL_STENCIL_BITS_ARB         ,stencil,
                                WGL_DEPTH_BITS_ARB           ,depth,
                                WGL_DOUBLE_BUFFER_ARB        ,TRUE,
                                0
                               };

    HDC dpy = display->getCurrentDC();
    int pixfmt;
    unsigned int numpf;
    if(!s_wglExtProcs->wglChoosePixelFormatARB || !s_wglExtProcs->wglChoosePixelFormatARB(dpy,wglPixelFormatAttribs, NULL, 1, &pixfmt, &numpf)) {
        DWORD err = GetLastError();
        return NULL;
    }

    EGLint width,height,largest,texTarget,texFormat;
    pbSurface->getDim(&width,&height,&largest);
    pbSurface->getTexInfo(&texTarget,&texFormat);

    int wglTexFormat = WGL_NO_TEXTURE_ARB;
    int wglTexTarget = (texTarget == EGL_TEXTURE_2D)? WGL_TEXTURE_2D_ARB:
                                                      WGL_NO_TEXTURE_ARB;

    switch(texFormat) {
    case EGL_TEXTURE_RGB:
        wglTexFormat = WGL_TEXTURE_RGB_ARB;
        break;
    case EGL_TEXTURE_RGBA:
        wglTexFormat = WGL_TEXTURE_RGBA_ARB;
        break;
    }

    int pbAttribs[] = {
                       WGL_TEXTURE_TARGET_ARB   ,wglTexTarget,
                       WGL_TEXTURE_FORMAT_ARB   ,wglTexFormat,
                       0
                      };
    if(!s_wglExtProcs->wglCreatePbufferARB) return NULL;
    EGLNativePbufferType pb = s_wglExtProcs->wglCreatePbufferARB(dpy,pixfmt,width,height,pbAttribs);
    if(!pb) {
        DWORD err = GetLastError();
        return NULL;
    }
    return pb;
}

bool releasePbuffer(EGLNativeDisplayType display,EGLNativePbufferType pb) {
    HDC  dis =  display->getCurrentDC();
    if(!s_wglExtProcs->wglReleasePbufferDCARB || !s_wglExtProcs->wglDestroyPbufferARB) return false;
    if(!s_wglExtProcs->wglReleasePbufferDCARB(pb,dis) || !s_wglExtProcs->wglDestroyPbufferARB(pb)){
        DWORD err = GetLastError();
        return false;
    }
    return true;
}

EGLNativeContextType createContext(EGLNativeDisplayType display,EglConfig* cfg,EGLNativeContextType sharedContext) {

    EGLNativeContextType ctx = NULL;
    HDC  dpy  = NULL;
    if(display->needToSetCurrent(cfg->id())){
        HWND hwnd = createDummyWindow();
        dpy  = GetDC(hwnd);
        display->setCurrent(cfg->id(),DisplayInfo(dpy,hwnd));
    } else {
        dpy = display->getCurrentDC();
    }

    if(!display->isCurrentPixelFormatSet()){
        if(!setPixelFormat(dpy,cfg)) return NULL;
        display->currentPixelFormatWasSet();
    }

    ctx = wglCreateContext(dpy);

    if(ctx && sharedContext) {
        if(!wglShareLists(sharedContext,ctx)) {
            wglDeleteContext(ctx);
            return NULL;
        }
    }
    return ctx;
}

bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) {
    if(!wglDeleteContext(ctx)) {
        DWORD err = GetLastError();
        return false;
    }
    return true;
}


HDC getSurfaceDC(EGLNativeDisplayType dpy,EglSurface* srfc){
    switch(srfc->type()){
    case EglSurface::WINDOW:
        return GetDC(static_cast<EGLNativeWindowType>(srfc->native()));
    case EglSurface::PBUFFER:
        if(!s_wglExtProcs->wglGetPbufferDCARB) return NULL;
        return s_wglExtProcs->wglGetPbufferDCARB(static_cast<EGLNativePbufferType>(srfc->native()));
    case EglSurface::PIXMAP: //not supported;
    default:
        return NULL;
    }
}

bool releaseSurfaceDC(EGLNativeDisplayType dpy,HDC dc,EglSurface*srfc){
    if(!srfc) return true;
    switch(srfc->type()){
    case EglSurface::WINDOW:
         ReleaseDC(static_cast<EGLNativeWindowType>(srfc->native()),dc);
         return true;
    case EglSurface::PBUFFER:
        if(!s_wglExtProcs->wglReleasePbufferDCARB) return false;
        s_wglExtProcs->wglReleasePbufferDCARB(static_cast<EGLNativePbufferType>(srfc->native()),dc);
        return true;
    case EglSurface::PIXMAP: //not supported;
    default:
        return false;
    }
}

bool makeCurrent(EGLNativeDisplayType display,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx) {

    HDC hdcRead = read ? getSurfaceDC(display,read):0;
    HDC hdcDraw = draw ? getSurfaceDC(display,draw):0;
    bool retVal = false;


    if(hdcRead == hdcDraw){
            bool ret =  wglMakeCurrent(hdcDraw,ctx);
            return ret;
    } else if (!s_wglExtProcs->wglMakeContextCurrentARB ) {
        return false;
    }
    retVal = s_wglExtProcs->wglMakeContextCurrentARB(hdcDraw,hdcRead,ctx);

    releaseSurfaceDC(display,hdcRead,read);
    releaseSurfaceDC(display,hdcDraw,draw);
    return retVal;
}

void swapBuffers(EGLNativeDisplayType display,EGLNativeWindowType win) {

    HDC dc  = GetDC(win);
    if(!SwapBuffers(dc)) {
        DWORD err = GetLastError();
    }
    ReleaseDC(win,dc);

}


void waitNative(){}

void swapInterval(EGLNativeDisplayType dpy,EGLNativeWindowType win,int interval) {

    if (s_wglExtProcs->wglSwapIntervalEXT){
        s_wglExtProcs->wglSwapIntervalEXT(interval);
    }
}

};
