#include "window9.bi"
#include Once "X11/Xutil.bi"

Extern "C"
	
	Type GLXContext As Any Ptr
	
	Declare Function glXChooseVisual(Byval dpy As Display Ptr, Byval Screen As Long, Byval attribList As Long Ptr) As Any  Ptr
	
	Declare Function glXCreateContext(Byval dpy As Display Ptr, Byval vis As Any Ptr, Byval shareList As GLXContext, Byval direct As Integer) As GLXContext
	
	Declare Function glXMakeCurrent(Byval dpy As Display Ptr, Byval drawable As Integer, Byval ctx As GLXContext) As Integer
	
	Declare Sub glXSwapBuffers(Byval dpy As Display Ptr, Byval drawable As Integer)
	
	Declare Sub glXDestroyContext(Byval dpy As Display Ptr, Byval ctx As GLXContext)
	
	#ifndef __USE_GTK3__
		
		Declare Function gdk_x11_window_get_xid Alias "gdk_x11_drawable_get_xid" (As Any Ptr) As XID
		
	#else
		
		Declare Function gdk_x11_window_get_xid (As Any Ptr) As XID
		
	#endif
	
	Declare Function gdk_x11_display_get_xdisplay (As Any Ptr) As Display Ptr
	
End Extern

#define GLX_RGBA		4
#define GLX_DEPTH_SIZE		12
#define GLX_DOUBLEBUFFER	5
#define GLX_RED_SIZE		8
#define GLX_GREEN_SIZE		9
#define GLX_BLUE_SIZE		10

Sub Perspective(Byval fov As Double, Byval ratio As Double, Byval zNear As Double, Byval zFar As Double) Export
	
	Dim As Double fH = Tan( fov / 360.0 * 3.1415926535897932384626433832795 ) * zNear
	
	Dim As Double fW = fH * ratio
	
	glFrustum(-fW,fW,-fH,fH,zNear,zFar)
	
End Sub

Function ConfigureOpenGlFunc Cdecl(w As GtkWidget Ptr, Event As GdkEventConfigure Ptr) As Integer

	If w Then 
		
		Dim As XID pXID

		pXID = gdk_x11_window_get_xid(gtk_widget_get_window(w))
		
		Dim As Any Ptr glx_context = g_object_get_data (Cast(Any Ptr,w), "context" )
		
		Dim As Any Ptr dpy = g_object_get_data (Cast(Any Ptr,w), "dpy" )
		
		glXMakeCurrent(dpy, pXID ,glx_context)

		If glXMakeCurrent(dpy, pXID ,glx_context) Then
			
			glViewport(0,0, Event->Width, Event->height)
			
			glMatrixMode(GL_PROJECTION)
			
			glLoadIdentity()
			
			glOrtho(0,100, 100, 0 , -1 , 1)
			
			glMatrixMode(GL_MODELVIEW)
			
			glLoadIdentity()
			
		Endif
	
	Endif
	
	Return True
	
End Function


