#include "X11OpenGLWindow.h"
#include "OpenGLInclude.h"

#include<stdio.h>
#include<stdlib.h>
#ifdef GLEW_STATIC
#include "CustomGL/glew.h"
#else
#include <GL/glew.h>
#endif//GLEW_STATIC

#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
#include "CustomGL/glxew.h"
#else
#include<GL/glx.h>
#endif // GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
#include <assert.h>

//#define DYNAMIC_LOAD_X11_FUNCTIONS
#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
#include <dlfcn.h>
#endif //DYNAMIC_LOAD_X11_FUNCTIONS

//#include<X11/X.h>
//#include<X11/Xlib.h>
//#include<GL/gl.h>

//defined in GL/glxew.h
//#include<GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <pthread.h>

GLint                   att[] = { GLX_RGBA,
GLX_DEPTH_SIZE, 24,
GLX_RED_SIZE        , 8,
GLX_GREEN_SIZE      , 8,
GLX_BLUE_SIZE       , 8,
GLX_ALPHA_SIZE      , 8,
GLX_STENCIL_SIZE    , 8,
GLX_DOUBLEBUFFER,
None };
/*
 static int att[] =
            {
                GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None

              GLX_X_RENDERABLE    , True,
              GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
              GLX_RENDER_TYPE     , GLX_RGBA_BIT,
              GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
              GLX_RED_SIZE        , 8,
              GLX_GREEN_SIZE      , 8,
              GLX_BLUE_SIZE       , 8,
              GLX_ALPHA_SIZE      , 8,
              GLX_DEPTH_SIZE      , 24,
              GLX_STENCIL_SIZE    , 8,
              GLX_DOUBLEBUFFER    , True,
              None
            };
*/
static bool forceOpenGL3 = true;



#ifdef DYNAMIC_LOAD_X11_FUNCTIONS

///our X11 function typedefs

typedef int (*PFNXFREE)(void*);
typedef XErrorHandler (* PFNXSETERRORHANDLER) (XErrorHandler);
typedef int (* PFNXSYNC) (Display* a,Bool b);
typedef Display* (* PFNXOPENDISPLAY) (_Xconst char* a);
typedef Colormap (*PFNXCREATECOLORMAP) (Display* a,Window b,Visual* c,int d);
typedef Window (*PFNXCREATEWINDOW) (Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l);
typedef int (*PFNXMAPWINDOW) (Display*, Window);
typedef int (*PFNXSTORENAME) (Display* a,Window b,_Xconst char* c);
typedef int (*PFNXCLOSEDISPLAY) (Display* a);
typedef int (*PFNXDESTROYWINDOW) (Display* a,Window b);
typedef int (*PFNXRAISEWINDOW) (Display* a, Window b);

#if NeedWidePrototypes
	typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,unsigned int,int,int*);
	typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,unsigned int b,int c);
#else
	typedef KeySym* (*PFNXGETKEYBOARDMAPPING) (Display*,KeyCode,int,int*);
	typedef KeySym (*PFNXKEYCODETOKEYSYM) (Display* a,KeyCode b,int c);
#endif
typedef void	(*PFNXCONVERTCASE) (KeySym /* sym */,KeySym *		/* lower */,KeySym * /* upper */);
typedef int (*PFNXPENDING) (Display* a);
typedef int (*PFNXNEXTEVENT) (Display* a,XEvent* b);
typedef int (*PFNXEVENTSQUEUED) (Display* a,int b);
typedef int (*PFNXPEEKEVENT) (Display* a,XEvent* b);
typedef KeySym (*PFNXLOOKUPKEYSYM) (XKeyEvent* a,int b);
typedef Status (*PFNXGETWINDOWATTRIBUTES) (Display* a,Window b,XWindowAttributes* c);

#define X11_LIBRARY "libX11.so.6"

#define MyXSync m_data->m_x11_XSync
#define MyXGetKeyboardMapping m_data->m_x11_XGetKeyboardMapping
#define MyXSetErrorHandler m_data->m_x11_XSetErrorHandler
#define MyXOpenDisplay m_data->m_x11_XOpenDisplay
#define MyXCreateColormap m_data->m_x11_XCreateColormap
#define MyXCreateWindow m_data->m_x11_XCreateWindow
#define MyXMapWindow m_data->m_x11_XMapWindow
#define MyXStoreName m_data->m_x11_XStoreName
#define MyXDestroyWindow m_data->m_x11_XDestroyWindow
#define MyXRaiseWindow m_data->m_x11_XRaiseWindow
#define MyXCloseDisplay m_data->m_x11_XCloseDisplay
#define MyXKeycodeToKeysym m_data->m_x11_XKeycodeToKeysym
#define MyXConvertCase m_data->m_x11_XConvertCase
#define MyXPending m_data->m_x11_XPending
#define MyXNextEvent m_data->m_x11_XNextEvent
#define MyXEventsQueued m_data->m_x11_XEventsQueued
#define MyXPeekEvent m_data->m_x11_XPeekEvent
#define MyXNextEvent m_data->m_x11_XNextEvent
#define MyXGetWindowAttributes m_data->m_x11_XGetWindowAttributes
#define MyXStoreName m_data->m_x11_XStoreName
#define MyXFree m_data->m_x11_XFree
#define MyXMapWindow m_data->m_x11_XMapWindow
#define MyXStoreName m_data->m_x11_XStoreName
#define MyXLookupKeysym m_data->m_x11_XLookupKeysym

