//-----------------------------------------------------------------------------
int vlWin32::choosePixelFormat(const vl::OpenGLContextFormat& fmt, bool verbose)
{
    if (!registerClass())
        return false;

    // this is true only under Win32
    // VL_CHECK( sizeof(wchar_t) == sizeof(short int) )

    HWND hWnd = CreateWindowEx(
                    WS_EX_APPWINDOW | WS_EX_ACCEPTFILES,
                    gWin32WindowClassName,
                    L"Temp GL Window",
                    WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                    NULL, NULL, GetModuleHandle(NULL), NULL);

    if (!hWnd)
    {
        if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create window.", L"Visualization Library error", MB_OK);
        return -1;
    }

    HDC hDC = GetDC(hWnd);
    if (!hDC)
    {
        if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create HDC.", L"Visualization Library error", MB_OK);
        DestroyWindow(hWnd);
        return -1;
    }

    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(pfd));
    pfd.nSize           = sizeof(pfd);
    pfd.nVersion        = 1;
    pfd.dwFlags         = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
    pfd.dwFlags         |= fmt.doubleBuffer() ? PFD_DOUBLEBUFFER : 0;
    pfd.dwFlags         |= fmt.stereo() ? PFD_STEREO : 0;
    pfd.iPixelType      = PFD_TYPE_RGBA;
    pfd.cColorBits      = 0;
    pfd.cRedBits        = (BYTE)fmt.rgbaBits().r();
    pfd.cGreenBits      = (BYTE)fmt.rgbaBits().g();
    pfd.cBlueBits       = (BYTE)fmt.rgbaBits().b();
    pfd.cAlphaBits      = (BYTE)fmt.rgbaBits().a();
    pfd.cAccumRedBits   = (BYTE)fmt.accumRGBABits().r();
    pfd.cAccumGreenBits = (BYTE)fmt.accumRGBABits().g();
    pfd.cAccumBlueBits  = (BYTE)fmt.accumRGBABits().b();
    pfd.cAccumAlphaBits = (BYTE)fmt.accumRGBABits().a();
    pfd.cDepthBits      = (BYTE)fmt.depthBufferBits();
    pfd.cStencilBits    = (BYTE)fmt.stencilBufferBits();
    pfd.iLayerType      = PFD_MAIN_PLANE;

    int pixel_format_index = ChoosePixelFormat(hDC, &pfd);

    if (pixel_format_index == 0)
    {
        if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not choose temporary format.", L"Visualization Library error", MB_OK);
        DeleteDC(hDC);
        DestroyWindow(hWnd);
        return -1;
    }

    if (SetPixelFormat(hDC, pixel_format_index, &pfd) == FALSE)
    {
        if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not set temporary format.", L"Visualization Library error", MB_OK);
        DeleteDC(hDC);
        DestroyWindow(hWnd);
        return -1;
    }

    // OpenGL Rendering Context
    HGLRC hGLRC = wglCreateContext(hDC);
    if (!hGLRC)
    {
        if (verbose) MessageBox(NULL, L"choosePixelFormat() critical failure: could not create temporary OpenGL context.", L"Visualization Library error", MB_OK);
        DeleteDC(hDC);
        DestroyWindow(hWnd);
        return -1;
    }

    wglMakeCurrent(hDC, hGLRC);

    if (!initializeOpenGL())
    {
        fprintf(stderr, "Error initializing OpenGL!\n");
        DeleteDC(hDC);
        DestroyWindow(hWnd);
        return -1;
    }

    // if this is not supported we use the current 'pixel_format_index' returned by ChoosePixelFormat above.

    int samples = 0;
    if(Has_WGL_ARB_pixel_format && fmt.multisample())
    {
        float fAttributes[] = { 0, 0 };
        int iAttributes[] =
        {
            // multi sampling
            WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
            WGL_SAMPLES_ARB,        -1, // this is set below
            // generic
            WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
            WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
            WGL_ACCELERATION_ARB,   WGL_FULL_ACCELERATION_ARB,
            // color buffer
            WGL_RED_BITS_ARB,         pfd.cRedBits,
            WGL_GREEN_BITS_ARB,       pfd.cGreenBits,
            WGL_BLUE_BITS_ARB,        pfd.cBlueBits,
            WGL_ALPHA_BITS_ARB,       pfd.cAlphaBits,
            // accumulation buffer
            WGL_ACCUM_RED_BITS_ARB,   pfd.cAccumRedBits,
            WGL_ACCUM_GREEN_BITS_ARB, pfd.cAccumGreenBits,
            WGL_ACCUM_BLUE_BITS_ARB,  pfd.cAccumBlueBits,
            WGL_ACCUM_ALPHA_BITS_ARB, pfd.cAccumAlphaBits,
            // depth buffer
            WGL_DEPTH_BITS_ARB,       pfd.cDepthBits,
            WGL_DOUBLE_BUFFER_ARB,    fmt.doubleBuffer() ? GL_TRUE : GL_FALSE,
            // stencil buffer
            WGL_STENCIL_BITS_ARB,     pfd.cStencilBits,
            // stereo
            WGL_STEREO_ARB,           fmt.stereo() ? GL_TRUE : GL_FALSE,
            0,0
        };

        for(samples = fmt.multisampleSamples(); samples > 1; samples/=2)
        {
            // sets WGL_SAMPLES_ARB value
            iAttributes[3] = samples;
            pixel_format_index = -1;
            UINT num_formats  = 0;
            if ( wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixel_format_index,&num_formats) && num_formats >= 1 )
                break;
            else
                pixel_format_index = -1;
        }
    }

    // destroy temporary HWND, HDC, HGLRC
    if ( wglDeleteContext(hGLRC) == FALSE )
        if (verbose) MessageBox(NULL, L"Error deleting temporary OpenGL context, wglDeleteContext(hGLRC) failed.", L"Visualization Library error", MB_OK);
    DeleteDC(hDC);
    DestroyWindow(hWnd);

    if (verbose)
    {
        if(pixel_format_index == -1)
            vl::Log::error("No suitable pixel format found.\n");
        else
        {
            // check the returned pixel format
#if defined(DEBUG) || !defined(NDEBUG)
            DescribePixelFormat(hDC, pixel_format_index, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
            vl::Log::debug(" --- vlWin32::choosePixelFormat() ---\n");
            // This one returns "not supported" even when its supported...
            // vl::Log::print( vl::Say("  OpenGL        = %s\n") << (pfd.dwFlags & PFD_SUPPORT_OPENGL ? "Supported" : "Not supported") );
            vl::Log::debug( vl::Say("RGBA Bits     = %n %n %n %n\n") << pfd.cRedBits << pfd.cGreenBits << pfd.cBlueBits << pfd.cAlphaBits);
            vl::Log::debug( vl::Say("Depth Bits    = %n\n")  << pfd.cDepthBits );
            vl::Log::debug( vl::Say("Stencil Bits  = %n \n") << pfd.cStencilBits);
            vl::Log::debug( vl::Say("Double Buffer = %s\n")  << (pfd.dwFlags & PFD_DOUBLEBUFFER ? "Yes" : "No") );
            vl::Log::debug( vl::Say("Stereo        = %s\n")  << (pfd.dwFlags & PFD_STEREO ? "Yes" : "No") );
            vl::Log::debug( vl::Say("Samples       = %n\n")  << samples );
            vl::Log::debug("\n");
#endif
        }
    }

    return pixel_format_index;
}
//-----------------------------------------------------------------------------
bool SDLWindow::initSDLWindow(const vl::String& title, const vl::OpenGLContextFormat& info, int x, int y, int width, int height)
{
  if (mScreen || mSDLWindow)
  {
    vl::Log::error("SDL supports only one window at a time.\n");
    VL_TRAP();
    return false;
  }

  framebuffer()->setWidth(width);
  framebuffer()->setHeight(height);
  mSDLWindow = this;

  // init key translation map
  for(int i=0; key_translation_vec[i]; i+=2)
    key_translation_map[ key_translation_vec[i] ] = (vl::EKey)key_translation_vec[i+1];

  // SDL_VIDEO_WINDOW_POS

  char win_pos[32] = {0};
  sprintf ( win_pos, "SDL_VIDEO_WINDOW_POS=%d,%d", x, y );
  SDL_putenv(win_pos);
  // setenv("SDL_VIDEO_CENTERED", "YES", 0);

  // init SDL

  if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
	{
    printf("Unable to init SDL: %s\n", SDL_GetError());
    return false;
  }

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   info.rgbaBits().r());
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, info.rgbaBits().g());
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  info.rgbaBits().b());
  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, info.rgbaBits().a());

  SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,   info.accumRGBABits().r());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, info.accumRGBABits().g());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,  info.accumRGBABits().b());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, info.accumRGBABits().a());

  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, info.depthBufferBits());
  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, info.stencilBufferBits());

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, info.doubleBuffer()?1:0);
  SDL_GL_SetAttribute(SDL_GL_STEREO, info.stereo());
  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, info.multisample()?1:0);
  if (info.multisample())
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info.multisampleSamples());
  SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, info.vSync());

  int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
  Uint32 flags = SDL_OPENGL | (info.fullscreen() ? SDL_FULLSCREEN : 0);
  width  = width  !=0 ? width  : SDL_GetVideoInfo()->current_w;
  height = height !=0 ? height : SDL_GetVideoInfo()->current_h;
  mScreen = SDL_SetVideoMode( width, height, bpp, flags );
  if (mScreen == 0)
  {
    vl::Log::print( vl::Say("\n  error: SDL_SetVideoMode(%n, %n, %n, %hn) failed: %s\n") << width << height << bpp << flags << SDL_GetError() );
    exit(1);
  }

  // window size problem

  int viewport[4];
  glGetIntegerv(GL_VIEWPORT,  viewport);
  VL_CHECK(viewport[0] == 0);
  VL_CHECK(viewport[1] == 0);
  if (viewport[2] != mScreen->w || viewport[3] != mScreen->h)
  {
    vl::Log::print( vl::Say("\n  warning: OpenGL reported %nx%n as video size but SDL says %nx%n\n") << viewport[2] << viewport[3] << mScreen->w << mScreen->h );
    VL_TRAP()
  }