Function Openglgadget(iGadget As Long , iX As Long , iY As Long, iWidth As Long, iHeight As Long, cBits As Long = 0, dBits As Long = 0, sBits As Long = 0, aBits As Long = 0) As HWND Export
	
	Dim As GLXContext glx_context
	
	Dim As HWND glarea , vBox , mainBox
	
	Dim As ListT Ptr pListTemp
	
	If cBits=0 Then cBits=24
	
	If dBits>0 Andalso dBits<16 Then dBits=16	
	
	If cBits<24 Then
		
		cBits=16
		
	Elseif cBits<32 Then
	
		cBits=24
		
	Elseif cBits>24 Then
	
		cBits=32
		
	End If
	
	If dBits<16 Then
		
		dBits=0
		
	Elseif dBits<24 Then
	
		dBits=16
		
	Elseif dBits<32 Then
	
		dBits=24
		
	Else
	
		dBits=32
		
	End If
	
	If sBits<1 Then
		
		sBits=0
		
	Elseif sBits>8 Then
	
		sBits=8
		
	End If
	
	If aBits<1 Then
		
		aBits=0
		
	Elseif aBits>8 Then
		
		aBits=8
		
	End If
	
	Dim As XVisualInfo Ptr vi
	
	Dim As Any Ptr dpy
	
	Dim As XID pXID

	Dim As Integer attribList(...) = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None }	
	
	Freegadget(iGadget)
	
	Updateinfoxserver()
	
	pGlobalTypeWindow9->OptGroup = 0 ' reset Group OptionGadget
	
	pListTemp = Cast(ListT Ptr,pGlobalTypeWindow9->ListWinAndContainers->findNodeFunc(Cint(pGlobalTypeWindow9->CurentHwnd)))
	
	mainBox = Cast(hwnd , pListTemp->anyTwoData)	
	
	vbox = gtk_fixed_new()
	
	gtk_container_add (GTK_CONTAINER(mainBox), vbox)
	
	glarea = GTK_WIDGET(gtk_drawing_area_new())
	
	pGlobalTypeWindow9->ListGadgets->addNodeSub(iGadget , Cint(glarea) ,  26)
	
	gtk_widget_set_size_request(glarea, iWidth, iHeight)
	
	gtk_widget_set_events (GTK_WIDGET(glarea), GDK_BUTTON_PRESS_MASK Or GDK_BUTTON_RELEASE_MASK)
	
	gtk_fixed_put(GTK_FIXED(vbox), glarea, iX , iY)
	
	g_object_set_data (Cast(Any Ptr, glarea), "X_SIZE" , Cast(Any Ptr,Cint(iX)))
	
	g_object_set_data (Cast(Any Ptr, glarea), "Y_SIZE" , Cast(Any Ptr,Cint(iY)))
	
	g_object_set_data (Cast(Any Ptr, glarea), "W_SIZE" , Cast(Any Ptr,Cint(iWidth)))
	
	g_object_set_data (Cast(Any Ptr, glarea), "H_SIZE" , Cast(Any Ptr,Cint(iHeight)))		
	
	tree_add_node(iGadget,pGlobalTypeWindow9->treeNumberGadgets)
	
	Dim As Node Ptr fNode = tree_find_node(iGadget,pGlobalTypeWindow9->treeNumberGadgets)
	
	g_signal_connect (glarea, "configure_event", G_CALLBACK(@ConfigureOpenGlFunc), NULL)
	
	g_signal_connect (glarea, "button-press-event", G_CALLBACK(@MousePressWindowSub), NULL)
	
	g_signal_connect (glarea, "button-release-event", G_CALLBACK(@MousePressWindowSub), NULL)
	
	g_signal_connect(G_OBJECT(glarea), "size-allocate", G_CALLBACK (@size_allocate_signals), @(fNode->x))
	
	gtk_widget_show(vBox)

	gtk_widget_show(glarea)
	
	Updateinfoxserver()
	
	dpy = gdk_x11_display_get_xdisplay(Cast(Any Ptr,gdk_window_get_display(gtk_widget_get_window(pGlobalTypeWindow9->CurentHwnd))))
	
	vi = glXChooseVisual(dpy,DefaultScreen(dpy),Cast(Any Ptr ,@attribList(0)))
	
	If vi = NULL Then
		
		fprintf(stderr,!"Could not create visual\n")
		
		Return 0
		
	Endif
	
	If  vi->Class <> TrueColor Then
		
		printf(!"truecolor visual not selected\n")
		
	Endif
	
	glx_context = glXCreateContext(dpy,vi,None,GL_TRUE)
	
	If glx_context = NULL Then
		
		fprintf(stderr,!"Could not create context\n")
		
		Return 0
		
	Endif
	
	pXID = gdk_x11_window_get_xid(gtk_widget_get_window(glarea))
	
	glXMakeCurrent(dpy, pXID ,glx_context)
	
	g_object_set_data (Cast(Any Ptr,glarea), "context"  , Cast(Any Ptr ,glx_context))
	
	g_object_set_data (Cast(Any Ptr,glarea), "dpy"  , Cast(Any Ptr ,dpy))

	glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST)
	
	glHint(GL_FOG_HINT,GL_NICEST)
	
	glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST)
	
	glHint(GL_LINE_SMOOTH_HINT,GL_NICEST)
	
	glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
	
	glViewport(0,0,iWidth,iHeight)
	
	glMatrixMode(GL_PROJECTION)
	
	glLoadIdentity()
	
	If (dBits>0) Then
		
		Dim As Double ratio = Iif(iWidth>iHeight,iWidth/iHeight,iHeight/iWidth)
		
		Perspective(65.0, ratio, 0.1,1000.0)
		
		glEnable(GL_DEPTH_TEST)
		
		#ifdef __USE_GTK3__
			
			glEnable(GL_CULL_FACE)
			
		#endif
		
		glMatrixMode(GL_MODELVIEW)
		
		glLoadIdentity()
		
	Else
		
		glOrtho (0, iWidth , iHeight, 0, -1, 1)
		
		glMatrixMode(GL_MODELVIEW)
		
		glLoadIdentity()
		
		glDisable(GL_DEPTH_TEST)
		
		#ifdef __USE_GTK3__
			
			glEnable(GL_CULL_FACE)
			
		#endif
		
		glTranslatef(0.375, 0.375, 0)
		
	End If
	
	glClearColor(0,0,0,1)	
	
	Dim As Integer buffers = GL_COLOR_BUFFER_BIT
	
	If (dBits>0) Then buffers Or=GL_DEPTH_BUFFER_BIT
	
	If (sBits>0) Then buffers Or=GL_STENCIL_BUFFER_BIT
	
	If (aBits>0) Then buffers Or=GL_ACCUM_BUFFER_BIT
	
	glClear(buffers)
	
	glXSwapBuffers(dpy,pXID)
	
	Return glarea
	
End Function 

Sub Openglgadgetswapbuffers(iGadget As Long) Export
	
	Dim As Any Ptr w = Gadgetid(iGadget)
	
	If w Then 
		
		Dim As XID pXID

		pXID = gdk_x11_window_get_xid(gtk_widget_get_window(w))
		
		Dim As Any Ptr dpy = g_object_get_data (Cast(Any Ptr,w), "dpy" )
		
		glXSwapBuffers(dpy,pXID)
		
	Endif
		
End Sub

Sub Openglgadgetmakecurrent(iGadget As Long) Export
	
	Dim As Any Ptr w = Gadgetid(iGadget)
	
	If w Then 
		
		Dim As XID pXID

		pXID = gdk_x11_window_get_xid(gtk_widget_get_window(w))
		
		Dim As Any Ptr glx_context = g_object_get_data (Cast(Any Ptr,w), "context" )
		
		Dim As Any Ptr dpy = g_object_get_data (Cast(Any Ptr,w), "dpy" )
		
		glXMakeCurrent(dpy, pXID ,glx_context)
		
	Endif

End Sub

