#Include "window9.bi"

#ifndef __USE_GTK3__

#inclib "gtkgl-2.0"

extern "C"
	
	declare function gtk_gl_area_make_current(byval area as any ptr) as integer
	
	declare sub gtk_gl_area_swap_buffers(byval area as any ptr)
	
	declare function  gtk_gl_area_new (attrList as integer ptr) as GtkWidget ptr
	
	declare function gdk_gl_query() as integer
	
End Extern

const GDK_GL_NONE  = 0
const GDK_GL_RGBA = 4
const GDK_GL_DOUBLEBUFFER = 5
const GDK_GL_RED_SIZE = 8
const GDK_GL_GREEN_SIZE	= 9
const GDK_GL_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

sub LookAt(byval ex as double, byval ey as double, byval ez as double, _
byval lx as double, byval ly as double, byval lz as double, _
byval ux as double, byval uy as double, byval uz as double ) Export

	dim as double z(2) = {ex-lx,ey-ly,ez-lz}
	
	dim as double l=z(0)*z(0)+z(1)*z(1)+z(2)*z(2)
	
	if (l) then
		
		l=1.0/sqr(l):z(0)*=l:z(1)*=l:z(2)*=l
	
	end if
	
	dim as double x(2)={uy*z(2)-uz*z(1), _
	-ux*z(2)+uz*z(0), _
	ux*z(1)-uy*z(0)}
	
	l=x(0)*x(0)+x(1)*x(1)+x(2)*x(2)
	
	if (l) then
		
		l=1.0/sqr(l):x(0)*=l:x(1)*=l:x(2)*=l
		
	end if
	
	dim as double y(2)={z(1)*x(2)-z(2)*x(1), _
	-z(0)*x(2)+z(2)*x(0), _
	z(0)*x(1)-z(1)*x(0)}

	l=y(0)*y(0)+y(1)*y(1)+y(2)*y(2)
	
	if (l) then
		
		l=1.0/sqr(l):y(0)*=l:y(1)*=l:y(2)*=l
		
	end if
	
	dim as double m4x4(15)=>{x(0),y(0),z(0),0, _
	x(1),y(1),z(1),0, _
	x(2),y(2),z(2),0, _
	0,   0,   0,1}
	
	glMultMatrixd @m4x4(0)
	
	glTranslated -ex,-ey,-ez
	
end sub

function ConfigureOpenGlFunc cdecl(widget as GtkWidget ptr, event as GdkEventConfigure ptr) as integer
	
	if (gtk_gl_area_make_current (widget)) then
		
		glViewport(0,0, widget->allocation.width, widget->allocation.height)
		
		glMatrixMode(GL_PROJECTION)
		
		glLoadIdentity()
		
		glOrtho(0,100, 100, 0 , -1 , 1)
		
		glMatrixMode(GL_MODELVIEW)
		
		glLoadIdentity()
		
	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 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 integer attrlist(...) = {_
	GDK_GL_RGBA,_
	GDK_GL_RED_SIZE,1,_
	GDK_GL_GREEN_SIZE,1,_
	GDK_GL_BLUE_SIZE,1,_
	GDK_GL_DOUBLEBUFFER,_
	GDK_GL_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_gl_area_new (@attrlist(0)))
	
	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_all (pGlobalTypeWindow9->CurentHwnd)
	
	updateinfoxserver()
	
	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)
		
		glMatrixMode(GL_MODELVIEW)
		
		glLoadIdentity()
		
	else
		
		glOrtho (0, iWidth , iHeight, 0, -1, 1)
		
		glMatrixMode(GL_MODELVIEW)
		
		glLoadIdentity()
		
		glDisable(GL_DEPTH_TEST)
		
		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)
	
	gtk_gl_area_swap_buffers (glarea)	
	
	return glarea
	
end function 

sub OpenGLGadgetSwapBuffers(iGadget as Long) export
	
	dim as any ptr w = gadgetid(iGadget)
	
	if w then gtk_gl_area_swap_buffers (w)
	
End Sub

sub OpenGLGadgetMakeCurrent(iGadget as Long) export
	
	dim as any ptr w = gadgetid(iGadget)
	
	if w then gtk_gl_area_make_current (w)
	
End Sub

#endif