#else
#define MyXSync XSync
#define MyXGetKeyboardMapping XGetKeyboardMapping
#define MyXSetErrorHandler XSetErrorHandler
#define MyXOpenDisplay XOpenDisplay
#define MyXCreateColormap XCreateColormap
#define MyXCreateWindow XCreateWindow
#define MyXMapWindow XMapWindow
#define MyXStoreName XStoreName
#define MyXDestroyWindow XDestroyWindow
#define MyXRaiseWindow XRaiseWindow
#define MyXCloseDisplay XCloseDisplay
#define MyXKeycodeToKeysym XKeycodeToKeysym
#define MyXConvertCase XConvertCase
#define MyXPending XPending
#define MyXNextEvent XNextEvent
#define MyXEventsQueued XEventsQueued
#define MyXPeekEvent XPeekEvent
#define MyXNextEvent XNextEvent
#define MyXGetWindowAttributes XGetWindowAttributes
#define MyXStoreName XStoreName
#define MyXFree XFree
#define MyXMapWindow XMapWindow
#define MyXStoreName XStoreName
#define MyXLookupKeysym XLookupKeysym

#endif//DYNAMIC_LOAD_X11_FUNCTIONS

enum
{
	MY_X11_ALT_KEY = 1,
	MY_X11_SHIFT_KEY = 2,
	MY_X11_CONTROL_KEY = 4
};

struct InternalData2
{
    Display*                m_dpy;
    Window                  m_root;
    XVisualInfo*            m_vi;
    Colormap                m_cmap;
    XSetWindowAttributes    m_swa;
    Window                  m_win;
    GLXContext              m_glc;
    XWindowAttributes       m_gwa;
    XEvent                  m_xev;
    GLXFBConfig             m_bestFbc;
    int			    m_modifierFlags;
    int			    m_glWidth;
    int			    m_glHeight;

#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
	//dynamically load stuff
	void*									m_x11_library;
	PFNXFREE							m_x11_XFree;
	PFNXSETERRORHANDLER		m_x11_XSetErrorHandler;
	PFNXSYNC							m_x11_XSync;
	PFNXOPENDISPLAY				m_x11_XOpenDisplay;
	PFNXCREATECOLORMAP		m_x11_XCreateColormap;
	PFNXCREATEWINDOW			m_x11_XCreateWindow;
	PFNXMAPWINDOW					m_x11_XMapWindow;
	PFNXSTORENAME					m_x11_XStoreName;
	PFNXCLOSEDISPLAY			m_x11_XCloseDisplay;
	PFNXDESTROYWINDOW			m_x11_XDestroyWindow;
	PFNXRAISEWINDOW				m_x11_XRaiseWindow;
	PFNXKEYCODETOKEYSYM		m_x11_XKeycodeToKeysym;
	PFNXGETKEYBOARDMAPPING m_x11_XGetKeyboardMapping;
	PFNXCONVERTCASE				m_x11_XConvertCase;
	PFNXPENDING						m_x11_XPending;
	PFNXNEXTEVENT					m_x11_XNextEvent;
	PFNXEVENTSQUEUED			m_x11_XEventsQueued;
	PFNXPEEKEVENT					m_x11_XPeekEvent;
	PFNXLOOKUPKEYSYM			m_x11_XLookupKeysym;
	PFNXGETWINDOWATTRIBUTES m_x11_XGetWindowAttributes;
#endif //DYNAMIC_LOAD_X11_FUNCTIONS

	b3WheelCallback m_wheelCallback;
	b3MouseMoveCallback	m_mouseMoveCallback;
	b3MouseButtonCallback	m_mouseButtonCallback;
	b3ResizeCallback		m_resizeCallback;
	b3KeyboardCallback	m_keyboardCallback;

