#ifndef	GLCTX_H
#define	GLCTX_H

/* Refresh driver parameters: visual */
/* FIXME: currently not used under Linux */
/* FIXME: under Win32 + nVidia ICD, request for software (MS GDI)
 * implementation sometimes fails (unable to SetPixelFormat(...)) */
/* TODO: (?) remove these ... */

typedef struct ref_visual_s
{
	struct
	{
		unsigned char hardware;		/* Hardware renderer */
        unsigned char offscreen;	/* Offscreen frame buffer */
        unsigned char activate_mouse; /* grab pointer */
		unsigned char pad;
	} flags;
	int	color_bits;		/* Bit depth of visual */
	int depth_bits;		/* Bit depth of Z - buffer */
	int stencil_bits;	/* Bit depth of stencil buffer */
}	ref_visual_t, *ref_visual_p;

/* Refresh driver window properties */
typedef enum
{
	ref_wm_title,		/* param is character string (of type char*) */
	ref_wm_left,		/* param is pointer to 32-bit unsigned */
	ref_wm_top,			/* param is pointer to 32-bit unsigned */
	ref_wm_width,		/* param is pointer to 32-bit unsigned */
	ref_wm_height,		/* param is pointer to 32-bit unsigned */
	ref_wm_icon			/* param is HICON */
}	ref_wm_property;

/* Refresh driver attributes */
typedef struct ref_visual_attributes_s
{
	struct
	{
		unsigned char force_software;
		unsigned char force_hardware;
        unsigned char force_offscreen;
	} flags;
	int min_color_bits;
	int min_depth_bits;
	int min_stencil_bits;
}	ref_visual_attributes_t, *ref_visual_attributes_p;

/*
 *	Predefined sets of attributes to use as initializers for refChooseVisual().
 */
/* 'Choose what available' */
#define REF_VISUAL_ATTRIBUTES_DEFAULT 	{ {0,0,0}, 8, 16, 0 }
/* Hints for SW visual */
#define REF_VISUAL_ATTRIBUTES_SW 		{ {1,0,0}, 8, 16, 0 }
/* Hints for HW visual */
#define REF_VISUAL_ATTRIBUTES_HW 		{ {0,1,0}, 15, 16, 0 }
/* Hints for HW visual with stencil */
#define REF_VISUAL_ATTRIBUTES_FX 		{ {0,1,0}, 15, 16, 1 }

#include <v_config.h>

/* TODO: (?) implement 2 structs: ctx_common && ctx_arch_dependent */

#ifdef	__WIN32__
#include <../source/PAL/oshead.h>
#include <GL/gl.h>
#include <../source/TAL/objbase.h>
#include <../source/TAL/fonthead.h>
#ifdef __BORLANDC__
#include <float.h>	/* For masking floating point exceptions. */
#endif

/*
 *	Internal GL context - Win32 form.
 */
typedef struct		gl_context_s
{
	libv_object_t	base;
	/*				Platform - independent part */
	ref_visual_t	visual;
	u32_t			x, y;			/* Position of window */
	u32_t			width,height;	/* Window extents */
	vboolean		fullscreen;		/* == true for FS window */
	u32_t			bpp;			/* bit depth (FS only) */
	u32_t			refresh;		/* refresh rate (FS only) */
	vboolean		bitmap_based;	/* == 1 for offscreen windows */
	vboolean		accelerated;	/* == 1 for HW renderer */
	vboolean		was_selected;	/* == 1 for 2nd and other selections */
	char			*vendor;		/* information about OpenGL driver */
	char			*renderer;
	char			*version;
	u32_t			num_extensions;
	char			**extensions;
	fonthead_t		*font;			/* selected font */
	vboolean		mouse_active;
	vboolean		vidmode_active;
	/*	Win32-specific part */
	char			class_name[64];
	WNDCLASS		wc;
	HWND			parent;			/* used for child windows */
	HBITMAP			bmp;			/* used for offscreen windows */
	BITMAPINFOHEADER	bmh;
	void			*bits;
	HPALETTE		pal;			/* used in 8-bpp mode */
	char			title[128];		/* window title */
	HWND			wnd;			/* window handle */
	BOOL			focused;		/* activity flag (focused) */
	HDC				dc;				/* window of bitmap DC */
	HGLRC			rc;				/* OpenGL RC */
	fifo_t			mqueue;			/* message queue */
	/* rest is HACKS ... */
	UINT			last_msg;			/* used to store last msg */
	s32_t			last_mx, last_my;	/* used to store last mousemove */
}	gl_context_t, *gl_context_p;

#else	/* !__WIN32__ */

#include <../source/TAL/objbase.h>
#include <../source/PAL/oshead.h>

#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>

#include <../source/TAL/fonthead.h>

/*
 * FIXME
 */
#ifdef	__linux
#define	XF86_VIDMODE
/*
#define	HAS_MESA
*/
#endif	/* __linux */

#ifdef	XF86_VIDMODE
#include <X11/extensions/xf86vmode.h>
#endif	/* XF86_VIDMODE */
#ifdef	HAS_MESA
#include <GL/osmesa.h>
#endif	/* HAS_MESA */

/*
 *	Internal GL context: Unix form.
 */
typedef struct		gl_context_s
{
	libv_object_t	base;
	/*				Platform - independent part */
	ref_visual_t	visual;
	u32_t			x, y;			/* Position of window */
	u32_t			width,height;	/* Window extents */
	vboolean		fullscreen;		/* == true for FS window */
	u32_t			bpp;			/* bit depth (FS only) */
	u32_t			refresh;		/* refresh rate (FS only) */
	vboolean		bitmap_based;	/* == 1 for offscreen windows */
	vboolean		was_selected;	/* == 1 for 2nd and other selections */
	char			*vendor;		/* information about OpenGL driver */
	char			*renderer;
	char			*version;
	u32_t			num_extensions;
	char			**extensions;
	fonthead_t		*font;			/* selected font */
	vboolean		mouse_active;
	vboolean		vidmode_active;
	/*	GLX-specific part */
	XSetWindowAttributes attr;
	XVisualInfo		*visinfo;
	Display			*dpy;
	Window 			root;
	int				scrnum;
	Window			parent;			/* used for child windows */
	char			title[128];		/* window title */
	Window			win;			/* window handle */
	vboolean		focused;		/* activity flag (focused) */
	vboolean		keyboard_active; /* keybard captured */
	GLXContext		ctx;
	fifo_t			mqueue;			/* message queue */
    /* deferred action queue, CURRENTLY NOT USED, see glut sources */
	fifo_t			aqueue;
#ifdef	HAS_MESA
	OSMesaContext	osctx;
	void			*fb;
#endif	/* HAS_MESA */
#ifdef	XF86_VIDMODE
	XF86VidModeModeInfo	**vidmodes;
	int				num_vidmodes;
#endif	/* XF86_VIDMODE */
}	gl_context_t, *gl_context_p;

#endif	/* !__WIN32__ */

#ifdef	CHECKED_BUILD
extern	char 	*gl_object;
#define	GL_MAGIC	0x56474C57
#endif	/* CHECKED_BUILD */

/* Handy macros */
#define	vglIsContext(context,caller) \
		((gl_context_p)libvIsHandle((context),(caller),gl_object,GL_MAGIC))

#define vglSafeGetCurrentContext(caller) \
		(vglIsContext(GetThreadData()->gl_context,(caller)))

#endif	/* GLCTX_H */