	InternalData2()
	:m_dpy(0),
	m_vi(0),
	m_modifierFlags(0),
	m_glWidth(-1),
	m_glHeight(-1),
	m_wheelCallback(0),
	m_mouseMoveCallback(0),
	m_mouseButtonCallback(0),
	m_resizeCallback(0),
	m_keyboardCallback(0)
	{
#ifdef DYNAMIC_LOAD_X11_FUNCTIONS
		 m_x11_library = dlopen(X11_LIBRARY, RTLD_LOCAL | RTLD_NOW);
		 if (!m_x11_library)
		{
			printf("Error opening X11 library %s\n", X11_LIBRARY);
			exit(0);
		}

		bool missingFunc = false;

		missingFunc = ((m_x11_XFree = (PFNXFREE)  dlsym(m_x11_library, "XFree"))==NULL) | missingFunc;
		assert(!missingFunc);
		if (missingFunc)		{ printf("Error: missing func XFree in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XSetErrorHandler = (PFNXSETERRORHANDLER) dlsym(m_x11_library,"XSetErrorHandler"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XSetErrorHandler in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XSync = (PFNXSYNC) dlsym(m_x11_library,"XSync"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XSync in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XOpenDisplay = (PFNXOPENDISPLAY) dlsym(m_x11_library,"XOpenDisplay"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XCreateColormap = (PFNXCREATECOLORMAP) dlsym(m_x11_library,"XCreateColormap"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XCreateColormap in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XCreateWindow = (PFNXCREATEWINDOW) dlsym(m_x11_library,"XCreateWindow"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XCreateWindow in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XMapWindow = (PFNXMAPWINDOW) dlsym(m_x11_library,"XMapWindow"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XMapWindow in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XStoreName = (PFNXSTORENAME) dlsym(m_x11_library,"XStoreName"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XStoreName in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XCloseDisplay = (PFNXCLOSEDISPLAY) dlsym(m_x11_library,"XCloseDisplay"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XCloseDisplay in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XDestroyWindow = (PFNXDESTROYWINDOW) dlsym(m_x11_library,"XDestroyWindow"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XDestroyWindow in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XRaiseWindow = (PFNXRAISEWINDOW) dlsym(m_x11_library,"XRaiseWindow"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XRaiseWindow in %s, exiting!\n", X11_LIBRARY);	exit(0);}

		missingFunc = ((m_x11_XGetKeyboardMapping = (PFNXGETKEYBOARDMAPPING) dlsym(m_x11_library,"XGetKeyboardMapping"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XGetKeyboardMapping in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XKeycodeToKeysym = (PFNXKEYCODETOKEYSYM) dlsym(m_x11_library,"XKeycodeToKeysym"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XKeycodeToKeysym in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XConvertCase = (PFNXCONVERTCASE) dlsym(m_x11_library,"XConvertCase"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XConvertCase in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XPending = (PFNXPENDING) dlsym(m_x11_library,"XPending"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XPending in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XNextEvent = (PFNXNEXTEVENT) dlsym(m_x11_library,"XNextEvent"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XNextEvent in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XEventsQueued = (PFNXEVENTSQUEUED) dlsym(m_x11_library,"XEventsQueued"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XEventsQueued in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XPeekEvent = (PFNXPEEKEVENT) dlsym(m_x11_library,"XPeekEvent"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XPeekEvent in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XLookupKeysym = (PFNXLOOKUPKEYSYM) dlsym(m_x11_library,"XLookupKeysym"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XLookupKeysym in %s, exiting!\n", X11_LIBRARY);	exit(0);}
		missingFunc = ((m_x11_XGetWindowAttributes = (PFNXGETWINDOWATTRIBUTES) dlsym(m_x11_library,"XGetWindowAttributes"))==NULL) | missingFunc;
		if (missingFunc)		{ printf("Error: missing func XGetWindowAttributes in %s, exiting!\n", X11_LIBRARY);	exit(0);}

		if (missingFunc)
		{
			printf("Error: a missing func in %s, exiting!\n", X11_LIBRARY);
			exit(0);
		} else
		{
			printf("X11 functions dynamically loaded using dlopen/dlsym OK!\n");
		}
#endif //DYNAMIC_LOAD_X11_FUNCTIONS
	}
};

#define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);

// Helper to check for extension string presence.  Adapted from:
//   http://www.opengl.org/resources/features/OGLextensions/
static bool isExtensionSupported(const char *extList, const char *extension)
{
  const char *start;
  const char *where, *terminator;

  /* Extension names should not have spaces. */
  where = strchr(extension, ' ');
  if (where || *extension == '\0')
    return false;

  /* It takes a bit of care to be fool-proof about parsing the
     OpenGL extensions string. Don't be fooled by sub-strings,
     etc. */
  for (start=extList;;) {
    where = strstr(start, extension);

    if (!where)
      break;

    terminator = where + strlen(extension);

    if ( where == start || *(where - 1) == ' ' )
      if ( *terminator == ' ' || *terminator == '\0' )
        return true;

    start = terminator;
  }

  return false;
}

static bool ctxErrorOccurred = false;
static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
{
    ctxErrorOccurred = true;
    return 0;
}




X11OpenGLWindow::X11OpenGLWindow()
:m_OpenGLInitialized(false),
m_requestedExit(false)
{
    m_data = new InternalData2;
}

X11OpenGLWindow::~X11OpenGLWindow()
{
    if (m_OpenGLInitialized)
    {
        disableOpenGL();
    }

    delete m_data;
}



void X11OpenGLWindow::enableOpenGL()
{


    if (forceOpenGL3)
    {
 // Get the default screen's GLX extension list
  const char *glxExts = glXQueryExtensionsString( m_data->m_dpy,
                                                  DefaultScreen( m_data->m_dpy ) );

  // NOTE: It is not necessary to create or make current to a context before
  // calling glXGetProcAddressARB, unless we dynamically load OpenGL/GLX/X11

  glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
  glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
           glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );

  GLXContext ctx = 0;

  // Install an X error handler so the application won't exit if GL 3.0
  // context allocation fails.
  //
  // Note this error handler is global.  All display connections in all threads
  // of a process use the same error handler, so be sure to guard against other
  // threads issuing X commands while this code is running.
  ctxErrorOccurred = false;
  int (*oldHandler)(Display*, XErrorEvent*) =
         MyXSetErrorHandler(&ctxErrorHandler);

  // Check for the GLX_ARB_create_context extension string and the function.
  // If either is not present, use GLX 1.3 context creation method.
  if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) ||
       !glXCreateContextAttribsARB )
  {
    printf( "glXCreateContextAttribsARB() not found"
            " ... using old-style GLX context\n" );
    ctx = glXCreateNewContext( m_data->m_dpy, m_data->m_bestFbc, GLX_RGBA_TYPE, 0, True );
  }

  // If it does, try to get a GL 3.0 context!
  else
  {
	 int context_attribs[] = {
          GLX_CONTEXT_MAJOR_VERSION_ARB ,3,
          GLX_CONTEXT_MINOR_VERSION_ARB, 2,
          GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
          GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,None
     };
/*
    int context_attribs[] =
      {
        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
        GLX_CONTEXT_MINOR_VERSION_ARB, 2,

        //GLX_CONTEXT_FLAGS_ARB        , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
        None
      };
*/
    printf( "Creating context\n" );
    ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
                                      True, context_attribs );

    // Sync to ensure any errors generated are processed.
    MyXSync( m_data->m_dpy, False );
    if ( !ctxErrorOccurred && ctx )
      printf( "Created GL 3.0 context\n" );
    else
    {
      // Couldn't create GL 3.0 context.  Fall back to old-style 2.x context.
      // When a context version below 3.0 is requested, implementations will
      // return the newest context version compatible with OpenGL versions less
      // than version 3.0.
      // GLX_CONTEXT_MAJOR_VERSION_ARB = 1
      context_attribs[1] = 1;
      // GLX_CONTEXT_MINOR_VERSION_ARB = 0
      context_attribs[3] = 0;

      ctxErrorOccurred = false;

      printf( "Failed to create GL 3.0 context"
              " ... using old-style GLX context\n" );
      ctx = glXCreateContextAttribsARB( m_data->m_dpy, m_data->m_bestFbc, 0,
                                        True, context_attribs );
    }
  }

  // Sync to ensure any errors generated are processed.
  MyXSync( m_data->m_dpy, False );

  // Restore the original error handler
  MyXSetErrorHandler( oldHandler );

  if ( ctxErrorOccurred || !ctx )
  {
    printf( "Failed to create an OpenGL context\n" );
    exit(1);
  }

  // Verifying that context is a direct context
  if ( ! glXIsDirect ( m_data->m_dpy, ctx ) )
  {
    printf( "Indirect GLX rendering context obtained\n" );
  }
  else
  {
    printf( "Direct GLX rendering context obtained\n" );
  }

  printf( "Making context current\n" );
  glXMakeCurrent( m_data->m_dpy, m_data->m_win, ctx );
  m_data->m_glc = ctx;

    } else
    {
        m_data->m_glc = glXCreateContext(m_data->m_dpy, m_data->m_vi, NULL, GL_TRUE);
        glXMakeCurrent(m_data->m_dpy, m_data->m_win, m_data->m_glc);
    }

#ifdef GLEW_INIT_OPENGL11_FUNCTIONS
{
	GLboolean res = glewOpenGL11Init();
	if (res==0)
		{
			printf("glewOpenGL11Init OK!\n");
		} else
			{
				printf("ERROR: glewOpenGL11Init failed, exiting!\n");
				exit(0);
			}
}

#endif //GLEW_INIT_OPENGL11_FUNCTIONS

    const GLubyte* ven = glGetString(GL_VENDOR);
    printf("GL_VENDOR=%s\n", ven);

    const GLubyte* ren = glGetString(GL_RENDERER);
    printf("GL_RENDERER=%s\n",ren);
    const GLubyte* ver = glGetString(GL_VERSION);
    printf("GL_VERSION=%s\n", ver);
    const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
    printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);

//Access pthreads as a workaround for a bug in Linux/Ubuntu
//See https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642

	int i=pthread_getconcurrency();
        printf("pthread_getconcurrency()=%d\n",i);

//    const GLubyte* ext = glGetString(GL_EXTENSIONS);
//    printf("GL_EXTENSIONS=%s\n", ext);
}

void X11OpenGLWindow::disableOpenGL()
{
    glXMakeCurrent(m_data->m_dpy, None, NULL);
 	glXDestroyContext(m_data->m_dpy, m_data->m_glc);
}


void    X11OpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
{

    m_data->m_dpy = MyXOpenDisplay(NULL);

    if(m_data->m_dpy == NULL) {
        printf("\n\tcannot connect to X server\n\n");
            exit(0);
     }

    m_data->m_root = DefaultRootWindow(m_data->m_dpy);


#ifdef GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS
GLboolean res = glewXInit();
if (res==0)
{
	printf("glewXInit OK\n");
} else
{
	printf("glewXInit failed, exit\n");
	exit(0);
}
#endif //GLEW_DYNAMIC_LOAD_ALL_GLX_FUNCTIONS


    if (ci.m_openglVersion < 3)
    {
        forceOpenGL3 = false;
    }

    if (forceOpenGL3)
    {
        int glxMinor, glxMajor;
        if (!glXQueryVersion(m_data->m_dpy,&glxMajor,&glxMinor) || (((glxMajor==1)&&(glxMinor<3)) || (glxMajor<1)))
        {
            printf("Invalid GLX version: major %d, minor %d\n",glxMajor,glxMinor);
            exit(0);
        }

        static int visual_attribs[] =
            {
              GLX_X_RENDERABLE    , True,
              GLX_DRAWABLE_TYPE   , GLX_WINDOW_BIT,
              GLX_RENDER_TYPE     , GLX_RGBA_BIT,
              GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
              GLX_RED_SIZE        , 8,
              GLX_GREEN_SIZE      , 8,
              GLX_BLUE_SIZE       , 8,
              GLX_ALPHA_SIZE      , 8,
              GLX_DEPTH_SIZE      , 24,
              GLX_STENCIL_SIZE    , 8,
              GLX_DOUBLEBUFFER    , True,
              None
            };
            int fbcount;
            GLXFBConfig* fbc = glXChooseFBConfig(m_data->m_dpy, DefaultScreen(m_data->m_dpy), visual_attribs, &fbcount);
            if (!fbc)
            {
                printf( "Failed to retrieve a framebuffer config\n" );
                exit(1);
            }
///don't use highest samples, it is really slow on some NVIDIA Quadro cards
#ifdef USE_HIGHEST_SAMPLES
            int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;

            int i;
            for (i=0; i<fbcount; ++i)
            {
	            XVisualInfo *vi = glXGetVisualFromFBConfig( m_data->m_dpy, fbc[i] );
	            if ( vi )
	            {
	              int samp_buf, samples;
	              glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
	              glXGetFBConfigAttrib( m_data->m_dpy, fbc[i], GLX_SAMPLES       , &samples  );

	              //printf( "  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
	               //       " SAMPLES = %d\n",
	                //      i, vi -> visualid, samp_buf, samples );

	              if ( best_fbc < 0 || (samp_buf && (samples > best_num_samp)) )
	                best_fbc = i, best_num_samp = samples;
	              if ( worst_fbc < 0 || (!samp_buf || (samples < worst_num_samp)) )
	                worst_fbc = i, worst_num_samp = samples;
	            }
	            MyXFree( vi );
            }

            m_data->m_bestFbc = fbc[ best_fbc ];
#else
	    m_data->m_bestFbc = *fbc;
#endif
            // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
            MyXFree( fbc );

            m_data->m_vi = glXGetVisualFromFBConfig( m_data->m_dpy, m_data->m_bestFbc );


            m_data->m_swa.colormap = m_data->m_cmap = MyXCreateColormap( m_data->m_dpy,
                                                 RootWindow( m_data->m_dpy, m_data->m_vi->screen ),
                                                 m_data->m_vi->visual, AllocNone );
            m_data->m_swa.background_pixmap = None ;
            m_data->m_swa.border_pixel      = 0;
            m_data->m_swa.event_mask        = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
;
            m_data->m_root =  RootWindow( m_data->m_dpy, m_data->m_vi->screen );

            m_data->m_win = MyXCreateWindow( m_data->m_dpy, m_data->m_root,
                                      0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput,
                                      m_data->m_vi->visual,
                                      CWBorderPixel|CWColormap|CWEventMask, &m_data->m_swa );

            //m_data->m_win = m_data->m_x11_XCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);


            if (!m_data->m_win)
            {
                printf("Cannot create window\n");
                exit(0);
            }

            MyXMapWindow(m_data->m_dpy, m_data->m_win);
            MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL3 Window");


    } else
    {
         m_data->m_vi = glXChooseVisual(m_data->m_dpy, 0, att);

				printf("4\n");

         if(m_data->m_vi == NULL) {
            printf("\n\tno appropriate visual found\n\n");
                exit(0);
         }
         else {
            printf("\n\tvisual %p selected\n", (void *)m_data->m_vi->visualid); /* %p creates hexadecimal output like in glxinfo */
         }


         m_data->m_cmap = MyXCreateColormap(m_data->m_dpy, m_data->m_root, m_data->m_vi->visual, AllocNone);
         m_data->m_swa.colormap = m_data->m_cmap;
         m_data->m_swa.event_mask = ExposureMask | KeyReleaseMask | KeyPressMask |ButtonPressMask | ButtonReleaseMask |PointerMotionMask|StructureNotifyMask;
         m_data->m_win = MyXCreateWindow(m_data->m_dpy, m_data->m_root, 0, 0, ci.m_width, ci.m_height, 0, m_data->m_vi->depth, InputOutput, m_data->m_vi->visual, CWColormap | CWEventMask, &m_data->m_swa);

         MyXMapWindow(m_data->m_dpy, m_data->m_win);

         MyXStoreName(m_data->m_dpy, m_data->m_win, "OpenGL2 Window");


    }

    enableOpenGL();
}

void    X11OpenGLWindow::closeWindow()
{
    disableOpenGL();

    MyXDestroyWindow(m_data->m_dpy, m_data->m_win);
    MyXCloseDisplay(m_data->m_dpy);
}

int X11OpenGLWindow::getAsciiCodeFromVirtualKeycode(int keycode)
{
    int result = 0;

    KeySym key, key_lc, key_uc;

    int keysyms_per_keycode_return;
    KeySym *keysym = MyXGetKeyboardMapping(m_data->m_dpy,
        keycode,
        1,
        &keysyms_per_keycode_return);

    key = keysym[0];


    //key = MyXKeycodeToKeysym( m_data->m_dpy, keycode, 0 );

    switch( key )
    {
        case XK_Escape:       return B3G_ESCAPE;
        case XK_Return:       return B3G_RETURN;
        case XK_BackSpace:    return B3G_BACKSPACE;
        case XK_Delete:       return B3G_DELETE;
        case XK_Tab:       	  return 9;

	case XK_Control_L:
	case XK_Control_R:     {
			return B3G_CONTROL;
            }
    case XK_Left: return B3G_LEFT_ARROW;
    case XK_Right: return B3G_RIGHT_ARROW;
    case XK_Up: return B3G_UP_ARROW;
    case XK_Down: return B3G_DOWN_ARROW;

	case XK_Alt_L:
	case XK_Alt_R:
		{
		  return B3G_ALT;
		}
	case XK_Shift_L:
	case XK_Shift_R:	      return B3G_SHIFT;
        case XK_F1:           return B3G_F1;
        case XK_F2:           return B3G_F2;
        case XK_F3:           return B3G_F3;
        case XK_F4:           return B3G_F4;
        case XK_F5:           return B3G_F5;
        case XK_F6:           return B3G_F6;
        case XK_F7:           return B3G_F7;
        case XK_F8:           return B3G_F8;
        case XK_F9:           return B3G_F9;
        case XK_F10:          return B3G_F10;
        case XK_F11:          return B3G_F11;
        case XK_F12:          return B3G_F12;
        case XK_F13:          return B3G_F13;
        case XK_F14:          return B3G_F14;
        case XK_F15:          return B3G_F15;
        default:
	// Make lowercase
            MyXConvertCase( key, &key_lc, &key_uc );
            key = key_lc;
            // Valid ISO 8859-1 character?
            if( (key >=  32 && key <= 126) ||(key >= 160 && key <= 255) )
            {
                return (int) key;
            }
            result = -1;
    }

    MyXFree(keysym);

    return result;
}

bool    X11OpenGLWindow::isModifierKeyPressed(int key)
{
        bool isPressed = false;

        switch (key)
        {
                case B3G_ALT:
                {
                        isPressed = ((m_data->m_modifierFlags & MY_X11_ALT_KEY)!=0);
                        break;
                };
                case B3G_SHIFT:
                {
                        isPressed = ((m_data->m_modifierFlags & MY_X11_SHIFT_KEY)!=0);
                        break;
                };
                case B3G_CONTROL:
                {
                        isPressed = ((m_data->m_modifierFlags & MY_X11_CONTROL_KEY )!=0);
                        break;
                };

                default:
                {
                }
        };
        return isPressed;
}

void X11OpenGLWindow::pumpMessage()
{

    int buttonState = 1;

     // Process all pending events
    while( MyXPending( m_data->m_dpy ) )
    {
        MyXNextEvent(m_data->m_dpy, &m_data->m_xev);
  //      printf("#");
  //      fflush(stdout);
        switch( m_data->m_xev.type )
        {
            case KeyPress:
            {
                    int keycode = getAsciiCodeFromVirtualKeycode(m_data->m_xev.xkey.keycode);
		    switch (keycode)
			{
			case B3G_ALT:
			m_data->m_modifierFlags |= MY_X11_ALT_KEY;
			break;
			case B3G_SHIFT:
			m_data->m_modifierFlags |= MY_X11_SHIFT_KEY;
			break;
			case B3G_CONTROL:
			m_data->m_modifierFlags |= MY_X11_CONTROL_KEY;
			break;
			default:
			{}
			};
		if (m_data->m_keyboardCallback)
                {

                    int state = 1;
                    (*m_data->m_keyboardCallback)(keycode,state);
                //    printf("keycode %d",keycode);
                  //  fflush(stdout);

                }
                break;
            }

            case KeyRelease:
            {
   //           fflush(stdout);
 int keycode = getAsciiCodeFromVirtualKeycode( m_data->m_xev.xkey.keycode);
		  switch (keycode)
                        {
                        case B3G_ALT:
                        m_data->m_modifierFlags &= ~MY_X11_ALT_KEY;
                        break;
                        case B3G_SHIFT:
                        m_data->m_modifierFlags &= ~MY_X11_SHIFT_KEY;
                        break;
                        case B3G_CONTROL:
                        m_data->m_modifierFlags &= ~MY_X11_CONTROL_KEY;
                        break;
                        default:
                        {}
                        };

                if (m_data->m_keyboardCallback)
                {
#if 0
                     unsigned short is_retriggered = 0;
///filter out keyboard repeat
//see http://stackoverflow.com/questions/2100654/ignore-auto-repeat-in-x11-applications
                     if (MyXEventsQueued(m_data->m_dpy, QueuedAfterReading))
                       {
                         XEvent nev;
                         MyXPeekEvent(m_data->m_dpy, &nev);

                         if (nev.type == KeyPress && nev.xkey.time ==  m_data->m_xev.xkey.time &&
                             nev.xkey.keycode ==  m_data->m_xev.xkey.keycode)
                           {
                             fprintf (stdout, "key #%ld was retriggered.\n",
                               (long) MyXLookupKeysym(&nev.xkey, 0));

                             // delete retriggered KeyPress event
                             MyXNextEvent(m_data->m_dpy, & m_data->m_xev);
                             is_retriggered = 1;
                           }
                       }
#endif
                    int state = 0;
                    (*m_data->m_keyboardCallback)(keycode,state);
                    }

                break;
            }

            case ButtonRelease:
                buttonState = 0;
                //continue with ButtonPress code
            case ButtonPress:
            {
//                printf("!");
//                fflush(stdout);

                int button=-1;

                switch (m_data->m_xev.xbutton.button)
                {
                    case Button1:
                    {
                    button=0;
                    break;
                    }
                    case Button2:
                    {
                        button=1;
                        break;
                    }
                    case Button3:
                    {
                        button=2;
                        break;
                    }
                    case Button4:
                    {
                        if (m_data->m_wheelCallback)
                        {
                            (*m_data->m_wheelCallback)(0,10);
                        }
                        break;
                    }
                    case Button5:
                    {
                        if (m_data->m_wheelCallback)
                        {
                            (*m_data->m_wheelCallback)(0,-10);
                        }
                        break;
                    }
                }
                int xpos = m_data->m_xev.xmotion.x;
                int ypos = m_data->m_xev.xmotion.y;

                if (button>=0 && m_data->m_mouseButtonCallback)
                {
//                      printf("xpos = %d, ypos = %d\n",xpos,ypos);

                    (*m_data->m_mouseButtonCallback)(button,buttonState,xpos,ypos);
                }
                break;
            }
            case MotionNotify:
            {
//                printf("!");
//                fflush(0);
                if (m_data->m_mouseMoveCallback)
                {
                    int xpos = m_data->m_xev.xmotion.x;
                    int ypos = m_data->m_xev.xmotion.y;
                    (*m_data->m_mouseMoveCallback)(xpos,ypos);
                }
                break;
            }
            case ConfigureNotify:
            {
  //              printf("@");
  //              fflush(0);
		m_data->m_glWidth = m_data->m_xev.xconfigure.width;
		m_data->m_glHeight = m_data->m_xev.xconfigure.height;

                if (m_data->m_resizeCallback)
                {
                    (*m_data->m_resizeCallback)(m_data->m_xev.xconfigure.width,m_data->m_xev.xconfigure.height);
                }
                break;
            }
            case ClientMessage:
            {
  //              printf("?");
  //              fflush(stdout);
                break;
            }
            case Expose:
            {
                    break;
            }
            case DestroyNotify:
            {
                break;
            }
            default:
            {
                //XRRUpdateConfiguration( &event );
            }
        };
    }
}



void    X11OpenGLWindow::startRendering()
{
	pumpMessage();

    MyXGetWindowAttributes(m_data->m_dpy, m_data->m_win, &m_data->m_gwa);
    glViewport(0, 0, m_data->m_gwa.width, m_data->m_gwa.height);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);	//clear buffers

    //glCullFace(GL_BACK);
    //glFrontFace(GL_CCW);
    glEnable(GL_DEPTH_TEST);
}

void    X11OpenGLWindow::renderAllObjects()
{

}

void    X11OpenGLWindow::endRendering()
{
    glXSwapBuffers(m_data->m_dpy, m_data->m_win);
}

void    X11OpenGLWindow::runMainLoop()
{

}

float   X11OpenGLWindow::getTimeInSeconds()
{
    return 0.f;
}

bool    X11OpenGLWindow::requestedExit() const
{
    return m_requestedExit;
}

void    X11OpenGLWindow::setRequestExit()
{
	m_requestedExit=true;
}

void X11OpenGLWindow::setRenderCallback( b3RenderCallback renderCallback)
{

}

void X11OpenGLWindow::setWindowTitle(const char* title)
{
    MyXStoreName(m_data->m_dpy, m_data->m_win, title);
}


void X11OpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback)
{
	m_data->m_wheelCallback = wheelCallback;
}

void X11OpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback	mouseCallback)
{
	m_data->m_mouseMoveCallback = mouseCallback;
}

void X11OpenGLWindow::setMouseButtonCallback(b3MouseButtonCallback	mouseCallback)
{
	m_data->m_mouseButtonCallback = mouseCallback;
}

void X11OpenGLWindow::setResizeCallback(b3ResizeCallback	resizeCallback)
{
	if (resizeCallback && m_data->m_glWidth>0 && m_data->m_glHeight > 0)
	{
		resizeCallback(m_data->m_glWidth, m_data->m_glHeight);
	}
	m_data->m_resizeCallback = resizeCallback;
}

void X11OpenGLWindow::setKeyboardCallback( b3KeyboardCallback	keyboardCallback)
{
	m_data->m_keyboardCallback = keyboardCallback;

}

b3MouseMoveCallback X11OpenGLWindow::getMouseMoveCallback()
{
	return m_data->m_mouseMoveCallback;
}
b3MouseButtonCallback X11OpenGLWindow::getMouseButtonCallback()
{
	return m_data->m_mouseButtonCallback;
}
b3ResizeCallback X11OpenGLWindow::getResizeCallback()
{
	return m_data->m_resizeCallback;
}
b3WheelCallback X11OpenGLWindow::getWheelCallback()
{
	return m_data->m_wheelCallback;
}


b3KeyboardCallback      X11OpenGLWindow::getKeyboardCallback()
{
	return m_data->m_keyboardCallback;
}

int   X11OpenGLWindow::getWidth() const
{
    if (m_data)
        return m_data->m_glWidth;
    return 0;
}
int   X11OpenGLWindow::getHeight() const
{
    if (m_data)
        return m_data->m_glHeight;
    return 0;
}


#include <stdio.h>

int X11OpenGLWindow::fileOpenDialog(char* filename, int maxNameLength)
{
	int len = 0;
	FILE * output = popen("zenity --file-selection --file-filter=\"*.urdf\" --file-filter=\"*.sdf\"  --file-filter=\"*.obj\"  --file-filter=\"*.*\"","r");
	if (output)
	{
		while( fgets(filename, maxNameLength-1, output) != NULL )
		{
			len=strlen(filename);
			if (len>0)
			{
				filename[len-1]=0;
				printf("file open (length=%d) = %s\n", len,filename);
			}
		}
		pclose(output);
	} else
	{
		printf("Error: fileOpenDialog no popen output, perhaps install zenity?\n");
	}
	MyXRaiseWindow(m_data->m_dpy, m_data->m_win);
	return len;

}
